# Technical Documentation: docker/docs

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/docker/docs)

### Overview (`README.md`)

# Docs @ Docker

<div align="center">
<img src="static/assets/images/docker-docs.svg" alt="Welcome to Docker Documentation">
</div>
<br/>
<br/>

Welcome to the Docker Documentation repository. This is the source for the [Docker Docs Website](https://docs.docker.com/).

Feel free to open pull requests or issues. Our docs are completely open source, and we deeply appreciate contributions from the Docker community!

## Provide feedback

We’d love to hear your feedback! To submit feedback:

- Click **[New issue](https://github.com/docker/docs/issues/new)** on the docs repository, or
- Click **Request changes** in the right column of every page on
  [docs.docker.com](https://docs.docker.com/), or
- Click **Give feedback** on every page in the docs.

To get community support, use the [Docker Community Slack](https://dockr.ly/comm-slack). Personalized support is available
through the Docker Pro, Team, and Business subscriptions. See [Docker
Pricing](https://www.docker.com/pricing?ref=Docs&refAction=DocsReadme) for details.

If you have an idea for a new feature or behavior change in a specific aspect of
Docker or have found a product bug, file an issue in the project's
repository.

## Contribute to Docker docs

We welcome contributions! To get started:

- [CONTRIBUTING.md](CONTRIBUTING.md) - Contribution workflow and setup
- [STYLE.md](STYLE.md) - Writing style and content guidelines
- [COMPONENTS.md](COMPONENTS.md) - Component and shortcode usage

## Copyright and license

Copyright 2013-2026 Docker, Inc., released under the [Apache 2.0 license](https://github.com/docker/docs/blob/main/LICENSE).

---

### Overview (`hack/api-docs/README.md`)

# API reference build

This tool validates the Hub, DVP, Registry, AI Governance, and Sandboxes OpenAPI sources
in `content/reference/api/` and generates presentation data for Hugo. Engine
retains its existing sources and renderer.

## Commands

Site builds use the committed `data/api-reference.json`. To build the site,
use Hugo and the site's Node dependencies. From the repository root:

```console
$ npm ci
$ hugo server
```

For a static build with HTML/Markdown checks, run
`./hack/api-docs/run.sh build`. To serve that build on port 1314, run
`./hack/api-docs/run.sh serve`. Set `DOCS_URL` and `DOCS_PORT` when using another
address. These commands use the committed data without running the generator.

After changing a specification, source manifest entry, or generator code, use
the Go version declared in `hack/api-docs/go.mod` to regenerate the data.

Install the Vacuum version pinned in the [Dockerfile](../../Dockerfile) and make
the `vacuum` executable available on `PATH`. The script runs Vacuum and the Go
generator without installing tools.

```console
$ ./hack/api-docs/run.sh test
$ ./hack/api-docs/run.sh generate
```

Commit `data/api-reference.json` with the source changes. With
`docker compose watch`, the regenerated JSON syncs to the server and Hugo
rebuilds the reference. Docker builds and Netlify deploy previews also use the
committed JSON. Validation reports and local builds remain under
`tmp/api-reference/`.

## Processor inputs

`sources.json` registers input specifications and their product/manual
relationships. Both generation and the validation wrapper use this manifest.
Hugo reads the generated presentation data, rather than this file. Authentication
descriptions come from the specifications and linked guides.

`validation/` contains the Vacuum rules and locked official
schema resources. `testdata/` contains validation fixtures. The presentation model
version and supported dialect are defined by the processor, not configurable
manifest fields.

## Pipeline

1. Parse the authoritative YAML with `libopenapi` and preserve source values and
   reference identities. Verify locked OpenAPI dialect resources.
2. Run Vacuum policy checks and JSON Schema validation of schemas and supplied
   examples, followed by documentation profile checks.
3. Generate presentation model version 1: operations, effective security and
   servers, parameters, media variants, examples, schema links, and provenance.
4. Render HTML and Markdown through the content adapter and `api-docs` templates.
5. Run the shared site flattening script, then check generated operation,
   parameter, media, schema, and link coverage.

The shared `hack/flatten-and-resolve.js` script resolves Markdown link destinations
relative to each original file, then moves `index.md` files to flattened paths.
It preserves code examples and other text. API pages use the same processing as
other pages; links that already use published URLs remain unchanged.

The published YAML URLs still serve the source files directly.

## Validation

`check` is strict and reports every documentation profile failure:

```console
$ ./hack/api-docs/run.sh check
```

Generation runs the same strict validation. Any diagnostic fails generation;
there is no exception baseline. Reports are written to
`tmp/api-reference/validation.json`.

The build workflow's validation matrix runs API reference checks alongside the
other validation targets. It runs tests, validates the sources, regenerates the
JSON, and compares the result with the committed file to detect stale data.
This matrix entry is advisory: failures do not block site builds or deployment.

Run the same check locally with Docker:

```console
$ docker buildx bake validate-api-reference
```

This target runs generator tests, strict validation, and a byte-for-byte
comparison inside Docker. It leaves the working tree unchanged and is also
included in the `validate` Bake group.

## Tests and scope

Go fixtures cover dialects, references, recursion, boolean schemas, examples,
security overrides, server and parameter precedence, and request generation.
`verify-output.mjs` checks all generated HTML/Markdown pairs, retention of
Engine v1.40–v1.56 in ReDoc, and byte-identical published specifications. It
also checks local links and fragments from API pages, including links to
`docs.docker.com`. The site `htmltest` checks include migrated Hub, DVP,
Registry, and AI Governance references. `browser-checks.mjs` exports a
Playwright check for navigation, page aliases, filtering, requests, and narrow
screens.

Callbacks and webhook navigation are unsupported and fail validation. Request
examples are POSIX shell templates; they do not make service calls.

Examples are optional. Supplied examples must validate against their schemas.
When a request body has no example, the generated cURL command reads from
`request-body` and directs the reader to prepare that file from the schema.

---

### Overview (`hack/sandboxes/README.md`)

# Sandboxes documentation import

The public cookbook export is published to the `generated` branch of
`docker/sbx-api` after its documentation CI passes. `source.json` pins both
the generated commit and the source commit recorded in that export's `SOURCE`
file. The guide list explicitly selects the recipes to publish.

`name-a-sandbox-and-find-it-again.md` is temporarily excluded pending a
working example. Restore its manifest entry and import it after verification.

Run the import from the repository root with Python 3 and `gh` authenticated for
`docker/sbx-api`:

```console
$ python3 hack/sync-sandboxes-docs.py
```

The import writes:

- Cookbook recipes to `content/manuals/ai/sandboxes-api/cookbook/`
- The public OpenAPI specification to
  `content/reference/api/sandboxes/api.yaml`

Treat these files as generated. Make prose, example, and API corrections in
`docker/sbx-api`, then import the updated export. The cookbook's `_index.md`
is maintained in docker/docs, along with the overview, installation,
authentication, concepts, errors, and limits pages.

The import copies the selected recipes and OpenAPI specification byte for byte.
It excludes the upstream overview, installation page, and generated Markdown
API reference. Recipe installation links point to the canonical Docker Docs
installation page.

The specification is registered in `hack/api-docs/sources.json`. The shared API
renderer generates an overview and separate operation and schema pages under
`/reference/api/sandboxes/latest/`, in HTML and Markdown. Run
`./hack/api-docs/run.sh generate` after importing a specification and commit
`data/api-reference.json` with the source changes. Strict validation checks the
specification and its examples. Fix failures upstream and re-import the export.

To update, change both commit IDs in `source.json`, review additions or removals
in the upstream guide list, and run the import. Removed guides require explicit
deletion and a link check. Review the diff and build the site before committing.
The import does not select the latest release or push changes.

Release automation can update this manifest and run the same command in a pull
request once upstream publishes a release-to-export mapping. Keep the source
and generated commits paired rather than importing a moving branch.

---

### Overview (`content/manuals/engine/security/https/README.md`)

---
build:
  list: never
  publishResources: false
  render: never
---

This is an initial attempt to make it easier to test the TLS (HTTPS) examples in the protect-access.md
doc.

At this point, it is a manual thing, and I've been running it in boot2docker.

My process is as following:

    $ boot2docker ssh
    root@boot2docker:/# git clone https://github.com/moby/moby
    root@boot2docker:/# cd docker/docs/articles/https
    root@boot2docker:/# make cert

lots of things to see and manually answer, as openssl wants to be interactive

> [!NOTE]: make sure you enter the hostname (`boot2docker` in my case) when prompted for `Computer Name`)

    root@boot2docker:/# sudo make run

Start another terminal:

    $ boot2docker ssh
    root@boot2docker:/# cd docker/docs/articles/https
    root@boot2docker:/# make client

The last connects first with `--tls` and then with `--tlsverify`, both should succeed.

---

### Overview (`_vendor/github.com/moby/moby/api/docs/README.md`)

# API Documentation

This directory contains versioned documents for each version of the API
specification supported by this module. While this module provides support
for older API versions, support should be considered "best-effort", especially
for very old versions. Users are recommended to use the latest API versions,
and only rely on older API versions for compatibility with older clients.

Newer API versions tend to be backward-compatible with older versions,
with some exceptions where features were deprecated. For an overview
of changes for each version, refer to [CHANGELOG.md](CHANGELOG.md).

The latest version of the API specification can be found [at the root directory
of this module](../swagger.yaml) which may contain unreleased changes.

For API version v1.24, documentation is only available in markdown
format, for later versions [Swagger (OpenAPI) v2.0](https://swagger.io/specification/v2/)
specifications can be found in this directory. The Moby project itself
primarily uses these swagger files to produce the API documentation;
while we attempt to make these files match the actual implementation,
the OpenAPI 2.0 specification has limitations that prevent us from
expressing all options provided. There may be discrepancies (for which
we welcome contributions). If you find bugs, or discrepancies, please
open a ticket (or pull request).

---

###  Index (`content/_index.md`)

---
title: Home
description: Docker Documentation is the official Docker library of resources, manuals, and guides to help you containerize applications.
keywords: Docker, documentation, manual, guide, reference, api, samples
aliases:
  - /search/
---

Docker Documentation helps you learn Docker, install Docker products, and find
reference material for everyday development and operations tasks.

## Browse docs by area

- [Get started](/get-started/): Run an application, sandbox an AI agent, or
  roll out Docker.
- [Guides](/guides/): Follow task-focused walkthroughs for common workflows.
- [Manuals](/manuals/): Install, configure, and use Docker products.
- [Reference](/reference/): Browse CLI, API, and file format documentation.

{{< whats-new >}}

## Common questions

- [How do I get started with Docker?](/get-started/)
- [How do I containerize an application?](/get-started/tutorials/run-an-app/)
- [Can I run my AI agent in a sandbox?](/get-started/tutorials/run-an-agent/)
- [What are Docker Hardened Images?](/dhi/)
- [Why should I use Docker Compose?](/compose/)

---

### Get Started  Index (`content/get-started/_index.md`)

---
title: Get started
keywords: Docker, get started, containers, AI agents, sandboxes, administration
description: Choose a tutorial to build and run an application, work with an AI agent safely, or set up Docker for your organization.
layout: get-started
params:
  notoc: true
  installs:
    - eyebrow: Docker
      title: Install Docker
      description: Get Docker Desktop or Docker Engine for your operating system.
      link: /get-started/get-docker/
    - eyebrow: Docker Sandboxes
      title: Install Docker Sandboxes
      description: Install the sbx command to run coding agents in isolated environments.
      link: /ai/sandboxes/install/
  tutorials:
    - audience: New to Docker
      title: Build and share a containerized application
      description: Run a container and an application stack, build an image, and share it through Docker Hub.
      link: /get-started/tutorials/run-an-app/
    - audience: AI developers
      title: Run your coding agent in a sandbox
      description: Move your existing full-autonomy coding-agent workflow into a disposable Docker Sandbox.
      link: /get-started/tutorials/run-an-agent/
    - audience: Administrators
      title: Roll out Docker to a pilot group
      description: Invite a pilot user, apply a Docker Desktop policy, and verify the managed experience.
      link: /get-started/tutorials/admin-set-up/
aliases:
  - /engine/get-started/
  - /engine/tutorials/usingdocker/
  - /guides/getting-started/get-docker-desktop/
---

---

### Get Started Docker Overview (`content/get-started/docker-overview.md`)

---
description: Get an in-depth overview of the Docker platform including what it can
  be used for, the architecture it employs, and its underlying technology.
keywords: what is a docker, docker daemon, why use docker, docker architecture, what
  to use docker for, docker client, what is docker for, why docker, uses for docker,
  what is docker container used for, what are docker containers used for
title: What is Docker?
weight: 20
aliases:
 - /introduction/understanding-docker/
 - /engine/userguide/basics/
 - /engine/introduction/understanding-docker/
 - /engine/understanding-docker/
 - /engine/docker-overview/
 - /get-started/overview/
 - /guides/docker-overview/
---

Docker is an open platform for developing, shipping, and running applications.
Docker enables you to separate your applications from your infrastructure so
you can deliver software quickly. With Docker, you can manage your infrastructure
in the same ways you manage your applications. By taking advantage of Docker's
methodologies for shipping, testing, and deploying code, you can
significantly reduce the delay between writing code and running it in production.

## The Docker platform

Docker provides the ability to package and run an application in a loosely isolated
environment called a container. The isolation and security let you run many
containers simultaneously on a given host. Containers are lightweight and contain
everything needed to run the application, so you don't need to rely on what's
installed on the host. You can share containers while you work,
and be sure that everyone you share with gets the same container that works in the
same way.

Docker provides tooling and a platform to manage the lifecycle of your containers:

* Develop your application and its supporting components using containers.
* The container becomes the unit for distributing and testing your application.
* When you're ready, deploy your application into your production environment,
  as a container or an orchestrated service. This works the same whether your
  production environment is a local data center, a cloud provider, or a hybrid
  of the two.

## What can I use Docker for?

### Fast, consistent delivery of your applications

Docker streamlines the development lifecycle by allowing developers to work in
standardized environments using local containers which provide your applications
and services. Containers are great for continuous integration and continuous
delivery (CI/CD) workflows.

Consider the following example scenario:

- Your developers write code locally and share their work with their colleagues
  using Docker containers.
- They use Docker to push their applications into a test environment and run
  automated and manual tests.
- When developers find bugs, they can fix them in the development environment
  and redeploy them to the test environment for testing and validation.
- When testing is complete, getting the fix to the customer is as simple as
  pushing the updated image to the production environment.

### Responsive deployment and scaling

Docker's container-based platform allows for highly portable workloads. Docker
containers can run on a developer's local laptop, on physical or virtual
machines in a data center, on cloud providers, or in a mixture of environments.

Docker's portability and lightweight nature also make it easy to dynamically
manage workloads, scaling up or tearing down applications and services as
business needs dictate, in near real time.

### Running more workloads on the same hardware

Docker is lightweight and fast. It provides a viable, cost-effective alternative
to hypervisor-based virtual machines, so you can use more of your server
capacity to achieve your business goals. Docker is perfect for high density
environments and for small and medium deployments where you need to do more with
fewer resources.

## Docker architecture

Docker uses a client-server architecture. The Docker client talks to the
Docker daemon, which does the heavy lifting of building, running, and
distributing your Docker containers. The Docker client and daemon can
run on the same system, or you can connect a Docker client to a remote Docker
daemon. The Docker client and daemon communicate using a REST API, over UNIX
sockets or a network interface. Another Docker client is Docker Compose,
that lets you work with applications consisting of a set of containers.



### The Docker daemon

The Docker daemon (`dockerd`) listens for Docker API requests and manages Docker
objects such as images, containers, networks, and volumes. A daemon can also
communicate with other daemons to manage Docker services.

### The Docker client

The Docker client (`docker`) is the primary way that many Docker users interact
with Docker. When you use commands such as `docker run`, the client sends these
commands to `dockerd`, which carries them out. The `docker` command uses the
Docker API. The Docker client can communicate with more than one daemon.

### Docker Desktop

Docker Desktop is an easy-to-install application for your Mac, Windows, or Linux environment that enables you to build and share containerized applications and microservices. Docker Desktop includes the Docker daemon (`dockerd`), the Docker client (`docker`), Docker Compose, Docker Content Trust, Kubernetes, and Credential Helper. For more information, see [Docker Desktop](/manuals/desktop/_index.md).

### Docker registries

A Docker registry stores Docker images. Docker Hub is a public
registry that anyone can use, and Docker looks for images on
Docker Hub by default. You can even run your own private registry.

When you use the `docker pull` or `docker run` commands, Docker pulls the required images from your configured registry. When you use the `docker push` command, Docker pushes
your image to your configured registry.

### Docker objects

When you use Docker, you are creating and using images, containers, networks,
volumes, plugins, and other objects. This section is a brief overview of some
of those objects.

#### Images

An image is a read-only template with instructions for creating a Docker
container. Often, an image is based on another image, with some additional
customization. For example, you may build an image that is based on the Ubuntu image 
but includes the Apache web server and your application, as well as the
configuration details needed to make your application run.

You might create your own images or you might only use those created by others
and published in a registry. To build your own image, you create a Dockerfile
with a simple syntax for defining the steps needed to create the image and run
it. Each instruction in a Dockerfile creates a layer in the image. When you
change the Dockerfile and rebuild the image, only those layers which have
changed are rebuilt. This is part of what makes images so lightweight, small,
and fast, when compared to other virtualization technologies.

#### Containers

A container is a runnable instance of an image. You can create, start, stop,
move, or delete a container using the Docker API or CLI. You can connect a
container to one or more networks, attach storage to it, or even create a new
image based on its current state.

By default, a container is relatively well isolated from other containers and
its host machine. You can control how isolated a container's network, storage,
or other underlying subsystems are from other containers or from the host
machine.

A container is defined by its image as well as any configuration options you
provide to it when you create or start it. When a container is removed, any changes to
its state that aren't stored in persistent storage disappear.

##### Example `docker run` command

The following command runs an `ubuntu` container, attaches interactively to your
local command-line session, and runs `/bin/bash`.

```console
$ docker run -i -t ubuntu /bin/bash
```

When you run this command, the following happens (assuming you are using
the default registry configuration):

1.  If you don't have the `ubuntu` image locally, Docker pulls it from your
    configured registry, as though you had run `docker pull ubuntu` manually.

2.  Docker creates a new container, as though you had run a `docker container create`
    command manually.

3.  Docker allocates a read-write filesystem to the container, as its final
    layer. This allows a running container to create or modify files and
    directories in its local filesystem.

4.  Docker creates a network interface to connect the container to the default
    network, since you didn't specify any networking options. This includes
    assigning an IP address to the container. By default, containers can
    connect to external networks using the host machine's network connection.

5.  Docker starts the container and executes `/bin/bash`. Because the container
    is running interactively and attached to your terminal (due to the `-i` and `-t`
    flags), you can provide input using your keyboard while Docker logs the output to
    your terminal.

6.  When you run `exit` to terminate the `/bin/bash` command, the container
    stops but isn't removed. You can start it again or remove it.

## The underlying technology

Docker is written in the [Go programming language](https://golang.org/) and takes
advantage of several features of the Linux kernel to deliver its functionality.
Docker uses a technology called `namespaces` to provide the isolated workspace
called the container. When you run a container, Docker creates a set of
namespaces for that container.

These namespaces provide a layer of isolation. Each aspect of a container runs
in a separate namespace and its access is limited to that namespace.

## Next steps

- [Install Docker](/get-started/get-docker.md)
- [Build and share a containerized application](/get-started/tutorials/run-an-app.md)

---

### Guides  Index (`content/guides/_index.md`)

---
title: Docker guides
linkTitle: Guides
description: Step-by-step tutorials, organized by what you're trying to do.
keywords: docker, guides, tutorials, learning paths, getting started
params:
  icon: book-open
layout: landing
aliases:
  - /guides/language/
  - /language/
  - /guides/dhi-from-doi/
  - /guides/dhi-from-wolfi/
  - /guides/dhi-go-example/
  - /guides/dhi-nodejs-example/
  - /guides/dhi-python-example/
  - /guides/lab-docker-for-ai-redirect/
  - /learning-paths/
---

Explore guides to learn how Docker can optimize your development workflows and
how to use it with specific languages, frameworks, or technologies.

Can't find the guide you're looking for? Open an issue on the
[docker/docs](https://github.com/docker/docs/issues/new) repository.

---

### Guides Lab Compose Quickstart (`content/guides/lab-compose-quickstart.md`)

---
title: "Lab: Docker Compose Quickstart"
linkTitle: "Lab: Docker Compose Quickstart"
description: |
  Build a multi-container Flask and Redis application from scratch using Docker
  Compose. Learn health checks, watch mode, named volumes, and multi-file
  configurations.
summary: |
  Hands-on lab: Define and run a multi-container app with Docker Compose.
  Progress from a bare compose.yaml through health checks, live development
  with watch mode, data persistence, and modular Compose file composition.
keywords: Docker, Compose, multi-container, Flask, Redis, watch mode, volumes, lab, labspace
params:
  tags: [labs]
  time: 45 minutes
---

Build a Python Flask and Redis hit-counter app using Docker Compose, starting
from a bare `compose.yaml` and progressively adding production-quality
features at each step.

## Launch the lab

{{< labspace-launch image="dockersamples/labspace-compose-quickstart" >}}

## What you'll learn

By the end of this Labspace, you will have completed the following:

- Define a multi-service application in a `compose.yaml` file and manage it with Compose commands
- Control service startup order using health checks and `depends_on` conditions
- Iterate on code without manual rebuilds using Compose watch mode
- Persist data across container restarts with named volumes
- Modularize a stack across multiple files using the `include` directive
- Use `config`, `logs`, and `exec` to inspect and debug a running stack

## Modules

| #   | Module                           | Description                                                           |
| --- | -------------------------------- | --------------------------------------------------------------------- |
| 1   | Introduction                     | Tour the starter app and verify the environment                       |
| 2   | Defining Services                | Write the first `compose.yaml` and bring up the Flask and Redis stack |
| 3   | Health Checks & Startup Order    | Add a Redis healthcheck and `depends_on` to eliminate race conditions |
| 4   | Live Development with Watch Mode | Configure watch mode to sync code changes without manual rebuilds     |
| 5   | Persistence & Debugging          | Add a named volume so Redis data survives `docker compose down`       |
| 6   | Using Multiple Compose Files     | Extract Redis into `infra.yaml` and compose files with `include`      |
| 7   | Additional Commands              | Use `config`, `logs -f`, and `exec` to inspect the running stack      |
| 8   | Recap                            | Review what was built and explore next steps                          |

---

### Guides Lab Container Getting Started (`content/guides/lab-container-getting-started.md`)

---
title: "Lab: Getting Started with Docker"
linkTitle: "Lab: Docker basics"
description: |
  Learn Docker fundamentals by running containers, exploring the container
  lifecycle, and packaging a real Node.js app into your own custom image.
summary: |
  Hands-on lab: Run your first containers, write a Dockerfile, build a custom
  image from a Node.js app, and optionally push it to Docker Hub.
keywords: Docker, containers, Dockerfile, images, getting started, lab, labspace
params:
  tags: [labs]
  time: 30 minutes
---

Start from zero and learn Docker's core building blocks. You'll run pre-built
containers, write a `Dockerfile` to package a Node.js app, build your own
image, and see container immutability and isolation in action.

## Launch the lab

{{< labspace-launch image="dockersamples/labspace-container-getting-started" >}}

## What you'll learn

By the end of this Labspace, you will have completed the following:

- Understand what containers are and how they differ from virtual machines
- Run containers in the background, inspect their logs and filesystem, and manage their lifecycle
- Write a `Dockerfile` to package an application, using layer caching for fast rebuilds
- Build a custom image with `docker build` and run it as a container
- Optionally publish your image to Docker Hub

## Modules

| #   | Module                    | Description                                                                    |
| --- | ------------------------- | ------------------------------------------------------------------------------ |
| 1   | Welcome to Docker         | Introduction to containers and running your first `hello-world` container      |
| 2   | Running Containers        | Launch Nginx, inspect logs and internals, and manage the container lifecycle   |
| 3   | Building Your First Image | Write a `Dockerfile` and build a custom image from a Node.js app               |
| 4   | Running Your App          | Run your image, explore container isolation, and optionally push to Docker Hub |
| 5   | Wrap-up                   | Summary of key concepts and next steps                                         |

---

### Guides Testcontainers Dotnet Getting Started (`content/guides/testcontainers-dotnet-getting-started.md`)

---
title: Getting started with Testcontainers for .NET
linkTitle: Testcontainers for .NET
description: Learn how to use Testcontainers for .NET to test database interactions with a real PostgreSQL instance.
keywords: testcontainers, dotnet, csharp, testing, postgresql, integration testing, xunit
summary: |
  Learn how to create a .NET application and test database interactions
  using Testcontainers for .NET with a real PostgreSQL instance.
aliases:
  - /guides/testcontainers-dotnet-getting-started/create-project/
  - /guides/testcontainers-dotnet-getting-started/run-tests/
  - /guides/testcontainers-dotnet-getting-started/write-tests/
params:
  tags: [testing]
  time: 20 minutes
---




In this guide, you will learn how to:

- Create a .NET solution with a source and test project
- Implement a `CustomerService` that manages customer records in PostgreSQL
- Write integration tests using Testcontainers and xUnit
- Manage container lifecycle with `IAsyncLifetime`

## Prerequisites

- .NET 8.0+ SDK
- A Docker environment supported by Testcontainers

> [!NOTE]
> If you're new to Testcontainers, visit the
> [Testcontainers overview](https://testcontainers.com/getting-started/) to learn more about
> Testcontainers and the benefits of using it.

## Create the .NET project

### Set up the solution

Create a .NET solution with source and test projects:

```console
$ dotnet new sln -o TestcontainersDemo
$ cd TestcontainersDemo
$ dotnet new classlib -o CustomerService
$ dotnet sln add ./CustomerService/CustomerService.csproj
$ dotnet new xunit -o CustomerService.Tests
$ dotnet sln add ./CustomerService.Tests/CustomerService.Tests.csproj
$ dotnet add ./CustomerService.Tests/CustomerService.Tests.csproj reference ./CustomerService/CustomerService.csproj
```

Add the Npgsql dependency to the source project:

```console
$ dotnet add ./CustomerService/CustomerService.csproj package Npgsql
```

### Implement the business logic

Create a `Customer` record type:

```csharp
namespace Customers;

public readonly record struct Customer(long Id, string Name);
```

Create a `DbConnectionProvider` class to manage database connections:

```csharp
using System.Data.Common;
using Npgsql;

namespace Customers;

public sealed class DbConnectionProvider
{
    private readonly string _connectionString;

    public DbConnectionProvider(string connectionString)
    {
        _connectionString = connectionString;
    }

    public DbConnection GetConnection()
    {
        return new NpgsqlConnection(_connectionString);
    }
}
```

Create the `CustomerService` class:

```
/* Detailed source-code truncated for AI context efficiency. */
```

Here's what `CustomerService` does:

- The constructor calls `CreateCustomersTable()` to ensure the table exists.
- `GetCustomers()` fetches all rows from the `customers` table and returns them as `Customer` objects.
- `Create()` inserts a customer record into the database.

## Write tests with Testcontainers

### Add Testcontainers dependencies

Add the Testcontainers PostgreSQL module to the test project:

```console
$ dotnet add ./CustomerService.Tests/CustomerService.Tests.csproj package Testcontainers.PostgreSql
```

### Write the test

Create `CustomerServiceTest.cs` in the test project:

```csharp
using Testcontainers.PostgreSql;

namespace Customers.Tests;

public sealed class CustomerServiceTest : IAsyncLifetime
{
    private readonly PostgreSqlContainer _postgres = new PostgreSqlBuilder()
        .WithImage("postgres:16-alpine")
        .Build();

    public Task InitializeAsync()
    {
        return _postgres.StartAsync();
    }

    public Task DisposeAsync()
    {
        return _postgres.DisposeAsync().AsTask();
    }

    [Fact]
    public void ShouldReturnTwoCustomers()
    {
        // Given
        var customerService = new CustomerService(new DbConnectionProvider(_postgres.GetConnectionString()));

        // When
        customerService.Create(new Customer(1, "George"));
        customerService.Create(new Customer(2, "John"));
        var customers = customerService.GetCustomers();

        // Then
        Assert.Equal(2, customers.Count());
    }
}
```

Here's what the test does:

- Declares a `PostgreSqlContainer` using the `PostgreSqlBuilder` with the
  `postgres:16-alpine` Docker image.
- Implements `IAsyncLifetime` for container lifecycle management:
  - `InitializeAsync()` starts the container before the test runs.
  - `DisposeAsync()` stops and removes the container after the test finishes.
- `ShouldReturnTwoCustomers()` creates a `CustomerService` with connection
  details from the container, inserts two customers, fetches all customers, and
  asserts the count.

## Run tests and next steps

### Run the tests

Run the tests:

```console
$ dotnet test
```

You can see in the output that Testcontainers pulls the Postgres Docker image
from Docker Hub (if not already available locally), starts the container, and
runs the test.

Writing an integration test using Testcontainers works like writing a unit test
that you can run from your IDE. Your teammates can clone the project and run
tests without installing Postgres on their machines.

### Summary

The Testcontainers for .NET library helps you write integration tests using the
same type of database (Postgres) that you use in production, instead of mocks.
Because you aren't using mocks and instead talk to real services, you're free
to refactor code and still verify that the application works as expected.

In addition to Postgres, Testcontainers provides dedicated
[modules](https://www.nuget.org/profiles/Testcontainers) for many SQL
databases, NoSQL databases, messaging queues, and more.

To learn more about Testcontainers, visit the
[Testcontainers overview](https://testcontainers.com/getting-started/).

### Further reading

- [Testing an ASP.NET Core web app](https://testcontainers.com/guides/testing-an-aspnet-core-web-app/)

---

### Guides Testcontainers Go Getting Started (`content/guides/testcontainers-go-getting-started.md`)

---
title: Getting started with Testcontainers for Go
linkTitle: Testcontainers for Go
description: Learn how to use Testcontainers for Go to test database interactions with a real PostgreSQL instance.
keywords: testcontainers, go, golang, testing, postgresql, integration testing
summary: |
  Learn how to create a Go application and test database interactions
  using Testcontainers for Go with a real PostgreSQL instance.
aliases:
  - /guides/testcontainers-go-getting-started/create-project/
  - /guides/testcontainers-go-getting-started/run-tests/
  - /guides/testcontainers-go-getting-started/test-suites/
  - /guides/testcontainers-go-getting-started/write-tests/
params:
  tags: [testing]
  time: 20 minutes
---




In this guide, you will learn how to:

- Create a Go application with modules support
- Implement a Repository to manage customer data in a PostgreSQL database using the pgx driver
- Write integration tests using testcontainers-go
- Reuse containers across multiple tests using test suites

## Prerequisites

- Go 1.25+
- Your preferred IDE (VS Code, GoLand)
- A Docker environment supported by Testcontainers. For details, see
  the [testcontainers-go system requirements](https://golang.testcontainers.org/system_requirements/).

> [!NOTE]
> If you're new to Testcontainers, visit the
> [Testcontainers overview](https://testcontainers.com/getting-started/) to learn more about
> Testcontainers and the benefits of using it.

## Create the Go project

### Initialize the project

Start by creating a Go project.

```console
$ mkdir testcontainers-go-demo
$ cd testcontainers-go-demo
$ go mod init github.com/testcontainers/testcontainers-go-demo
```

This guide uses the [jackc/pgx](https://github.com/jackc/pgx) PostgreSQL
driver to interact with the Postgres database and the testcontainers-go
[Postgres module](https://golang.testcontainers.org/modules/postgres/) to
spin up a Postgres Docker instance for testing. It also uses
[testify](https://github.com/stretchr/testify) for running multiple tests
as a suite and for writing assertions.

Install these dependencies:

```console
$ go get github.com/jackc/pgx/v5
$ go get github.com/testcontainers/testcontainers-go
$ go get github.com/testcontainers/testcontainers-go/modules/postgres
$ go get github.com/stretchr/testify
```

### Create Customer struct

Create a `types.go` file in the `customer` package and define the `Customer`
struct to model the customer details:

```go
package customer

type Customer struct {
	Id    int
	Name  string
	Email string
}
```

### Create Repository

Next, create `customer/repo.go`, define the `Repository` struct, and add
methods to create a customer and get a customer by email:

```go
package customer

import (
	"context"
	"fmt"
	"os"

	"github.com/jackc/pgx/v5"
)

type Repository struct {
	conn *pgx.Conn
}

func NewRepository(ctx context.Context, connStr string) (*Repository, error) {
	conn, err := pgx.Connect(ctx, connStr)
	if err != nil {
		_, _ = fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
		return nil, err
	}
	return &Repository{
		conn: conn,
	}, nil
}

func (r Repository) CreateCustomer(ctx context.Context, customer Customer) (Customer, error) {
	err := r.conn.QueryRow(ctx,
		"INSERT INTO customers (name, email) VALUES ($1, $2) RETURNING id",
		customer.Name, customer.Email).Scan(&customer.Id)
	return customer, err
}

func (r Repository) GetCustomerByEmail(ctx context.Context, email string) (Customer, error) {
	var customer Customer
	query := "SELECT id, name, email FROM customers WHERE email = $1"
	err := r.conn.QueryRow(ctx, query, email).
		Scan(&customer.Id, &customer.Name, &customer.Email)
	if err != nil {
		return Customer{}, err
	}
	return customer, nil
}
```

Here's what the code does:

- `Repository` holds a `*pgx.Conn` for performing database operations.
- `NewRepository(connStr)` takes a database connection string and initializes a `Repository`.
- `CreateCustomer()` and `GetCustomerByEmail()` are methods on the `Repository` receiver that insert and query customer records.

## Write tests with Testcontainers

You have the `Repository` implementation ready, but for testing you need a
PostgreSQL database. You can use testcontainers-go to spin up a Postgres
database in a Docker container and run your tests against that database.

### Set up the test database

In real applications you might use a database migration tool, but for this
guide, use a script to initialize the database.

Create a `testdata/init-db.sql` file to create the `CUSTOMERS` table and
insert sample data:

```sql
CREATE TABLE IF NOT EXISTS customers (id serial, name varchar(255), email varchar(255));

INSERT INTO customers(name, email) VALUES ('John', 'john@gmail.com');
```

### Understand the testcontainers-go API

The testcontainers-go library provides the generic `Container` abstraction
that can run any containerized service. To further simplify, testcontainers-go
provides technology-specific modules that reduce boilerplate and provide a
functional options pattern to construct the container instance.

For example, `PostgresContainer` provides `WithDatabase()`,
`WithUsername()`, `WithPassword()`, and other functions to set various
properties of Postgres containers.

### Write the test

Create the `customer/repo_test.go` file and implement the test:

```go
package customer

import (
	"context"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/modules/postgres"
)

func TestCustomerRepository(t *testing.T) {
	ctx := context.Background()

	ctr, err := postgres.Run(ctx,
		"postgres:16-alpine",
		postgres.WithInitScripts(filepath.Join("..", "testdata", "init-db.sql")),
		postgres.WithDatabase("test-db"),
		postgres.WithUsername("postgres"),
		postgres.WithPassword("postgres"),
		postgres.BasicWaitStrategies(),
	)
	testcontainers.CleanupContainer(t, ctr)
	require.NoError(t, err)

	connStr, err := ctr.ConnectionString(ctx, "sslmode=disable")
	require.NoError(t, err)

	customerRepo, err := NewRepository(ctx, connStr)
	require.NoError(t, err)

	c, err := customerRepo.CreateCustomer(ctx, Customer{
		Name:  "Henry",
		Email: "henry@gmail.com",
	})
	assert.NoError(t, err)
	assert.NotNil(t, c)

	customer, err := customerRepo.GetCustomerByEmail(ctx, "henry@gmail.com")
	assert.NoError(t, err)
	assert.NotNil(t, customer)
	assert.Equal(t, "Henry", customer.Name)
	assert.Equal(t, "henry@gmail.com", customer.Email)
}
```

Here's what the test does:

- Calls `postgres.Run()` with the `postgres:16-alpine` Docker image as the
  first argument. This is the v0.41.0 API — the image is a required positional
  parameter instead of an option.
- Configures initialization scripts using `WithInitScripts(...)` so that the
  `CUSTOMERS` table is created and sample data is inserted after the database
  starts.
- Uses `postgres.BasicWaitStrategies()` which combines waiting for the Postgres
  log message and for the port to be ready. This replaces manual wait strategy
  configuration.
- Calls `testcontainers.CleanupContainer(t, ctr)` right after `postgres.Run()`.
  This registers automatic cleanup with the test framework, replacing the manual
  `t.Cleanup` and `Terminate` pattern.
- Obtains the database `ConnectionString` from the container and initializes a
  `Repository`.
- Creates a customer with the email `henry@gmail.com` and verifies that the
  customer exists in the database.

## Reuse containers with test suites

In the previous section, you saw how to spin up a Postgres Docker container
for a single test. But often you have multiple tests in a single file, and you
may want to reuse the same Postgres Docker container for all of them.

You can use the [testify suite](https://pkg.go.dev/github.com/stretchr/testify/suite)
package to implement common test setup and teardown actions.

### Extract container setup

First, extract the `PostgresContainer` creation logic into a separate file
called `testhelpers/containers.go`:

```go
package testhelpers

import (
	"context"
	"path/filepath"
	"testing"

	"github.com/stretchr/testify/require"
	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/modules/postgres"
)

type PostgresContainer struct {
	*postgres.PostgresContainer
	ConnectionString string
}

func CreatePostgresContainer(t *testing.T, ctx context.Context) *PostgresContainer {
	t.Helper()

	ctr, err := postgres.Run(ctx,
		"postgres:16-alpine",
		postgres.WithInitScripts(filepath.Join("..", "testdata", "init-db.sql")),
		postgres.WithDatabase("test-db"),
		postgres.WithUsername("postgres"),
		postgres.WithPassword("postgres"),
		postgres.BasicWaitStrategies(),
	)
	testcontainers.CleanupContainer(t, ctr)
	require.NoError(t, err)

	connStr, err := ctr.ConnectionString(ctx, "sslmode=disable")
	require.NoError(t, err)

	return &PostgresContainer{
		PostgresContainer: ctr,
		ConnectionString:  connStr,
	}
}
```

In `containers.go`, `PostgresContainer` extends the testcontainers-go
`PostgresContainer` to provide easy access to `ConnectionString`. The
`CreatePostgresContainer()` function accepts `*testing.T` as its first
parameter, calls `t.Helper()` so that test failures point to the caller,
and uses `testcontainers.CleanupContainer()` to register automatic cleanup.

### Write the test suite

Create `customer/repo_suite_test.go` and implement tests for creating
a customer and getting a customer by email using the testify suite package:

```go
package customer

import (
	"context"
	"testing"

	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
	"github.com/stretchr/testify/suite"
	"github.com/testcontainers/testcontainers-go-demo/testhelpers"
)

type CustomerRepoTestSuite struct {
	suite.Suite
	pgContainer *testhelpers.PostgresContainer
	repository  *Repository
	ctx         context.Context
}

func (suite *CustomerRepoTestSuite) SetupSuite() {
	suite.ctx = context.Background()
	suite.pgContainer = testhelpers.CreatePostgresContainer(suite.T(), suite.ctx)

	repository, err := NewRepository(suite.ctx, suite.pgContainer.ConnectionString)
	require.NoError(suite.T(), err)
	suite.repository = repository
}

func (suite *CustomerRepoTestSuite) TestCreateCustomer() {
	t := suite.T()

	customer, err := suite.repository.CreateCustomer(suite.ctx, Customer{
		Name:  "Henry",
		Email: "henry@gmail.com",
	})
	require.NoError(t, err)
	assert.NotNil(t, customer.Id)
}

func (suite *CustomerRepoTestSuite) TestGetCustomerByEmail() {
	t := suite.T()

	customer, err := suite.repository.GetCustomerByEmail(suite.ctx, "john@gmail.com")
	require.NoError(t, err)
	assert.Equal(t, "John", customer.Name)
	assert.Equal(t, "john@gmail.com", customer.Email)
}

func TestCustomerRepoTestSuite(t *testing.T) {
	suite.Run(t, new(CustomerRepoTestSuite))
}
```

Here's what the code does:

- `CustomerRepoTestSuite` extends `suite.Suite` and includes fields shared
  across multiple tests.
- `SetupSuite()` runs once before all tests. It calls
  `CreatePostgresContainer(suite.T(), ...)` which handles cleanup registration
  automatically via `CleanupContainer`, so no `TearDownSuite()` is needed.
- `TestCreateCustomer()` uses `require.NoError()` for the create operation
  (fail immediately if it errors) and `assert.NotNil()` for the ID check.
- `TestGetCustomerByEmail()` uses `require.NoError()` then asserts on the
  returned values.
- `TestCustomerRepoTestSuite(t *testing.T)` runs the test suite when you
  execute `go test`.

> [!TIP]
> For the purpose of this guide, the tests don't reset data in the database.
> In practice, it's a good idea to reset the database to a known state before
> running each test.

## Run tests and next steps

### Run the tests

Run all the tests using `go test ./...`. Optionally add the `-v` flag for
verbose output:

```console
$ go test -v ./...
```

You should see two Postgres Docker containers start automatically: one for the
suite and its two tests, and another for the initial standalone test. All tests
should pass. After the tests finish, the containers are stopped and removed
automatically.

### Summary

The Testcontainers for Go library helps you write integration tests by using
the same type of database (Postgres) that you use in production, instead of
mocks. Because you aren't using mocks and instead talk to real services, you're
free to refactor code and still verify that the application works as expected.

To learn more about Testcontainers, visit the
[Testcontainers overview](https://testcontainers.com/getting-started/).

### Further reading

- [Testcontainers for Go documentation](https://golang.testcontainers.org/)
- [Testcontainers for Go quickstart](https://golang.testcontainers.org/quickstart/)
- [Testcontainers Postgres module for Go](https://golang.testcontainers.org/modules/postgres/)

---

### Guides Testcontainers Java Getting Started (`content/guides/testcontainers-java-getting-started.md`)

---
title: Getting started with Testcontainers for Java
linkTitle: Testcontainers for Java
description: Learn how to use Testcontainers for Java to test a customer service with a real PostgreSQL database.
keywords: testcontainers, java, testing, postgresql, integration testing, junit, maven
summary: |
  Learn how to create a Java application and test database interactions
  using Testcontainers for Java with a real PostgreSQL instance.
aliases:
  - /guides/testcontainers-java-getting-started/create-project/
  - /guides/testcontainers-java-getting-started/run-tests/
  - /guides/testcontainers-java-getting-started/write-tests/
params:
  tags: [testing]
  time: 20 minutes
---




In this guide, you will learn how to:

- Create a Java project with Maven
- Implement a `CustomerService` that manages customer records in PostgreSQL
- Write integration tests using Testcontainers with a real Postgres database
- Run the tests and verify everything works

## Prerequisites

- Java 17+
- Maven or Gradle
- A Docker environment supported by Testcontainers

> [!NOTE]
> If you're new to Testcontainers, visit the
> [Testcontainers overview](https://testcontainers.com/getting-started/) to learn more about
> Testcontainers and the benefits of using it.

## Create the Java project

### Set up the Maven project

Create a Java project with Maven from your preferred IDE. This guide uses
Maven, but you can use Gradle if you prefer. Add the following dependencies
to `pom.xml`:

```xml
<dependencies>
    <dependency>
        <groupId>org.postgresql</groupId>
        <artifactId>postgresql</artifactId>
        <version>42.7.3</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.5.6</version>
    </dependency>
    <dependency>
        <groupId>org.junit.jupiter</groupId>
        <artifactId>junit-jupiter</artifactId>
        <version>5.10.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.2.5</version>
        </plugin>
    </plugins>
</build>
```

This adds the Postgres JDBC driver, logback for logging, JUnit 5 for testing,
and the latest `maven-surefire-plugin` for JUnit 5 support.

### Implement the business logic

Create a `Customer` record:

```java
package com.testcontainers.demo;

public record Customer(Long id, String name) {}
```

Create a `DBConnectionProvider` class to hold JDBC connection parameters and
provide a database `Connection`:

```java
package com.testcontainers.demo;

import java.sql.Connection;
import java.sql.DriverManager;

class DBConnectionProvider {

  private final String url;
  private final String username;
  private final String password;

  public DBConnectionProvider(String url, String username, String password) {
    this.url = url;
    this.username = username;
    this.password = password;
  }

  Connection getConnection() {
    try {
      return DriverManager.getConnection(url, username, password);
    } catch (Exception e) {
      throw new RuntimeException(e);
    }
  }
}
```

Create the `CustomerService` class:

```
/* Detailed source-code truncated for AI context efficiency. */
```

Here's what `CustomerService` does:

- The constructor calls `createCustomersTableIfNotExists()` to ensure the table exists.
- `createCustomer()` inserts a customer record into the database.
- `getAllCustomers()` fetches all rows from the `customers` table and returns a list of `Customer` objects.

## Write tests with Testcontainers

You have the `CustomerService` implementation ready, but for testing you need a
PostgreSQL database. You can use Testcontainers to spin up a Postgres database
in a Docker container and run your tests against it.

### Add Testcontainers dependencies

Add the Testcontainers PostgreSQL module as a test dependency in `pom.xml`:

```xml
<dependency>
    <groupId>org.testcontainers</groupId>
    <artifactId>testcontainers-postgresql</artifactId>
    <version>2.0.4</version>
    <scope>test</scope>
</dependency>
```

Since the application uses a Postgres database, the Testcontainers Postgres
module provides a `PostgreSQLContainer` class for managing the container.

### Write the test

Create `CustomerServiceTest.java` under `src/test/java`:

```java
package com.testcontainers.demo;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.List;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.testcontainers.postgresql.PostgreSQLContainer;

class CustomerServiceTest {

  static PostgreSQLContainer postgres = new PostgreSQLContainer(
    "postgres:16-alpine"
  );

  CustomerService customerService;

  @BeforeAll
  static void beforeAll() {
    postgres.start();
  }

  @AfterAll
  static void afterAll() {
    postgres.stop();
  }

  @BeforeEach
  void setUp() {
    DBConnectionProvider connectionProvider = new DBConnectionProvider(
      postgres.getJdbcUrl(),
      postgres.getUsername(),
      postgres.getPassword()
    );
    customerService = new CustomerService(connectionProvider);
  }

  @Test
  void shouldGetCustomers() {
    customerService.createCustomer(new Customer(1L, "George"));
    customerService.createCustomer(new Customer(2L, "John"));

    List<Customer> customers = customerService.getAllCustomers();
    assertEquals(2, customers.size());
  }
}
```

Here's what the test does:

- Declares a `PostgreSQLContainer` with the `postgres:16-alpine` Docker image.
- The `@BeforeAll` callback starts the Postgres container before any test
  methods run.
- The `@BeforeEach` callback creates a `DBConnectionProvider` using the JDBC
  connection parameters from the container, then creates a `CustomerService`.
  The `CustomerService` constructor creates the `customers` table if it
  doesn't exist.
- `shouldGetCustomers()` inserts 2 customer records, fetches all customers,
  and asserts the count.
- The `@AfterAll` callback stops the container after all test methods finish.

## Run tests and next steps

### Run the tests

Run the tests using Maven:

```console
$ mvn test
```

You can see in the logs that Testcontainers pulls the Postgres Docker image
from Docker Hub (if not already available locally), starts the container, and
runs the test.

Writing an integration test using Testcontainers works like writing a unit test
that you can run from your IDE. Your teammates can clone the project
and run tests without installing Postgres on their machines.

### Summary

The Testcontainers for Java library helps you write integration tests using the
same type of database (Postgres) that you use in production, instead of mocks.
Because you aren't using mocks and instead talk to real services, you're free
to refactor code and still verify that the application works as expected.

In addition to Postgres, Testcontainers provides dedicated modules for many
SQL databases, NoSQL databases, messaging queues, and more. You can use
Testcontainers to run any containerized dependency for your tests.

To learn more about Testcontainers, visit the
[Testcontainers overview](https://testcontainers.com/getting-started/).

### Further reading

- [Testcontainers container lifecycle management using JUnit 5](https://testcontainers.com/guides/testcontainers-container-lifecycle/)
- [Replace H2 with a real database for testing](https://testcontainers.com/guides/replace-h2-with-real-database-for-testing/)
- [Getting started with Testcontainers in a Java Spring Boot project](https://testcontainers.com/guides/testing-spring-boot-rest-api-using-testcontainers/)

---

### Guides Testcontainers Nodejs Getting Started (`content/guides/testcontainers-nodejs-getting-started.md`)

---
title: Getting started with Testcontainers for Node.js
linkTitle: Testcontainers for Node.js
description: Learn how to use Testcontainers for Node.js to test database interactions with a real PostgreSQL instance.
keywords: testcontainers, nodejs, javascript, testing, postgresql, integration testing, jest
summary: |
  Learn how to create a Node.js application and test database interactions
  using Testcontainers for Node.js with a real PostgreSQL instance.
aliases:
  - /guides/testcontainers-nodejs-getting-started/create-project/
  - /guides/testcontainers-nodejs-getting-started/run-tests/
  - /guides/testcontainers-nodejs-getting-started/write-tests/
params:
  tags: [testing]
  time: 15 minutes
---




In this guide, you will learn how to:

- Create a Node.js application that stores and retrieves customers from PostgreSQL
- Write integration tests using Testcontainers and Jest
- Run tests against a real PostgreSQL database in a Docker container

## Prerequisites

- Node.js 18+
- npm
- A Docker environment supported by Testcontainers

> [!NOTE]
> If you're new to Testcontainers, visit the
> [Testcontainers overview](https://testcontainers.com/getting-started/) to learn more about
> Testcontainers and the benefits of using it.

## Create the Node.js project

### Initialize the project

Create a new Node.js project:

```console
$ npm init -y
```

Add `pg`, `jest`, and `@testcontainers/postgresql` as dependencies:

```console
$ npm install pg --save
$ npm install jest @testcontainers/postgresql --save-dev
```

### Implement the customer repository

Create `src/customer-repository.js` with functions to manage customers in
PostgreSQL:

```javascript
async function createCustomerTable(client) {
  const sql =
    "CREATE TABLE IF NOT EXISTS customers (id INT NOT NULL, name VARCHAR NOT NULL, PRIMARY KEY (id))";
  await client.query(sql);
}

async function createCustomer(client, customer) {
  const sql = "INSERT INTO customers (id, name) VALUES($1, $2)";
  await client.query(sql, [customer.id, customer.name]);
}

async function getCustomers(client) {
  const sql = "SELECT * FROM customers";
  const result = await client.query(sql);
  return result.rows;
}

module.exports = { createCustomerTable, createCustomer, getCustomers };
```

The module provides three functions:

- `createCustomerTable()` creates the `customers` table if it doesn't exist.
- `createCustomer()` inserts a customer record.
- `getCustomers()` fetches all customer records.

## Write tests with Testcontainers

Create `src/customer-repository.test.js` with the test:

```javascript
const { Client } = require("pg");
const { PostgreSqlContainer } = require("@testcontainers/postgresql");
const {
  createCustomerTable,
  createCustomer,
  getCustomers,
} = require("./customer-repository");

describe("Customer Repository", () => {
  jest.setTimeout(60000);

  let postgresContainer;
  let postgresClient;

  beforeAll(async () => {
    postgresContainer = await new PostgreSqlContainer().start();
    postgresClient = new Client({
      connectionString: postgresContainer.getConnectionUri(),
    });
    await postgresClient.connect();
    await createCustomerTable(postgresClient);
  });

  afterAll(async () => {
    await postgresClient.end();
    await postgresContainer.stop();
  });

  it("should create and return multiple customers", async () => {
    const customer1 = { id: 1, name: "John Doe" };
    const customer2 = { id: 2, name: "Jane Doe" };

    await createCustomer(postgresClient, customer1);
    await createCustomer(postgresClient, customer2);

    const customers = await getCustomers(postgresClient);
    expect(customers).toEqual([customer1, customer2]);
  });
});
```

Here's what the test does:

- The `beforeAll` block starts a real PostgreSQL container using
  `PostgreSqlContainer`. It then creates a `pg` client connected to the
  container and sets up the `customers` table.
- The `afterAll` block closes the client connection and stops the container.
- The test inserts two customers, fetches all customers, and asserts the
  results match.

The test timeout is set to 60 seconds to allow time for the container to start
on the first run (when the Docker image needs to be pulled).

## Run tests and next steps

### Run the tests

Add the test script to `package.json` if it isn't there already:

```json
{
  "scripts": {
    "test": "jest"
  }
}
```

Then run the tests:

```console
$ npm test
```

You should see output like:

```text
 PASS  src/customer-repository.test.js
  Customer Repository
    ✓ should create and return multiple customers (5 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
```

To see what Testcontainers is doing under the hood — which containers it
starts, what versions it uses — set the `DEBUG` environment variable:

```console
$ DEBUG=testcontainers* npm test
```

### Summary

The Testcontainers for Node.js library helps you write integration tests using
the same type of database (Postgres) that you use in production, instead of
mocks. Because you aren't using mocks and instead talk to real services, you're
free to refactor code and still verify that the application works as expected.

In addition to PostgreSQL, Testcontainers provides dedicated
[modules](https://github.com/testcontainers/testcontainers-node/tree/main/packages/modules)
for many SQL databases, NoSQL databases, messaging queues, and more.

To learn more about Testcontainers, visit the
[Testcontainers overview](https://testcontainers.com/getting-started/).

### Further reading

- [Testcontainers for Node.js documentation](https://node.testcontainers.org)

---

### Guides Testcontainers Python Getting Started (`content/guides/testcontainers-python-getting-started.md`)

---
title: Getting started with Testcontainers for Python
linkTitle: Testcontainers for Python
description: Learn how to use Testcontainers for Python to test database interactions with a real PostgreSQL instance.
keywords: testcontainers, python, testing, postgresql, integration testing, pytest
summary: |
  Learn how to create a Python application and test database interactions
  using Testcontainers for Python with a real PostgreSQL instance.
aliases:
  - /guides/testcontainers-python-getting-started/create-project/
  - /guides/testcontainers-python-getting-started/run-tests/
  - /guides/testcontainers-python-getting-started/write-tests/
params:
  tags: [testing]
  time: 15 minutes
---




In this guide, you will learn how to:

- Create a Python application that uses PostgreSQL to store customer data
- Use `psycopg` to interact with the database
- Write integration tests using `testcontainers-python` and `pytest`
- Manage container lifecycle with pytest fixtures

## Prerequisites

- Python 3.10+
- pip
- A Docker environment supported by Testcontainers

> [!NOTE]
> If you're new to Testcontainers, visit the
> [Testcontainers overview](https://testcontainers.com/getting-started/) to learn more about
> Testcontainers and the benefits of using it.

## Create the Python project

### Initialize the project

Start by creating a Python project with a virtual environment:

```console
$ mkdir tc-python-demo
$ cd tc-python-demo
$ python3 -m venv venv
$ source venv/bin/activate
```

This guide uses [psycopg3](https://www.psycopg.org/psycopg3/) to interact
with the Postgres database, [pytest](https://pytest.org/) for testing, and
[testcontainers-python](https://testcontainers-python.readthedocs.io/) for
running a PostgreSQL database in a container.

Install the dependencies:

```console
$ pip install "psycopg[binary]" pytest testcontainers[postgres]
$ pip freeze > requirements.txt
```

The `pip freeze` command generates a `requirements.txt` file so that others
can install the same package versions using `pip install -r requirements.txt`.

### Create the database helper

Create a `db/connection.py` file with a function to get a database connection:

```python
import os

import psycopg


def get_connection():
    host = os.getenv("DB_HOST", "localhost")
    port = os.getenv("DB_PORT", "5432")
    username = os.getenv("DB_USERNAME", "postgres")
    password = os.getenv("DB_PASSWORD", "postgres")
    database = os.getenv("DB_NAME", "postgres")
    return psycopg.connect(f"host={host} dbname={database} user={username} password={password} port={port}")
```

Instead of hard-coding the database connection parameters, the function uses
environment variables. This makes it possible to run the application in
different environments without changing code.

### Create the business logic

Create a `customers/customers.py` file and define the `Customer` class:

```python
class Customer:
    def __init__(self, cust_id, name, email):
        self.id = cust_id
        self.name = name
        self.email = email

    def __str__(self):
        return f"Customer({self.id}, {self.name}, {self.email})"
```

Add a `create_table()` function to create the `customers` table:

```python
from db.connection import get_connection


def create_table():
    with get_connection() as conn:
        with conn.cursor() as cur:
            cur.execute("""
                CREATE TABLE customers (
                    id serial PRIMARY KEY,
                    name varchar not null,
                    email varchar not null unique)
                """)
            conn.commit()
```

The function obtains a database connection using `get_connection()` and creates
the `customers` table. The `with` statement automatically closes the connection
when done.

Add the remaining CRUD functions:

```python
def create_customer(name, email):
    with get_connection() as conn:
        with conn.cursor() as cur:
            cur.execute(
                "INSERT INTO customers (name, email) VALUES (%s, %s)", (name, email))
            conn.commit()


def get_all_customers() -> list[Customer]:
    with get_connection() as conn:
        with conn.cursor() as cur:
            cur.execute("SELECT * FROM customers")
            return [Customer(cid, name, email) for cid, name, email in cur]


def get_customer_by_email(email) -> Customer:
    with get_connection() as conn:
        with conn.cursor() as cur:
            cur.execute("SELECT id, name, email FROM customers WHERE email = %s", (email,))
            (cid, name, email) = cur.fetchone()
            return Customer(cid, name, email)


def delete_all_customers():
    with get_connection() as conn:
        with conn.cursor() as cur:
            cur.execute("DELETE FROM customers")
            conn.commit()
```

> [!NOTE]
> To keep it straightforward for this guide, each function creates a new
> connection. In a real-world application, use a connection pool to reuse
> connections.

## Write tests with Testcontainers

You'll create a PostgreSQL container using Testcontainers and use it for all
the tests. Before each test, you'll delete all customer records so that tests
run with a clean database.

### Set up pytest fixtures

This guide uses [pytest fixtures](https://pytest.org/en/stable/how-to/fixtures.html)
for setup and teardown logic. A recommended approach is to use
[finalizers](https://pytest.org/en/stable/how-to/fixtures.html#adding-finalizers-directly)
to guarantee cleanup runs even if setup fails:

```python
@pytest.fixture
def setup(request):
    # setup code

    def cleanup():
        # teardown code

    request.addfinalizer(cleanup)
    return some_value
```

### Create the test file

Create a `tests/__init__.py` file with empty content to enable pytest
[auto-discovery](https://pytest.org/explanation/goodpractices.html#test-discovery).

Then create `tests/test_customers.py` with the fixtures:

```python
import os
import pytest
from testcontainers.postgres import PostgresContainer

from customers import customers

postgres = PostgresContainer("postgres:16-alpine")


@pytest.fixture(scope="module", autouse=True)
def setup(request):
    postgres.start()

    def remove_container():
        postgres.stop()

    request.addfinalizer(remove_container)
    os.environ["DB_CONN"] = postgres.get_connection_url()
    os.environ["DB_HOST"] = postgres.get_container_host_ip()
    os.environ["DB_PORT"] = str(postgres.get_exposed_port(5432))
    os.environ["DB_USERNAME"] = postgres.username
    os.environ["DB_PASSWORD"] = postgres.password
    os.environ["DB_NAME"] = postgres.dbname
    customers.create_table()


@pytest.fixture(scope="function", autouse=True)
def setup_data():
    customers.delete_all_customers()
```

Here's what the fixtures do:

- The `setup` fixture has `scope="module"`, so it runs once for all tests in
  the file. It starts a PostgreSQL container, sets environment variables with
  the connection details, and creates the `customers` table. A cleanup
  function removes the container after all tests complete.
- The `setup_data` fixture has `scope="function"`, so it runs before every
  test. It deletes all records to give each test a clean database.

### Write the tests

Add the test functions to the same file:

```python
def test_get_all_customers():
    customers.create_customer("Siva", "siva@gmail.com")
    customers.create_customer("James", "james@gmail.com")
    customers_list = customers.get_all_customers()
    assert len(customers_list) == 2


def test_get_customer_by_email():
    customers.create_customer("John", "john@gmail.com")
    customer = customers.get_customer_by_email("john@gmail.com")
    assert customer.name == "John"
    assert customer.email == "john@gmail.com"
```

- `test_get_all_customers()` inserts two customer records, fetches all
  customers, and asserts the count.
- `test_get_customer_by_email()` inserts a customer, fetches it by email, and
  asserts the details.

Because `setup_data` deletes all records before each test, the tests can run in
any order.

## Run tests and next steps

### Run the tests

Run the tests using pytest:

```console
$ pytest -v
```

You should see output similar to:

```text
============================= test session starts ==============================
platform linux -- Python 3.13.x, pytest-9.x.x
collected 2 items

tests/test_customers.py::test_get_all_customers PASSED                   [ 50%]
tests/test_customers.py::test_get_customer_by_email PASSED               [100%]

============================== 2 passed in 1.90s ===============================
```

The tests run against a real PostgreSQL database instead of mocks, which gives
more confidence in the implementation.

### Summary

The Testcontainers for Python library helps you write integration tests using the
same type of database (Postgres) that you use in production, instead of mocks.
Because you aren't using mocks and instead talk to real services, you're free
to refactor code and still verify that the application works as expected.

In addition to PostgreSQL, Testcontainers for Python provides modules for many
SQL databases, NoSQL databases, messaging queues, and more. You can use
Testcontainers to run any containerized dependency for your tests.

To learn more about Testcontainers, visit the
[Testcontainers overview](https://testcontainers.com/getting-started/).

### Further reading

- [testcontainers-python documentation](https://testcontainers-python.readthedocs.io/)
- [Getting started with Testcontainers for Go](/guides/testcontainers-go-getting-started/)
- [Getting started with Testcontainers for Java](https://testcontainers.com/guides/getting-started-with-testcontainers-for-java/)
- [Getting started with Testcontainers for Node.js](https://testcontainers.com/guides/getting-started-with-testcontainers-for-nodejs/)

---

### Includes  Index (`content/includes/_index.md`)

---
cascade:
- build:
    list: never
    publishResources: false
    render: never
---

---

### Manuals  Index (`content/manuals/_index.md`)

---
title: Manuals
description: Learn how to install, set up, configure, and use Docker products with this collection of user guides
keywords: docker, docs, manuals, products, user guides, how-to
# hard-code the URL of this page
url: /manuals/
layout: wide
params:
  icon: document-text
  sidebar:
    groups:
      - AI and agents
      - Application development
      - Supply chain security
      - Accounts and admin
  notoc: true
  ai-and-agents:
  - title: Docker Agentic Platform
    description: Run agents in cloud sandboxes with this experimental platform.
    icon: cloud
    link: /agentic-platform/
  - title: Docker Sandboxes
    description: Run AI coding agents in isolated environments.
    icon: command-line
    link: /ai/sandboxes/
  - title: Sandboxes API and SDK
    description: Create and manage cloud sandboxes from your applications.
    icon: code-bracket
    link: /ai/sandboxes-api/
  - title: MCP Catalog and Toolkit
    description: Augment your AI workflow with MCP servers.
    icon: /icons/toolkit.svg
    link: /ai/mcp-catalog-and-toolkit/
  - title: Gordon
    description: Streamline your workflow and get the most out of the Docker ecosystem with your personal AI assistant.
    icon: document-plus
    link: /ai/gordon/
  - title: Docker Model Runner
    description: View and manage your local models.
    icon: /icons/models.svg
    link: /ai/model-runner/
  - title: Docker Agent
    description: The open-source multi-agent solution to assist you in your tasks.
    icon: /icons/cagent.svg
    link: /ai/docker-agent
  - title: Docker Skills
    description: Docker's official skills for AI coding agents.
    icon: document-text
    link: /ai/skills/
  application-development:
  - title: Docker Desktop
    description: Your command center for container development.
    icon: /icons/Whale.svg
    link: /desktop/
  - title: Docker Offload
    description: Build and run containers in the cloud.
    icon: cloud
    link: /offload/
  - title: Docker Build Cloud
    description: Build your images faster in the cloud.
    icon: /icons/logo-build-cloud.svg
    link: /build-cloud/
  - title: Testcontainers
    description: Run containers programmatically in your preferred programming language.
    icon: /icons/Testcontainers.svg
    link: /testcontainers/
  - title: Docker Build
    description: Build and ship any application anywhere.
    icon: wrench-screwdriver
    link: /build/
  - title: Docker Engine
    description: The industry-leading container runtime.
    icon: cpu-chip
    link: /engine/
  - title: Docker Compose
    description: Define and run multi-container applications.
    icon: /icons/Compose.svg
    link: /compose/
  supply-chain-security:
  - title: Docker Hub
    description: Discover, share, and integrate container images.
    icon: globe-alt
    link: /docker-hub/
  - title: Docker Hardened Images
    description: Secure, minimal images for trusted software delivery.
    icon: /icons/dhi.svg
    link: /dhi/
  - title: Docker Scout
    description: Image analysis and policy evaluation.
    icon: /icons/Scout.svg
    link: /scout/
  platform:
  - title: Accounts
    description: Manage Docker individual and organization accounts.
    icon: user-circle
    link: /accounts/
  - title: Subscription and billing
    description: Manage Docker subscriptions, plans, billing, and payments.
    icon: credit-card
    link: /subscription-billing/
  - title: Security
    description: Security guardrails for both administrators and developers.
    icon: lock-closed
    link: /security/
  - title: FAQs
    description: Frequently asked questions about Docker accounts, organizations, companies, subscriptions, billing, and security.
    icon: question-mark-circle
    link: /faqs/
  - title: Support
    description: Support options for paid subscriptions and community resources.
    icon: chat-bubble-left
    link: /support/
  - title: Release notes
    description: Features, bug fixes, and breaking changes for Docker Home, billing, security, and subscriptions.
    icon: document-plus
    link: /platform-release-notes/
---

This section contains user guides on how to install, set up, configure, and use
Docker products.

## AI and agents

All the Docker AI tools in one easy-to-access location.

{{< grid items=ai-and-agents >}}

## Application development

End-to-end developer solutions for innovative teams.

{{< grid items=application-development >}}

## Supply chain security

Security guardrails and image analysis for your software supply chain.

{{< grid items=supply-chain-security >}}

## Accounts and admin

Manage Docker accounts, administration, subscriptions, billing, and security.

{{< grid items=platform >}}

---

### Manuals Ai Overview (`content/manuals/ai-overview.md`)

---
title: Docker AI overview
linkTitle: Overview
description: Docker's AI tools help you build, run, and manage AI-powered applications and workflows.
weight: 1
keywords: docker, ai, gordon, docker agent, sandboxes, agentic platform, model runner, mcp
params:
  sidebar:
    group: AI and agents
---

Docker provides tools for working with AI across your development workflow.
Each tool serves a different purpose.

## Which tool do I need?

| I want to...                                                    | Use                                                      | Interface        |
| --------------------------------------------------------------- | -------------------------------------------------------- | ---------------- |
| Run coding agents in isolated environments                      | [Docker Sandboxes](./ai/sandboxes/)                      | `sbx`            |
| Run agents in cloud sandboxes through a web Console | [Docker Agentic Platform](./agentic-platform/_index.md) (experimental) | Web Console |
| Get AI help with Docker tasks (containers, images, Dockerfiles) | [Gordon](./ai/gordon/)                                   | `docker ai`      |
| Run AI models locally with an OpenAI-compatible API             | [Model Runner](./ai/model-runner/)                       | `docker model`   |
| Connect AI tools to external services via MCP                   | [MCP Catalog and Toolkit](/manuals/desktop/features/mcp-catalog-and-toolkit/_index.md) | `docker mcp`     |
| Build and orchestrate custom multi-agent teams                  | [Docker Agent](./ai/docker-agent/)                       | `docker agent`   |
| Give my coding agent Docker best-practice guidance              | [Docker Skills](./ai/skills/)                            | None             |

## How these tools relate

**Gordon** is Docker's built-in AI assistant. It helps with Docker-specific
tasks like debugging containers, writing Dockerfiles, and managing images. You
interact with it through Docker Desktop or the `docker ai` command.

**Docker Agent** is an open-source framework for defining teams of AI agents
in YAML. You configure agents with specific roles, models, and tools, then
run them from your terminal. Docker Agent is a general-purpose agent runtime,
not specific to Docker tasks.

**Docker Skills** are Docker's official, open-source instructions for compatible
coding agents working on Docker tasks. Install them through your agent's
supported method; they can also be used by Docker Agent and agents running in
Docker Sandboxes. Browse the [Docker Skills
catalog](https://github.com/docker/skills#readme) for current guidance.

Docker Sandboxes provides isolated environments for running coding agents
[locally](./ai/sandboxes/get-started.md) or
[in the cloud](./ai/sandboxes/cloud/_index.md). Sandboxes is the isolation layer;
the agents themselves are separate tools. Agent configuration and supported
features differ between local and cloud sandboxes.

Docker Agentic Platform is an experimental service for running agents in
Docker-managed cloud sandboxes. Its web Console provides kit selection,
credentials, network policies, MCP tools, and sandbox lifecycle controls.
[Activate a subscription](./agentic-platform/signup.md) to use cloud compute,
billed on a pay-as-you-go basis.

**Model Runner** lets you run LLMs locally. Other tools like Docker Agent can
use Model Runner as a model provider.

**MCP Catalog and Toolkit** manages connections between AI tools and external
services using the Model Context Protocol. Gordon, Docker Agent, and
third-party tools can all use MCP servers configured through the Toolkit.

---

### Reference  Index (`content/reference/_index.md`)

---
title: Reference documentation
linkTitle: Reference
layout: wide
description: Find reference documentation for the Docker platform’s various APIs, CLIs, and file formats
keywords: Docker reference, API, CLI, file formats
params:
  icon: command-line
  notoc: true
  grid_files:
  - title: Dockerfile
    description: Defines the contents and startup behavior of a single container.
    icon: pencil-square
    link: /reference/dockerfile/
  - title: Compose file
    description: Defines a multi-container application.
    icon: rectangle-stack
    link: /reference/compose-file/
  grid_clis:
  - title: Docker CLI
    description: The main Docker CLI, includes all `docker` commands.
    icon: command-line
    link: /reference/cli/docker/
  - title: Compose CLI
    description: The CLI for Docker Compose, for building and running multi-container
      applications.
    icon: server-stack
    link: /reference/cli/docker/compose/
  - title: Daemon CLI (dockerd)
    description: Persistent process that manages containers.
    icon: cpu-chip
    link: /reference/cli/dockerd/
  grid_apis:
  - title: Sandboxes API
    description: Create cloud sandboxes, run processes, and manage sandbox resources.
    icon: code-bracket
    link: /reference/api/sandboxes/latest/
  - title: Engine API
    description: The main API for Docker, provides programmatic access to a daemon.
    icon: code-bracket
    link: /reference/api/engine/
  - title: Docker Hub API
    description: API to interact with Docker Hub.
    icon: cloud
    link: /reference/api/hub/latest/
  - title: DVP Data API
    description: API for Docker Verified Publishers to fetch analytics data.
    icon: chart-bar
    link: /reference/api/dvp/latest/
  - title: Registry API
    description: API for Docker Registry.
    icon: circle-stack
    link: /reference/api/registry/latest/
---

This section includes the reference documentation for the Docker platform's
various APIs, CLIs, drivers and specifications, and file formats.

## File formats

{{< grid items="grid_files" >}}

## Command-line interfaces (CLIs)

{{< grid items="grid_clis" >}}

## Application programming interfaces (APIs)

{{< grid items="grid_apis" >}}

---

### Get Started Docker Concepts  Index (`content/get-started/docker-concepts/_index.md`)

---
build:
  render: never
title: Docker concepts
weight: 40
---

---

### Get Started Tutorials  Index (`content/get-started/tutorials/_index.md`)

---
title: Tutorials
description: Follow short tutorials for running applications, working with AI agents, and administering Docker.
keywords: Docker, get started, tutorials, containers, AI agents, administration
weight: 1
build:
  render: never
---

---

### Manuals Accounts  Index (`content/manuals/accounts/_index.md`)

---
title: Accounts
description: >
  Manage Docker individual accounts and organization administration, including
  members, teams, and companies.
keywords: accounts, admin, Docker ID, organization, company, Docker Home,
  account management
weight: 10
params:
  sidebar:
    group: Accounts and admin
grid:
  - title: Docker individual accounts
    description: Create and manage your Docker ID, email, and sign-in methods.
    icon: user-circle
    link: /accounts/individual/
  - title: Organization accounts
    description: Manage members, teams, and organization settings.
    icon: building-storefront
    link: /accounts/organization/
  - title: Company accounts
    description: Group multiple organizations for centralized administration.
    icon: building-office-2
    link: /accounts/company/
  - title: Security
    description: Authentication, tokens, and roles for accounts and organizations.
    icon: lock-closed
    link: /security/
  - title: Subscription and billing
    description: Plans, payments, and invoices for your account or organization.
    icon: credit-card
    link: /subscription-billing/
  - title: FAQs
    description: Common questions about accounts, billing, and security.
    icon: question-mark-circle
    link: /faqs/
---

A Docker account identifies you and lets you access Docker products. You
manage it in [Docker Home](https://app.docker.com/). Docker has two
primary account types: individual and organization. A company groups
multiple organizations.

| Account type | What it is | Who it's for |
| --- | --- | --- |
| Individual | A Docker ID with personal settings, Hub repositories, and sign-in methods | A person |
| Organization | A shared workspace for members, teams, and repositories | Teams on Docker Team or Business |
| Company | Shared sign-in and administration for organizations that keep their own members, repositories, and billing | Docker Business subscribers |

You always sign in with your individual account, then work in the
organizations you own or belong to.

## Next steps

{{< grid >}}

---

### Manuals Agentic Platform  Index (`content/manuals/agentic-platform/_index.md`)

---
title: Docker Agentic Platform
description: Run agents and tools in isolated cloud sandboxes with Docker Agentic Platform.
keywords: docker agentic platform, agents, kits, sandboxes, mcp, secrets, network policies
weight: 5
params:
  sidebar:
    group: AI and agents
    badge:
      color: violet
      text: Experimental
grid:
  - title: Sign up
    description: Activate cloud access and review billing.
    icon: credit-card
    link: /agentic-platform/signup/
  - title: Get started
    description: Start your first sandbox.
    icon: rocket-launch
    link: /agentic-platform/get-started/
  - title: Kits
    description: Find a kit or run your own public kit.
    icon: cube
    link: /agentic-platform/kits/
  - title: Sandboxes
    description: Access, pause, resume, and delete your sandboxes.
    icon: command-line
    link: /agentic-platform/sandboxes/
  - title: MCP
    description: Connect predefined or custom MCP servers.
    icon: cpu-chip
    link: /agentic-platform/mcp/
  - title: Secrets
    description: Manage model provider and service credentials.
    icon: key
    link: /agentic-platform/secrets/
  - title: Policies
    description: Control outbound network access from sandboxes.
    icon: shield-check
    link: /agentic-platform/policies/
  - title: FAQ
    description: Find answers about access, billing, and supported features.
    icon: question-mark-circle
    link: /agentic-platform/faq/
---

> [!NOTE]
> Docker Agentic Platform is experimental. Features and behavior may change.

Docker Agentic Platform lets you run agents and tools in isolated cloud
sandboxes. Your agent keeps working when you close the Console, disconnect
your computer, or put it to sleep.

The `sbx` CLI supports both
[local sandboxes](/manuals/ai/sandboxes/get-started.md) and
[cloud sandboxes](/manuals/ai/sandboxes/cloud/_index.md). These pages describe
the web Console experience. The Console and CLI use different secret names;
see [Cloud credentials](/manuals/ai/sandboxes/cloud/credentials.md).

In the Console, choose a [kit](/manuals/agentic-platform/kits.md) and configure
the sandbox's credentials, network access, tools, and compute size. Once it
starts, use its terminal to work with the agent. You can return to running or
paused sandboxes from **Sandboxes**.

You can reuse these settings across sandboxes:

- [MCP](/manuals/agentic-platform/mcp.md) connects external tools.
- [Secrets](/manuals/agentic-platform/secrets.md) provide credentials
  without placing their values inside a sandbox.
- [Network policies](/manuals/agentic-platform/policies.md) control
  which hosts and services a sandbox can reach.

To begin, [activate your subscription](signup.md#activate-cloud-access), then
[start a sandbox](get-started.md). You pay for compute by the second while your
sandbox runs. See [Signup and billing](signup.md) for account and payment
information.

{{< grid >}}

---

### Manuals Build Cloud  Index (`content/manuals/build-cloud/_index.md`)

---
title: Docker Build Cloud
weight: 20
description: Find documentation on Docker Build Cloud to help you build your container images faster, both locally and in CI
keywords: build, cloud, cloud build, remote builder
params:
  sidebar:
    group: Application development
aliases:
  - /build/cloud/faq/
  - /build/cloud/
---

{{< summary-bar feature_name="Docker Build Cloud" >}}

Docker Build Cloud is a service that lets you build your container images
faster, both locally and in CI. Builds run on cloud infrastructure optimally
dimensioned for your workloads, no configuration required. The service uses a
remote build cache, ensuring fast builds anywhere and for all team members.

## How Docker Build Cloud works

Using Docker Build Cloud is no different from running a regular build. You invoke a
build the same way you normally would, using `docker buildx build`. The
difference is in where and how that build gets executed.

By default when you invoke a build command, the build runs on a local instance
of BuildKit, bundled with the Docker daemon. With Docker Build Cloud, you send
the build request to a BuildKit instance running remotely, in the cloud.
All data is encrypted in transit.

The remote builder executes the build steps, and sends the resulting build
output to the destination that you specify. For example, back to your local
Docker Engine image store, or to an image registry.

Docker Build Cloud provides several benefits over local builds:

- Improved build speed
- Shared build cache
- Native multi-platform builds

And the best part: you don't need to worry about managing builders or
infrastructure. Just connect to your builders, and start building.
Each cloud builder provisioned to an organization is completely
isolated to a single Amazon EC2 instance, with a dedicated EBS volume for build
cache, and encryption in transit. That means there are no shared processes or
data between cloud builders.

> [!NOTE]
> Docker Build Cloud is only available in the US East region.

## Get Docker Build Cloud

To get started with Docker Build Cloud,
[create a Docker account](/accounts/individual/create-account/). There are two options
to get access to Docker Build Cloud:

- Users with a free Personal account can opt-in to a 7-day free trial, with the option
  to subscribe for access. To start your free trial, sign in to [Docker Build Cloud Dashboard](https://app.docker.com/build/) and follow the on-screen instructions.
- All users with a paid Docker subscription have access to Docker Build Cloud included
  with their Docker suite of products. See [Docker subscriptions and features](https://www.docker.com/pricing?ref=Docs&refAction=DocsBuildCloud) for more information.

Once you've signed up and created a builder, continue by
[setting up the builder in your local environment](./setup.md).

For information about roles and permissions related to Docker Build Cloud, see
[Roles and Permissions](/manuals/security/roles-and-permissions/core-roles.md#docker-build-cloud).

---

### Manuals Compose  Index (`content/manuals/compose/_index.md`)

---
title: Docker Compose
weight: 30
description: Learn how to use Docker Compose to define and run multi-container applications
  with this detailed introduction to the tool.
keywords: docker compose, docker-compose, compose.yaml, docker compose command, multi-container applications, container orchestration, docker cli
params:
  sidebar:
    group: Application development
grid:
- title: Why use Compose?
  description: Understand Docker Compose's key benefits
  icon: magnifying-glass
  link: /compose/intro/features-uses/
- title: How Compose works 
  description: Understand how Compose works
  icon: squares-2x2
  link: /compose/intro/compose-application-model/
- title: Install Compose
  description: Follow the instructions on how to install Docker Compose.
  icon: arrow-down-tray
  link: /compose/install
- title: Quickstart
  description: Learn the key concepts of Docker Compose whilst building a simple Python
    web application.
  icon: magnifying-glass-plus
  link: /compose/gettingstarted
- title: View the release notes
  description: Find out about the latest enhancements and bug fixes.
  icon: document-plus
  link: "https://github.com/docker/compose/releases"
- title: Explore the Compose file reference
  description: Find information on defining services, networks, and volumes for a
    Docker application.
  icon: arrows-right-left
  link: /reference/compose-file
- title: Use Compose Bridge
  description: Transform your Compose configuration file into configuration files for different platforms, such as Kubernetes.
  icon: arrow-down
  link: /compose/bridge
- title: Browse common FAQs
  description: Explore general FAQs and find out how to give feedback.
  icon: question-mark-circle
  link: /compose/faq
aliases:
- /compose/overview/
- /compose/swarm/
- /compose/releases/migrate/
---

Docker Compose is a tool for defining and running multi-container applications. 
It is the key to unlocking a streamlined and efficient development and deployment experience. 

Compose simplifies the control of your entire application stack, making it easy to manage services, networks, and volumes in a single YAML configuration file. Then, with a single command, you create and start all the services
from your configuration file.

Compose works in all environments - production, staging, development, testing, as
well as CI workflows. It also has commands for managing the whole lifecycle of your application:

 - Start, stop, and rebuild services
 - View the status of running services
 - Stream the log output of running services
 - Run a one-off command on a service

{{< grid >}}

---

### Manuals Desktop  Index (`content/manuals/desktop/_index.md`)

---
title: Docker Desktop
weight: 10
description: Explore Docker Desktop, what it has to offer, and its key features. Take the next step by downloading or find additional resources
keywords: how to use docker desktop, what is docker desktop used for, what does docker
  desktop do, using docker desktop
params:
  sidebar:
    group: Application development
grid:
- title: Install Docker Desktop
  description: |
    Install Docker Desktop on
    [Mac](/desktop/setup/install/mac-install/),
    [Windows](/desktop/setup/install/windows-install/), or
    [Linux](/desktop/setup/install/linux/).
  icon: arrow-down-tray
- title: Learn about Docker Desktop
  description: Navigate Docker Desktop.
  icon: magnifying-glass
  link: /desktop/use-desktop/
- title: Explore its key features
  description: |
    Find information about [Networking](/desktop/features/networking/), [Docker VMM](/desktop/features/vmm/), [WSL](/desktop/features/wsl/), and more.
  icon: squares-2x2
- title: View the release notes
  description: Find out about new features, improvements, and bug fixes.
  icon: document-plus
  link: /desktop/release-notes/
- title: Browse common FAQs
  description: Explore general FAQs or FAQs for specific platforms.
  icon: question-mark-circle
  link: /desktop/troubleshoot-and-support/faqs/general/
- title: Give feedback
  description: Provide feedback on Docker Desktop or Docker Desktop features.
  icon: chat-bubble-left
  link: /desktop/troubleshoot-and-support/feedback/
aliases:
  - /desktop/mac/
  - /desktop/windows/
  - /docker-for-mac/
  - /docker-for-windows/
  - /desktop/get-started/
---

Docker Desktop is a one-click-install application for your Mac, Linux, or Windows environment
that lets you build, share, and run containerized applications and microservices. 

It provides a straightforward GUI (Graphical User Interface) that lets you manage your containers, applications, and images directly from your machine. 

Docker Desktop reduces the time spent on complex setups so you can focus on writing code. It takes care of port mappings, file system concerns, and other default settings, and is regularly updated with bug fixes and security updates.

Docker Desktop integrates with your preferred development tools and languages, and gives you access to a vast ecosystem of trusted images and templates via Docker Hub. This empowers teams to accelerate development, automate builds, enable CI/CD workflows, and collaborate securely through shared repositories.

## Key features

* Ability to containerize and share any application on any cloud platform, in multiple languages and frameworks.
* Quick installation and setup of a complete Docker development environment.
* Includes the latest version of Kubernetes.
* On Windows, the ability to toggle between Linux and Windows containers to build applications.
* Fast and reliable performance with native Windows Hyper-V virtualization.
* Ability to work natively on Linux through WSL 2 on Windows machines.
* Volume mounting for code and data, including file change notifications and easy access to running containers on the localhost network.

## Products inside Docker Desktop

- [Docker MCP Toolkit and Catalog](/manuals/desktop/features/mcp-catalog-and-toolkit/_index.md)
- [Docker Model Runner](/manuals/ai/model-runner/_index.md)
- [Gordon](/manuals/ai/gordon/_index.md)
- [Docker Offload](/manuals/offload/_index.md)
- [Docker Engine](/manuals/engine/_index.md)
- Docker CLI client
- [Docker Build](/manuals/build/_index.md)
- [Docker Compose](/manuals/compose/_index.md)
- [Docker Scout](../scout/_index.md)
- [Kubernetes](https://github.com/kubernetes/kubernetes/)

## Next steps

{{< grid >}}

---

### Manuals Dhi  Index (`content/manuals/dhi/_index.md`)

---
title: Docker Hardened Images
description: Secure, minimal, and production-ready base images
weight: 8
aliases:
  - /dhi/features/
  - /dhi/features/secure/
  - /dhi/features/integration/
  - /dhi/features/support/
  - /dhi/features/patching/
  - /dhi/features/flexible/
  - /dhi/features/helm/
params:
  sidebar:
    group: Supply chain security
  grid_sections:
    - title: Quickstart
      description: Follow a step-by-step guide to explore and run a Docker Hardened Image.
      icon: rocket-launch
      link: /dhi/get-started/
    - title: Explore
      description: Learn what Docker Hardened Images are, how they're built, and what sets them apart from typical base images.
      icon: information-circle
      link: /dhi/explore/
    - title: How-tos
      description: Step-by-step guides for using, verifying, scanning, and migrating to Docker Hardened Images.
      icon: play
      link: /dhi/how-to/
    - title: Security concepts
      description: Understand the secure supply chain principles that make Docker Hardened Images production-ready.
      icon: clipboard-document-check
      link: /dhi/explore/security-concepts/
    - title: Tools
      description: Browse and manage Docker Hardened Images using Docker Hub, the CLI, MCP server, or Terraform.
      icon: wrench-screwdriver
      link: /dhi/tools/
    - title: Resources and feedback
      description: Guides, GitHub repositories, community channels, and how to give feedback.
      icon: link
      link: /dhi/resources/
    - title: Release notes
      description: New features, improvements, and changes in Docker Hardened Images.
      icon: newspaper
      link: /dhi/release-notes/platform/
---

Docker Hardened Images (DHI) provide minimal, secure, and production-ready
container images, Helm charts, and system packages maintained by Docker.
Designed to reduce vulnerabilities and simplify compliance, DHI integrates
easily into your existing Docker-based workflows with little to no retooling
required.

DHI is available in the following three subscriptions.

| Feature | Community | Select | Enterprise |
|---|---|---|---|
| Hardened, minimal images | ✅ | ✅ | ✅ |
| Near-zero CVEs | ✅ | ✅ | ✅ |
| Verifiable SBOMs & SLSA Build L3 provenance | ✅ | ✅ | ✅ |
| Full, unsuppressed CVE visibility | ✅ | ✅ | ✅ |
| Drop-in adoption, no workflow changes | ✅ | ✅ | ✅ |
| Full catalog of open source images under Apache 2.0 | ✅ | ✅ | ✅ |
| Built with Docker Hardened System Packages | ✅ | ✅ | ✅ |
| Upstream cadence for Docker-released patches | ✅ | ✅ | ✅ |
| FIPS/STIG variants | ❌ | ✅ | ✅ |
| Critical CVE fixes < 7 days with SLA-backed continuous patching | ❌ | ✅ | ✅ |
| Customizations | ❌ | ✅ Up to 5 | ✅ Unlimited |
| Access to Hardened System Packages repository | ❌ | ❌ | ✅ |
| Full catalog access available | ❌ | ❌ | ✅ |
| Extended Lifecycle Support add-on available | ❌ | ❌ | ✅ +5 years of hardened updates |

For pricing and more details, see the [Docker Hardened Images subscription
comparison](https://www.docker.com/products/hardened-images/#compare).

## Community features

DHI's core features are free to use, share, and build on under Apache 2.0.

- [Near-zero CVEs](/dhi/explore/security-concepts/cves/): continuously scanned and patched
  to maintain minimal known vulnerabilities
- [Distroless variants](/dhi/explore/security-concepts/distroless/): remove unnecessary
  components, reducing attack surface by up to 95%
- Non-root execution: containers run as non-root by default
- [Hardened system packages](/dhi/how-to/hardened-packages/): system packages
  built from source, cryptographically signed, and verified by Docker
- [SLSA Build Level 3 provenance](/dhi/explore/security-concepts/slsa/), [signed
  SBOMs](/dhi/explore/security-concepts/sbom/), [VEX statements](/dhi/explore/security-concepts/vex/),
  and [cryptographic signatures](/dhi/explore/security-concepts/signatures/) on every image
- Built on Alpine and Debian with [glibc and musl
  variants](/dhi/explore/security-concepts/glibc-musl/); dev and runtime image variants
  available
- Works with existing Docker workflows, CI/CD pipelines, and tools with no
  retooling required
- [Helm charts](/dhi/how-to/helm/): Docker-provided charts built from upstream
  sources, tested for compatibility with DHI, and available as OCI artifacts in
  the DHI catalog; include SLSA Level 3 provenance, SBOMs, and cryptographic
  signing

## Select and Enterprise features

For organizations with strict security or compliance requirements:

- [7-day SLA](https://docs.docker.com/go/dhi-sla/) for critical and high
  severity CVE remediation
- [FIPS-enabled](/dhi/explore/security-concepts/fips/) and
  [STIG-ready](/dhi/explore/security-concepts/stig/) compliance variants
- [Customization](/dhi/how-to/customize/): add packages, tools, certificates,
  and configurations (up to 5 with Select, unlimited with Enterprise)
- [Enterprise package repository](/dhi/how-to/hardened-packages/) access and
  full catalog access (Enterprise)
- Extended Lifecycle Support: post-EOL security patches, updated SBOMs,
  provenance, and signing (Enterprise add-on)

## Get started

Explore the sections below to get started with Docker Hardened Images, integrate
them into your workflow, and learn what makes them secure and enterprise-ready.

{{< grid items="grid_sections" >}}

---

### Manuals Docker Hub  Index (`content/manuals/docker-hub/_index.md`)

---
description: Get an overview on Docker Hub to find and share container images
keywords: docker hub, hub, repositories
title: Docker Hub
weight: 30
params:
  sidebar:
    group: Supply chain security
grid:
- title: Quickstart
  description: Step-by-step instructions on getting started on Docker Hub.
  icon: magnifying-glass-plus
  link: /docker-hub/quickstart
- title: Library
  description: Explore the content library, featuring millions of images for operating systems, frameworks, databases, and more.
  icon: book-open
  link: /docker-hub/image-library/
- title: Repositories
  description: Create a repository to share your images with your team, customers,
    or the Docker community.
  icon: inbox
  link: /docker-hub/repos
- title: Settings
  description: Learn about settings in Docker Hub.
  icon: cog-6-tooth
  link: /docker-hub/settings
- title: Organizations
  description: Learn about organization administration.
  icon: building-storefront
  link: /accounts/organization/
- title: Usage and limits
  description: Explore usage limits and how to better utilize Docker Hub.
  icon: chart-bar
  link: /docker-hub/usage/
- title: MCP server
  description: Use the Docker Hub MCP server to access image metadata and manage repositories with AI agents.
  icon: server-stack
  link: /docker-hub/mcp-server/
- title: Release notes
  description: Find out about new features, improvements, and bug fixes.
  icon: document-plus
  link: /docker-hub/release-notes
aliases:
  - /docker-hub/overview/
---

Docker Hub simplifies development with the world's largest container registry
for storing, managing, and sharing Docker images. By integrating seamlessly with
your tools, it enhances productivity and ensures reliable deployment,
distribution, and access to containerized applications. It also provides
developers with pre-built images and assets to speed up development workflows.

Key features of Docker Hub:

* Unlimited public repositories
* Private repositories
* Webhooks to automate workflows
* GitHub and Bitbucket integrations
* Concurrent and automated builds
* Trusted content featuring high-quality, secure images

In addition to the graphical interface, you can interact with Docker Hub using
the [Docker Hub API](../../reference/api/hub/latest.md), the experimental [Docker
Hub CLI tool](https://github.com/docker/hub-tool#readme), or the [Docker Hub
MCP server](/docker-hub/mcp-server/) for AI agent integrations.

{{< grid >}}

---

### Manuals Docker Hub Quickstart (`content/manuals/docker-hub/quickstart.md`)

---
description: Learn how to get started using Docker Hub
keywords: Docker Hub, push image, pull image, repositories
title: Docker Hub quickstart
linkTitle: Quickstart
weight: 10
---

Docker Hub provides a vast library of pre-built images and resources,
accelerating development workflows and reducing setup time. You can build upon
pre-built images from Docker Hub and then use repositories to share and
distribute your own images with your team or millions of other developers.

This guide shows you how to find and run a pre-built image. It then walks you
through creating a custom image and sharing it through Docker Hub.

## Prerequisites

- [Download and install Docker](../../get-started/get-docker.md)
- A verified [Docker](https://app.docker.com/signup) account

## Step 1: Find an image in Docker Hub's library

You can search for content in Docker Hub itself, in the Docker Desktop
Dashboard, or by using the CLI.

To search or browse for content on Docker Hub:

{{< tabs >}}
{{< tab name="Docker Hub" >}}

1. Navigate to the [Docker Hub Explore page](https://hub.docker.com/explore).

   On the **Explore** page, you can browse by catalog or category, or use the search
   to quickly find content.

2. Under **Categories**, select **Web servers**.

   After the results are displayed, you can further filter the results using the
   filters on the left side of the page.

3. In the filters, select **Docker Official Image**.

   Filtering by Trusted Content ensures that you see only high-quality, secure
   images curated by Docker and verified publishing partners.

4. In the results, select the **nginx** image.

   Selecting the image opens the image's page where you can learn more about how
   to use the image. On the page, you'll also find the `docker pull` command to
   pull the image.

{{< /tab >}}
{{< tab name="Docker Desktop" >}}

1. Open the Docker Desktop Dashboard.
2. Select the **Docker Hub** view.

   In the **Docker Hub** view, you can browse by catalog or category, or use the search
   to quickly find content.

3. Leave the search box empty and then select **Search**.

   The search results are shown with additional filters now next to the search box.

4. Select the search filter icon, and then select **Docker Official Image** and **Web Servers**.
5. In the results, select the **nginx** image.

{{< /tab >}}
{{< tab name="CLI" >}}

1. Open a terminal window.

   > [!TIP]
   >
   > The Docker Desktop Dashboard contains a built-in terminal. At the bottom of
   > the Dashboard, select **>_ Terminal** to open it.

2. In the terminal, run the following command.

   ```console
   $ docker search --filter is-official=true nginx
   ```

   Unlike the Docker Hub and Docker Desktop interfaces, you can't browse by
   category using the `docker search` command. For more details about the
   command, see [docker search](/reference/cli/docker/search/).

{{< /tab >}}
{{< /tabs >}}

Now that you've found an image, it's time to pull and run it on your device.

## Step 2: Pull and run an image from Docker Hub

You can run images from Docker Hub using the CLI or Docker Desktop Dashboard.

{{< tabs >}}
{{< tab name="Docker Desktop" >}}

1. In the Docker Desktop Dashboard, select the **nginx** image in the **Docker
   Hub** view. For more details, see [Step 1: Find an image in Docker Hub's
   library](#step-1-find-an-image-in-docker-hubs-library).

2. On the **nginx** screen, select **Run**.

   If the image doesn't exist on your device, it is automatically pulled from
   Docker Hub. Pulling the image may take a few seconds or minutes depending on
   your connection. After the image has been pulled, a window appears in Docker
   Desktop and you can specify run options.

3. In the **Host port** option, specify `8080`.
4. Select **Run**.

   The container logs appear after the container starts.

5. Select the **8080:80** link to open the server, or visit
   [http://localhost:8080](http://localhost:8080) in your web browser.

6. In the Docker Desktop Dashboard, select the **Stop** button to stop the
   container.


{{< /tab >}}
{{< tab name="CLI" >}}

1. Open a terminal window.

   > [!TIP]
   >
   > The Docker Desktop Dashboard contains a built-in terminal. At the bottom of
   > the Dashboard, select **>_ Terminal** to open it.

2. In your terminal, run the following command to pull and run the Nginx image.

   ```console
   $ docker run -p 8080:80 --rm nginx
   ```

   The `docker run` command automatically pulls and runs the image without the
   need to run `docker pull` first. To learn more about the command and its
   options, see the [`docker run` CLI
   reference](/reference/cli/docker/container/run/). After running the
   command, you should see output similar to the following.

   ```
/* Detailed source-code truncated for AI context efficiency. */
```

3. Visit [http://localhost:8080](http://localhost:8080) to view the default
   Nginx page and verify that the container is running.

4. In the terminal, press <kdb>Ctrl+C</kbd> to stop the container.

{{< /tab >}}
{{< /tabs >}}

You've now run a web server without any set up or configuration. Docker Hub
provides instant access to pre-built, ready-to-use container images, letting you
quickly pull and run applications without needing to install or configure
software manually. With Docker Hub's vast library of images, you can experiment
with and deploy applications effortlessly, boosting productivity and making it
easy to try out new tools, set up development environments, or build on top of
existing software.

You can also extend images from Docker Hub, letting you quickly build and
customize your own images to suit specific needs.


## Step 3: Build and push an image to Docker Hub

1. Create a [Dockerfile](/reference/dockerfile.md) to specify your application:

   ```dockerfile
   FROM nginx
   RUN echo "<h1>Hello world from Docker!</h1>" > /usr/share/nginx/html/index.html
   ```

   This Dockerfile extends the Nginx image from Docker Hub to create a
   simple website. With just a few lines, you can easily set up, customize, and
   share a static website using Docker.

2. Run the following command to build your image. Replace `<YOUR-USERNAME>` with your Docker ID.

   ```console
   $ docker build -t <YOUR-USERNAME>/nginx-custom .
   ```

   This command builds your image and tags it so that Docker understands which
   repository to push it to in Docker Hub. To learn more about the command and
   its options, see the [`docker build` CLI
   reference](/reference/cli/docker/buildx/build/). After running the
   command, you should see output similar to the following.

   ```console {collapse=true}
   [+] Building 0.6s (6/6) FINISHED                      docker:desktop-linux
    => [internal] load build definition from Dockerfile                  0.0s
    => => transferring dockerfile: 128B                                  0.0s
    => [internal] load metadata for docker.io/library/nginx:latest       0.0s
    => [internal] load .dockerignore                                     0.0s
    => => transferring context: 2B                                       0.0s
    => [1/2] FROM docker.io/library/nginx:latest                         0.1s
    => [2/2] RUN echo "<h1>Hello world from Docker!</h1>" > /usr/share/  0.2s
    => exporting to image                                                0.1s
    => => exporting layers                                               0.0s
    => => writing image sha256:f85ab68f4987847713e87a95c39009a5c9f4ad78  0.0s
    => => naming to docker.io/mobyismyname/nginx-custom                  0.0s
   ```

3. Run the following command to test your image. Replace `<YOUR-USERNAME>` with
   your Docker ID.

   ```console
   $ docker run -p 8080:80 --rm <YOUR-USERNAME>/nginx-custom
   ```

4. Visit [http://localhost:8080](http://localhost:8080) to view the page. You
   should see `Hello world from Docker!`.

5. In the terminal, press CTRL+C to stop the container.

6. Sign in to Docker Desktop. You must be signed in before pushing an image to
   Docker Hub.

7. Run the following command to push your image to Docker Hub. Replace `<YOUR-USERNAME>` with your Docker ID.

   ```console
   $ docker push <YOUR-USERNAME>/nginx-custom
   ```

    > [!NOTE]
    >
    > You must be signed in to Docker Hub through Docker Desktop or the command line, and you must also name your images correctly, as per the above steps.

   The command pushes the image to Docker Hub and automatically
   creates the repository if it doesn't exist. To learn more about the command,
   see the [`docker push` CLI
   reference](/reference/cli/docker/image/push/). After running the
   command, you should see output similar to the following.

   ```console {collapse=true}
   Using default tag: latest
   The push refers to repository [docker.io/mobyismyname/nginx-custom]
   d0e011850342: Pushed
   e4e9e9ad93c2: Mounted from library/nginx
   6ac729401225: Mounted from library/nginx
   8ce189049cb5: Mounted from library/nginx
   296af1bd2844: Mounted from library/nginx
   63d7ce983cd5: Mounted from library/nginx
   b33db0c3c3a8: Mounted from library/nginx
   98b5f35ea9d3: Mounted from library/nginx
   latest: digest: sha256:7f5223ae866e725a7f86b856c30edd3b86f60d76694df81d90b08918d8de1e3f size: 1985
   ```

  Now that you've created a repository and pushed your image, it's time to view
  your repository and explore its options.

## Step 4: View your repository on Docker Hub and explore options

You can view your Docker Hub repositories in the Docker Hub or Docker Desktop interface.

{{< tabs >}}
{{< tab name="Docker Hub" >}}

1. Go to [Docker Hub](https://hub.docker.com) and sign in.

   After signing in, you should be on the **Repositories** page. If not, then go
   to the [**Repositories**](https://hub.docker.com/repositories/) page.

2. Find the **nginx-custom** repository and select that row.

   After selecting the repository, you should see more details and options for
   your repository.

{{< /tab >}}
{{< tab name="Docker Desktop" >}}

1. Sign in to Docker Desktop.
2. Select the **Images** view.
3. Select the **Hub repositories** tab.

   A list of your Docker Hub repositories appears.

4. Find the **nginx-custom** repository, hover over the row, and then select **View in Hub**.

   Docker Hub opens and you are able to view more details about the image.

{{< /tab >}}
{{< /tabs >}}

You've now verified that your repository exists on Docker Hub, and you've
discovered more options for it. View the next steps to learn more about some of
these options.

## Next steps

Add [repository information](./repos/manage/information.md) to help users find and use
your image.

---

### Manuals Engine  Index (`content/manuals/engine/_index.md`)

---
title: Docker Engine
weight: 10
description: Find a comprehensive overview of Docker Engine, including how to install, storage details, networking, and more
keywords: Engine
params:
  sidebar:
    group: Application development
grid:
- title: Install Docker Engine
  description: Learn how to install the open source Docker Engine for your distribution.
  icon: arrow-down-tray
  link: /engine/install
- title: Storage
  description: Use persistent data with Docker containers.
  icon: circle-stack
  link: /storage
- title: Networking
  description: Manage network connections between containers.
  icon: server-stack
  link: /network
- title: Container logs
  description: Learn how to view and read container logs.
  icon: document-text
  link: /config/containers/logging/
- title: Prune
  description: Tidy up unused resources.
  icon: scissors
  link: /config/pruning
- title: Configure the daemon
  description: Delve into the configuration options of the Docker daemon.
  icon: adjustments-horizontal
  link: /config/daemon
- title: Rootless mode
  description: Run Docker without root privileges.
  icon: shield-check
  link: /engine/security/rootless
- title: Deprecated features
  description: Find out what features of Docker Engine you should stop using.
  icon: folder-minus
  link: /engine/deprecated/
- title: Release notes
  description: Read the release notes for the latest version.
  icon: document-plus
  link: /engine/release-notes
aliases:
- /edge/
- /engine/ce-ee-node-activate/
- /engine/migration/
- /engine/misc/
- /linux/
---

Docker Engine is an open source containerization technology for building and
containerizing your applications. Docker Engine acts as a client-server
application with:

- A server with a long-running daemon process
  [`dockerd`](/reference/cli/dockerd).
- APIs which specify interfaces that programs can use to talk to and instruct
  the Docker daemon.
- A command line interface (CLI) client
  [`docker`](/reference/cli/docker/).

The CLI uses [Docker APIs](/reference/api/engine/_index.md) to control or interact with the Docker
daemon through scripting or direct CLI commands. Many other Docker applications
use the underlying API and CLI. The daemon creates and manages Docker objects,
such as images, containers, networks, and volumes.

For more details, see
[Docker Architecture](/get-started/docker-overview.md#docker-architecture).

{{< grid >}}

## Licensing

Commercial use of Docker Engine obtained via Docker Desktop
within larger enterprises (exceeding 250 employees OR with annual revenue surpassing
$10 million USD), requires a [paid subscription](https://www.docker.com/pricing?ref=Docs&refAction=DocsEngine).
Apache License, Version 2.0. See [LICENSE](https://github.com/moby/moby/blob/master/LICENSE) for the full license.

---

### Manuals Extensions  Index (`content/manuals/extensions/_index.md`)

---
title: Docker Extensions
weight: 60
description: Extensions
keywords: Docker Extensions, Docker Desktop, Linux, Mac, Windows
params:
  sidebar:
    group: Application development
aliases:
 - /desktop/extensions/
---

Docker Extensions let you use third-party tools within Docker Desktop to extend its functionality.

You can seamlessly connect your favorite development tools to your application development and deployment workflows. Augment Docker Desktop with debugging, testing, security, and networking functionalities, and create custom add-ons using the Extensions [SDK](extensions-sdk/_index.md).

Anyone can use Docker Extensions and there is no limit to the number of extensions you can install.

## What extensions are available?

There is a mix of partner and community-built extensions and Docker-built extensions.
You can explore the list of available extensions in [Docker Hub](https://hub.docker.com/search?q=&type=extension) or in the Extensions Marketplace within Docker Desktop.

## Security and trust

Docker Extensions run with elevated privileges on your host machine. They have direct access to the Docker Engine, can read and write files on your filesystem, and can install and run native binaries. 

Docker reviews extensions submitted to the Marketplace, but does not guarantee the security of any extension. Extensions installed outside the Marketplace have not been reviewed at all. Only install extensions from publishers you trust. 

If you're an organization admin, see [Configure a private marketplace](private-marketplace.md) to control which extensions your team can install.

---

### Manuals Faqs  Index (`content/manuals/faqs/_index.md`)

---
title: FAQs
linkTitle: FAQs
description: Frequently asked questions about Docker accounts, subscriptions, billing, and security.
keywords: FAQ, FAQs, accounts, Docker ID, Docker Home, subscription FAQs, billing FAQs, security FAQs, SSO FAQs
weight: 45
params:
  sidebar:
    group: Accounts and admin
aliases:
  - /faq/security/
grid:
  - title: Account FAQs
    description: FAQs about Docker IDs, account creation, organizations, and companies.
    icon: question-mark-circle
    link: /faqs/accounts/
  - title: Security FAQs
    description: FAQs about single sign-on, identity providers, enforcement, and domains.
    icon: lock-closed
    link: /faqs/security/
  - title: Subscription and billing FAQs
    description: FAQs about Docker plans, payments, taxes, and invoices.
    icon: credit-card
    link: /faqs/subscription-billing/
  - title: Platform FAQs
    description: FAQs about Docker Desktop containers, networking, VMs, and general platform security.
    icon: cpu-chip
    link: /faqs/platform/
---

Answers to common questions about Docker accounts, organizations, companies,
subscriptions, billing, and security.

## Next steps

{{< grid >}}

---

### Manuals Offload  Index (`content/manuals/offload/_index.md`)

---
title: Docker Offload
weight: 15
description: Find documentation on Docker Offload to help you offload containers to the cloud.
keywords: build, cloud, cloud build, remote builder
params:
  sidebar:
    group: Application development

grid:

- title: Quickstart
  description: Get up and running with Docker Offload in just a few steps.
  icon: rocket-launch
  link: /offload/quickstart/

- title: About
  description: Learn about Docker Offload and how it works.
  icon: information-circle
  link: /offload/about/

- title: Configure
  description: Configure Docker Offload settings for your organization and Docker Desktop.
  icon: adjustments-horizontal
  link: /offload/configuration/

- title: Usage
  description: Learn about Docker Offload usage and how to monitor your cloud resources.
  icon: heart
  link: /offload/usage/

- title: Optimize
  description: Improve performance and cost efficiency in Docker Offload.
  icon: bolt
  link: /offload/optimize/

- title: Troubleshoot
  description: Learn how to troubleshoot issues with Docker Offload.
  icon: bug-ant
  link: /offload/troubleshoot/

- title: Feedback
  description: Provide feedback on Docker Offload.
  icon: chat-bubble-left
  link: /offload/feedback/

aliases:
- /harmonia/
---

{{< summary-bar feature_name="Docker Offload" >}}

Docker Offload is a fully managed service that lets you offload building and
running containers to the cloud using the Docker tools you already know. It
enables developers to work efficiently in virtual desktop infrastructure (VDI)
environments or systems that don't support nested virtualization.

In the following topics, learn about Docker Offload, how to set it up, use it
for your workflows, and troubleshoot common issues.

{{< grid >}}

---

### Manuals Offload Quickstart (`content/manuals/offload/quickstart.md`)

---
title: Docker Offload quickstart
linktitle: Quickstart
weight: 10
description: Learn how to use Docker Offload to build and run your container images in the cloud.
keywords: cloud, quickstart, Docker Desktop, offload
---

{{< summary-bar feature_name="Docker Offload" >}}

[Docker Offload](./about.md) lets you build and run containers in the cloud
while using your local Docker Desktop tools and workflow. This means faster
builds, access to powerful cloud resources, and a seamless development
experience.

This quickstart covers the steps developers need to get started with Docker Offload.

> [!NOTE]
>
> If you're an organization owner, to get started you must <a href="https://www.docker.com/pricing/contact-sales/" id="dkr_docs_cs_offload_quickstart" class="link" rel="noopener">contact sales</a> and subscribe your
> organization to use Docker Offload. After subscribing, see [Manage Docker
> products](../accounts/organization/manage/manage-products.md) to learn how to manage
> access for the developers in your organization.


## Prerequisites

- You must have [Docker Desktop](/desktop/) installed. Docker recommends using
  the latest version of Docker Desktop to access the newest features and
  improvements in Docker Offload.
- You must have a Docker Business subscription and a Docker Offload subscription.

## Step 1: Verify access to Docker Offload

To access Docker Offload, you must be part of an organization that has
subscribed to Docker Offload. As a developer, you can verify this by checking if
the Docker Offload toggle appears in the Docker Desktop Dashboard header.

1. Start Docker Desktop and sign in.
2. In the Docker Desktop Dashboard header, look for the Docker Offload toggle.



If you see the Docker Offload toggle, you have access to Docker Offload and can
proceed to the next step. If you don't see the Docker Offload toggle, check if
Docker Offload is disabled in your [Docker Desktop
settings](./configuration.md), and then contact your administrator to verify
that your organization has subscribed to Docker Offload and that they have
enabled access for your organization.

## Step 2: Start Docker Offload

You can start Docker Offload from the CLI or in the header of the Docker Desktop
Dashboard. The following steps describe how to start Docker Offload using the
CLI.

1. Start Docker Desktop and sign in.
2. Open a terminal and run the following command to start Docker Offload:

   ```console
   $ docker offload start
   ```

   > [!TIP]
   >
   > To learn more about the Docker Offload CLI commands, see the [Docker Offload CLI
   > reference](/reference/cli/docker/offload/).

3. If you are a member of multiple organizations that have access to Docker
   Offload, you have the option to select a profile. Your usage will be
   associated with the organization of the selected profile.


When Docker Offload is started, you'll see a cloud icon ({{< inline-image
src="./images/cloud-mode.png" alt="Offload mode icon" >}}) in the Docker Desktop
Dashboard header, and the Docker Desktop Dashboard appears purple. You can run
`docker offload status` in a terminal to check the status of Docker Offload.

## Step 3: Run a container with Docker Offload

After starting Docker Offload, Docker Desktop connects to a secure cloud
environment that mirrors your local experience. When you run builds or
containers, they execute remotely, but behave just like local ones.

To verify that Docker Offload is working, run a container:

```console
$ docker run --rm hello-world
```

If Docker Offload is working, you'll see `Hello from Docker!` in the terminal output.

## Step 4: Monitor your Offload session

When Docker Offload is started and you have started session (for example, you've
ran a container), then you can see current session duration estimate in the
Docker Desktop Dashboard footer next to the hourglass icon ({{< inline-image
src="./images/hourglass-icon.png" alt="Offload session duration" >}}).

Also, when Docker Offload is started, you can view detailed session information
by selecting **Docker Offload** > **Insights** in the left navigation of the
Docker Desktop Dashboard.

## Step 5: Stop Docker Offload

Docker Offload automatically
[idles](./about.md#session-management-and-idle-state) if you do not respond to
periodic prompts that appear in the Docker Desktop Dashboard. You can stop your
Docker Offload session at any time. To stop Docker Offload:

```console
$ docker offload stop
```

When you stop Docker Offload, the cloud environment is terminated and all
running containers and images are removed. When Docker Offload has been idle for
5 minutes, the environment is also terminated and all running containers and
images are removed.

To start Docker Offload again, run the `docker offload start` command.

---

### Manuals Scout  Index (`content/manuals/scout/_index.md`)

---
title: Docker Scout
weight: 40
keywords: scout, supply chain, vulnerabilities, packages, cves, scan, analysis, analyze
description:
  Get an overview on Docker Scout to proactively enhance your software supply chain security
aliases:
  - /engine/scan/
params:
  sidebar:
    group: Supply chain security
grid:
  - title: Quickstart
    link: /scout/quickstart/
    description: Learn what Docker Scout can do, and how to get started.
    icon: magnifying-glass-plus
  - title: Image analysis
    link: /scout/image-analysis/
    description: Reveal and dig into the composition of your images.
    icon: signal
  - title: Advisory database
    link: /scout/advisory-db-sources/
    description: Learn about the information sources that Docker Scout uses.
    icon: circle-stack
  - title: Integrations
    description: |
      Connect Docker Scout with your CI, registries, and other third-party services.
    link: /scout/integrations/
    icon: arrows-right-left
  - title: Dashboard
    link: /scout/dashboard/
    description: |
      The web interface for Docker Scout.
    icon: squares-2x2
  - title: Policy
    link: /scout/policy/
    description: |
      Ensure that your artifacts align with supply chain best practices.
    icon: shield-check
  - title: Upgrade
    link: /subscription-billing/manage/plans/
    description: |
      A Personal subscription includes up to 1 repository. Upgrade for more.
    icon: arrow-up-circle
---

Container images consist of layers and software packages, which are susceptible to vulnerabilities.
These vulnerabilities can compromise the security of containers and applications.

Docker Scout is a solution for proactively enhancing your software supply chain security.
By analyzing your images, Docker Scout compiles an inventory of components, also known as a Software Bill of Materials (SBOM).
The SBOM is matched against a continuously updated vulnerability database to pinpoint security weaknesses.

Docker Scout is a standalone service and platform that you can interact with
using Docker Hub, the Docker CLI, and the Docker Scout Dashboard.

{{< grid >}}

---

### Manuals Scout Quickstart (`content/manuals/scout/quickstart.md`)

---
title: Docker Scout quickstart
linkTitle: Quickstart
weight: 20
keywords: scout, supply chain, vulnerabilities, packages, cves, scan, analysis, analyze
description: Learn how to get started with Docker Scout to analyze images and fix vulnerabilities
---

Docker Scout analyzes image contents and generates a detailed report of packages
and vulnerabilities that it detects. It can provide you with
suggestions for how to remediate issues discovered by image analysis.

This guide takes a vulnerable container image and shows you how to use Docker
Scout to identify and fix the vulnerabilities, compare image versions over time,
and share the results with your team.

## Step 1: Setup

[This example project](https://github.com/docker/scout-demo-service) contains
a vulnerable Node.js application that you can use to follow along.

1. Clone its repository:

   ```console
   $ git clone https://github.com/docker/scout-demo-service.git
   ```

2. Move into the directory:

   ```console
   $ cd scout-demo-service
   ```

3. Make sure you're signed in to your Docker account,
   either by running the `docker login` command or by signing in with Docker Desktop.

4. Build the image and push it to a `<ORG_NAME>/scout-demo:v1`,
   where `<ORG_NAME>` is the Docker Hub namespace you push to.

   ```console
   $ docker build --push -t <ORG_NAME>/scout-demo:v1 .
   ```

## Step 2: Enable Docker Scout

Docker Scout analyzes all local images by default. To analyze images in
remote repositories, you need to enable it first.
You can do this from Docker Hub, the Docker Scout Dashboard, and CLI.
[Find out how in the overview guide](/scout).

1. Sign in to your Docker account with the `docker login` command or use the
   **Sign in** button in Docker Desktop.

2. Next, enroll your organization with Docker Scout, using the `docker scout enroll` command.

   ```console
   $ docker scout enroll <ORG_NAME>
   ```

3. Enable Docker Scout for your image repository with the `docker scout repo enable` command.

   ```console
   $ docker scout repo enable --org <ORG_NAME> <ORG_NAME>/scout-demo
   ```

## Step 3: Analyze image vulnerabilities

After building, use the `docker scout` CLI command to see vulnerabilities
detected by Docker Scout.

The example application for this guide uses a vulnerable version of Express.
The following command shows all CVEs affecting Express in the image you just
built:

```console
$ docker scout cves --only-package express
```

Docker Scout analyzes the image you built most recently by default,
so there's no need to specify the name of the image in this case.

Learn more about the `docker scout cves` command in the
[`CLI reference documentation`](/reference/cli/docker/scout/cves).

## Step 4: Fix application vulnerabilities

After the Docker Scout analysis, a high vulnerability CVE-2022-24999 was found, caused by an outdated version of the **express** package.

The version 4.17.3 of the express package fixes the vulnerability. Therefore, update the `package.json` file to the new version:

   ```diff
      "dependencies": {
   -    "express": "4.17.1"
   +    "express": "4.17.3"
      }
   ```
   
Rebuild the image with a new tag and push it to your Docker Hub repository:

   ```console
   $ docker build --push -t <ORG_NAME>/scout-demo:v2 .
   ```

Run the `docker scout` command again and verify that HIGH CVE-2022-24999 is no longer present:

```console
$ docker scout cves --only-package express
    ✓ Provenance obtained from attestation
    ✓ Image stored for indexing
    ✓ Indexed 79 packages
    ✓ No vulnerable package detected


  ## Overview

                      │                  Analyzed Image                   
  ────────────────────┼───────────────────────────────────────────────────
    Target            │  mobywhale/scout-demo:v2                   
      digest          │  ef68417b2866                                     
      platform        │ linux/arm64                                       
      provenance      │ https://github.com/docker/scout-demo-service.git  
                      │  7c3a06793fc8f97961b4a40c73e0f7ed85501857         
      vulnerabilities │    0C     0H     0M     0L                        
      size            │ 19 MB                                             
      packages        │ 1                                                 


  ## Packages and Vulnerabilities

  No vulnerable packages detected

```

## Step 5: Evaluate policy compliance

While inspecting vulnerabilities based on specific packages can be useful,
it isn't the most effective way to improve your supply chain conduct.

Docker Scout also supports policy evaluation,
a higher-level concept for detecting and fixing issues in your images.
Policies are a set of customizable rules that let organizations track whether
images are compliant with their supply chain requirements.

Because policy rules are specific to each organization,
you must specify which organization's policy you're evaluating against.
Use the `docker scout config` command to configure your Docker organization.

```console
$ docker scout config organization <ORG_NAME>
    ✓ Successfully set organization to <ORG_NAME>
```

Now you can run the `quickview` command to get an overview
of the compliance status for the image you just built.
The image is evaluated against the default policy configurations. You'll see output similar to the following:

```console
$ docker scout quickview

...
Policy status  FAILED  (2/6 policies met, 2 missing data)

  Status │                  Policy                      │           Results
─────────┼──────────────────────────────────────────────┼──────────────────────────────
  ✓      │ No copyleft licenses                         │    0 packages
  !      │ Default non-root user                        │
  !      │ No fixable critical or high vulnerabilities  │    2C    16H     0M     0L
  ✓      │ No high-profile vulnerabilities              │    0C     0H     0M     0L
  ?      │ No outdated base images                      │    No data
  ?      │ Supply chain attestations                    │    No data
```

Exclamation marks in the status column indicate a violated policy.
Question marks indicate that there isn't enough metadata to complete the evaluation.
A check mark indicates compliance.

## Step 6: Improve compliance

The output of the `quickview` command shows that there's room for improvement.
Some of the policies couldn't evaluate successfully (`No data`)
because the image lacks provenance and SBOM attestations.
The image also failed the check on a few of the evaluations.

Policy evaluation does more than just check for vulnerabilities.
Take the `Default non-root user` policy for example.
This policy helps improve runtime security by ensuring that
images aren't set to run as the `root` superuser by default.

To address this policy violation, edit the Dockerfile by adding a `USER`
instruction, specifying a non-root user:

```diff
  CMD ["node","/app/app.js"]
  EXPOSE 3000
+ USER appuser
```

Additionally, to get a more complete policy evaluation result,
your image should have SBOM and provenance attestations attached to it.
Docker Scout uses the provenance attestations to determine how the image was
built so that it can provide a better evaluation result.

Before you can build an image with attestations,
you must enable the [containerd image store](/manuals/desktop/features/containerd.md)
(or create a custom builder using the `docker-container` driver).
The classic image store doesn't support manifest lists,
which is how the provenance attestations are attached to an image.

Open **Settings** in Docker Desktop. Under the **General** section, make sure
that the **Use containerd for pulling and storing images** option is checked, then select **Apply**.
Note that changing image stores temporarily hides images and containers of the
inactive image store until you switch back.

With the containerd image store enabled, rebuild the image with a new `v3` tag.
This time, add the `--provenance=true` and `--sbom=true` flags.

```console
$ docker build --provenance=true --sbom=true --push -t <ORG_NAME>/scout-demo:v3 .
```

## Step 7: View in Dashboard

After pushing the updated image with attestations, it's time to view the
results through a different lens: the Docker Scout Dashboard.

1. Open the [Docker Scout Dashboard](https://scout.docker.com/).
2. Sign in with your Docker account.
3. Select **Images** in the left-hand navigation.

The images page lists your Scout-enabled repositories.

Select the row for the image you want to view, anywhere in the row except on a link, to open the **Image details** sidebar.

The sidebar shows a compliance overview for the last pushed tag of a repository.

> [!NOTE]
>
> If policy results haven't appeared yet, try refreshing the page.
> It might take a few minutes before the results appear if this is your
> first time using the Docker Scout Dashboard.

Go back to the image list and select the image version, available in the **Most recent image** column.
Then, at the top right of the page, select the **Update base image** button to inspect the policy.

This policy checks whether base images you use are up-to-date.
It currently has a non-compliant status,
because the example image uses an old version `alpine` as a base image.

Close the **Recommended fixes for base image** modal. In the policy listing, select **View fixes** button, next to the policy name for details about the violation, and recommendations on how to address it.

In this case, the recommended action is to update the base image to a newer
version. You can use GitHub Dependabot with `package-ecosystem: "docker"` to
automate base image updates.

## Summary

This quickstart guide has scratched the surface on some of the ways
Docker Scout can support software supply chain management:

- How to enable Docker Scout for your repositories
- Analyzing images for vulnerabilities
- Policy and compliance
- Fixing vulnerabilities and improving compliance

## What's next?

There's lots more to discover, from third-party integrations,
to policy customization, and runtime environment monitoring in real-time.

Check out the following sections:

- [Image analysis](/manuals/scout/explore/analysis.md)
- [Data sources](/scout/advisory-db-sources)
- [Docker Scout Dashboard](/scout/dashboard)
- [Integrations](./integrations/_index.md)
- [Policy evaluation](./policy/_index.md)

---

### Manuals Security  Index (`content/manuals/security/_index.md`)

---
title: Secure Docker accounts and organizations
linkTitle: Security
description: >-
  Secure Docker accounts, manage access, and control membership for
  individuals and organizations in Docker Home.
keywords: docker, docker hub, security, account security, 2FA, access tokens,
  SSO, OIDC, provisioning, roles, Docker Home
weight: 40
aliases:
  - /security/for-developers/
params:
  sidebar:
    group: Accounts and admin
grid:
  - title: Authentication
    description: >-
      Two-factor authentication, single sign-on, and OIDC connections.
    icon: key
    link: /security/authentication/
  - title: Access tokens
    description: >-
      Personal and organization access tokens for the Docker CLI and
      automation.
    icon: lock-closed
    link: /security/access-tokens/
  - title: Provisioning
    description: >-
      Add users with SCIM, JIT, auto-provisioning, and domain management.
    icon: arrow-path
    link: /security/provisioning/
  - title: Roles and permissions
    description: >-
      Assign core or custom roles to control access in your organization.
    icon: shield-check
    link: /security/roles-and-permissions/
---

Security helps individual users and organization owners secure their
accounts, manage access, and control membership. You configure these
settings in [Docker Home](https://app.docker.com/).

## Individual accounts

You sign in with your individual account.

- [Two-factor authentication](/manuals/security/authentication/2fa/_index.md)
  (2FA) adds a time-based one-time password (TOTP) from an authenticator
  app to your password.
- A [personal access token](/manuals/security/access-tokens/personal-access-tokens.md)
  (PAT) authenticates the Docker CLI and tools without your password, and
  is required for CLI sign-in when 2FA is on or single sign-on (SSO) is
  enforced.

## Organization accounts

Organization and company owners set up how members sign in, add them to
the organization, configure automation, and control what members can do.

- [Single sign-on](/manuals/security/authentication/single-sign-on/_index.md)
  (SSO) federates sign-in through your identity provider, which can cover
  one organization or every organization in a company.
- [Provisioning](/manuals/security/provisioning/_index.md) adds users with
  System for Cross-domain Identity Management (SCIM), Just-in-Time (JIT)
  provisioning, auto-provisioning, or domain matching.
- An [organization access token](/manuals/security/access-tokens/organization-access-tokens.md)
  (OAT) stays with the organization when membership changes.
- [OIDC connections](/manuals/security/authentication/oidc-connections/_index.md)
  use OpenID Connect to authenticate GitHub Actions with short-lived
  tokens, as an alternative to a long-lived OAT.
- [Roles and permissions](/manuals/security/roles-and-permissions/_index.md)
  control what members can do after they join.

## Next steps

{{< grid >}}

---

### Manuals Subscription Billing  Index (`content/manuals/subscription-billing/_index.md`)

---
title: Subscription and billing
linkTitle: Subscription and billing
description: Manage Docker subscriptions, plans, billing, and payments.
keywords: subscription, billing, docker plans, payments, invoices, pricing
weight: 20
params:
  sidebar:
    group: Accounts and admin
aliases:
  - /subscription/
  - /billing/
  - /docker-hub/billing/
  - /docker-hub/billing/faq/
  - /billing/docker-hub-pricing/
grid:
  - title: Explore plans
    description: Browse available Docker plans and add-ons for individuals, teams, and organizations.
    link: /subscription-billing/plans/
    icon: chart-bar
  - title: Manage billing
    description: Manage payment methods, invoices, credits, and billing details in the billing portal.
    link: /subscription-billing/manage/
    icon: credit-card
---

A Docker plan is a subscription tied to a personal account, an organization
account, or a specific product. When you upgrade a plan, you expand your
usage entitlements and feature sets. You can also top up some plans,
extending usage without changing your plan type.

## Docker plans

The following table summarizes the available plans.

| Plans | Billing model | Types |
| --- | --- | --- |
| [Docker](/manuals/subscription-billing/plans/docker.md) | Flat-rate plans for personal and organization accounts | Docker Personal, Docker Pro, Docker Team, Docker Business |
| [Docker Hardened Images (DHI)](/manuals/subscription-billing/plans/dhi.md) | Graduated security features for hardened container images | DHI Community, DHI Select, DHI Enterprise |
| [Gordon](/manuals/subscription-billing/plans/gordon.md) | Prepaid usage for the Gordon AI agent | Gordon Plus, Gordon Max, Gordon Ultra |
| [AI Governance](/manuals/subscription-billing/plans/ai-governance.md) | Purchase set amount of licenses | AI Governance |
| [Docker Verified Publisher (DVP)](/manuals/subscription-billing/plans/docker-verified-publisher.md) | Annual plans based on consuming domains | DVP Starter, DVP Growth |

Docker plans that upgrade your account (Docker Pro, Team, and Business) cover
most use cases. Some product plans require an upgraded Docker account. Others
let you subscribe without one. For details, see
[Plans](/manuals/subscription-billing/plans/_index.md).

## Top up your plan

Plans come with usage entitlements that can be extended without upgrading to
a different plan.

| Unit | Description | Examples |
| --- | --- | --- |
| Seats | Each seat extends entitlements to one more member. | Docker Team, Docker Business |
| Licenses | Access to specific products or features. | AI Governance, Docker Offload |
| Minutes | Cloud build capacity, sold in blocks and consumed within the billing period. | Docker Build Cloud |
| Repositories | Additional container repositories covered by security scanning and analysis features. | DHI |
| Consuming domains | Additional consuming domains tracked in publisher analytics, sold in blocks of 25. | DVP Starter, DVP Growth |

## Manage your plans

To subscribe to a new plan or upgrade an active plan, see
[Manage plans](/manuals/subscription-billing/manage/plans.md). See
[Docker plans](/manuals/subscription-billing/plans/docker.md) to learn about
Docker Team, Business, and Pro. You can also
<a href="https://www.docker.com/pricing/contact-sales/" id="dkr_docs_index_sales" class="link" rel="noopener">contact sales</a>.

To update payment methods, review usage and credits, or download invoices, see
[Manage billing](/manuals/subscription-billing/manage/_index.md).

## Next steps

{{< grid >}}

---

### Manuals Support  Index (`content/manuals/support/_index.md`)

---
title: Get support for Docker products
linkTitle: Support
description: >-
  Find Docker support options, including paid subscription response times,
  severity levels, Docker Desktop support scope, and community resources.
keywords: docker support, contact support, subscription support, premium
  support, support response times, severity levels, community forums,
  docker desktop support
weight: 50
params:
  sidebar:
    group: Accounts and admin
---

Docker offers multiple support channels depending on your subscription level
and needs.

## Paid subscription support

All Docker Pro, Team, and Business subscribers receive email support for
Docker products.

### Support response times

- Docker Pro: 5 business day response
- Docker Team: 2 business day response, 24×5 availability
- Docker Business: 1 business day response, 24×5 availability

Docker Verified Publisher (DVP) organizations follow the response times for
their Docker Pro, Team, or Business subscription. Without one of those
subscriptions, the following response times apply:

- DVP Starter: 3 business day response
- DVP Growth: 2 business day response, 24×5 availability

> [!TIP]
>
> Premium Support with faster response times and 24×7 availability is
> available as an add-on for
> [Docker Business and Docker Hardened Images subscribers](https://www.docker.com/pricing?ref=Docs&refAction=DocsSupport).

### Support severity levels

| Level | Description |
| :--- | :--- |
| Critical | Widespread or company-wide service outage affecting many customers or all users within a single organization. Business operations are halted with no workaround available. |
| High | Team or department-level impact preventing significant users from accessing core functionality. Severe business impact with no workaround available. |
| Medium | Individual user or small group impact causing partial loss of functionality. Business operations continue, often with workarounds available but reduced productivity. |

### Request support

> [!TIP]
>
> Before reaching out for support, review the troubleshooting documentation
> for your product.

If you have a paid Docker subscription,
[contact the Support team](https://hub.docker.com/support/contact/).

## Community support

All Docker users can seek support through community resources, where Docker
or the community respond on a best-effort basis:

- [Docker Community Forums](https://forums.docker.com/)
- [Docker Community Slack](http://dockr.ly/comm-slack)

## Docker Desktop support

Docker Desktop support is available with a paid subscription.

### Scope of support

{{< tabs >}}
{{< tab name="Covered" >}}

Docker Desktop support includes:

- Account management and billing
- Configuration and installation issues
- Desktop updates
- Sign-in issues
- Push or pull issues, including rate limiting
- Application crashes or unexpected behavior
- Automated builds
- Basic product how-to questions

On Windows, support also covers:

- Turning on virtualization in BIOS
- Turning on Windows features
- Running inside
  [certain VM or VDI environments](/manuals/desktop/setup/vm-vdi.md)
  (Docker Business only)

{{< /tab >}}
{{< tab name="Not covered" >}}

Docker Desktop support excludes:

- Unsupported operating systems, including beta and preview versions
- Running containers of a different architecture using emulation
- Docker Engine, Docker CLI, or other bundled Linux components
- Kubernetes
- Features labeled as experimental
- System and server administration activities
- Desktop as a production runtime
- Scale deployment and multi-machine installation
- Routine product maintenance (data backup, disk space, log rotation)
- Third-party applications not provided by Docker
- Altered or modified Docker software
- Hardware malfunction, abuse, or improper use
- Versions older than the latest release (except Docker Business)
- Training, customization, and integration
- Running multiple instances on a single machine

> [!NOTE]
>
> Support for
> [running Docker Desktop in a VM or VDI environment](/manuals/desktop/setup/vm-vdi.md)
> is only available to Docker Business customers.

{{< /tab >}}
{{< /tabs >}}

### Supported versions

- Docker Business: Versions up to six months older than the latest version
  (fixes applied to latest version only)
- Docker Pro and Team: Latest version only

### Machines per subscription

- Docker Pro: One machine
- Docker Team: Number of machines equal to subscription seats
- Docker Business: Unlimited machines

### Supported operating systems

- [Mac system requirements](/manuals/desktop/setup/install/mac-install.md#system-requirements)
- [Windows system requirements](/manuals/desktop/setup/install/windows-install.md#system-requirements)
- [Linux system requirements](/manuals/desktop/setup/install/linux/_index.md#system-requirements)

### Docker Desktop community resources

- [Docker Desktop issue tracker](https://github.com/docker/desktop-feedback)

### Diagnostic data and privacy

When uploading diagnostics, the bundle may contain personal data such as
usernames and IP addresses. Diagnostics bundles are only accessible to
Docker, Inc. employees directly involved in diagnosing issues.

By default, Docker, Inc. deletes uploaded diagnostics bundles after 30 days.
You can request removal of a diagnostics bundle by specifying the diagnostics
ID or your GitHub ID. Docker, Inc. only uses the data to investigate specific
user issues but may derive high-level (non-personal) metrics.

For more information, see
[Docker Data Processing Agreement](https://www.docker.com/legal/data-processing-agreement).

---

### Reference Cli  Index (`content/reference/cli/_index.md`)

---
title: CLI reference
weight: 10
build:
  render: never
---

---

### Reference Compose File  Index (`content/reference/compose-file/_index.md`)

---
description:
  Find the latest recommended version of the Docker Compose file format
  for defining multi-container applications.
keywords:
  docker compose file, docker compose yml, docker compose reference, docker
  compose cmd, docker compose user, docker compose image, yaml spec, docker compose
  syntax, yaml specification, docker compose specification
title: Compose file reference
toc_max: 4
toc_min: 1
grid:
  - title: Version and name top-level element
    description: Understand version and name attributes for Compose.
    icon: document-text
    link: /reference/compose-file/version-and-name/
  - title: Services top-level element
    description: Explore all services attributes for Compose.
    icon: wrench-screwdriver
    link: /reference/compose-file/services/
  - title: Networks top-level element
    description: Find all networks attributes for Compose.
    icon: server-stack
    link: /reference/compose-file/networks/
  - title: Volumes top-level element
    description: Explore all volumes attributes for Compose.
    icon: circle-stack
    link: /reference/compose-file/volumes/
  - title: Configs top-level element
    description: Find out about configs in Compose.
    icon: cog-6-tooth
    link: /reference/compose-file/configs/
  - title: Secrets top-level element
    description: Learn about secrets in Compose.
    icon: lock-closed
    link: /reference/compose-file/secrets/
aliases:
  - /compose/compose-file/
  - /compose/reference/overview/
---

> **New to Docker Compose?**
>
> Find more information about the [key features and use cases of Docker Compose](/manuals/compose/intro/features-uses.md) or [try the quickstart guide](/manuals/compose/gettingstarted.md).

The Compose Specification is the latest and recommended version of the Compose file format. It helps you define a [Compose file](/manuals/compose/intro/compose-application-model.md) which is used to configure your Docker application’s services, networks, volumes, and more.

Legacy versions 2.x and 3.x of the Compose file format were merged into the Compose Specification. It is implemented in versions 1.27.0 and above (also known as Compose v2) of the Docker Compose CLI.

The Compose Specification on Docker Docs is the Docker Compose implementation. If you wish to implement your own version of the Compose Specification, see the [Compose Specification repository](https://github.com/compose-spec/compose-spec).

Use the following links to navigate key sections of the Compose Specification.

> [!TIP]
>
> Want a better editing experience for Compose files in VS Code?
> Check out the [Docker DX](https://marketplace.visualstudio.com/items?itemName=docker.docker) extension for linting, code navigation, and vulnerability scanning.

{{< grid >}}

---

### Reference Samples  Index (`content/reference/samples/_index.md`)

---
linkTitle: Samples
title: Samples overview
description: Learn how to containerize different types of services by walking through
  Official Docker samples.
aliases:
- /en/latest/examples/
- /engine/examples/
- /examples/
- /samples/runnning_riak_service/
- /samples/apt-cacher-ng/
- /samples/
---

Learn how to containerize different types of services by walking through Official Docker samples.

## Databases

[MariaDB](../samples/mariadb.md) \| [MongoDB](../samples/mongodb.md) \| [MS-SQL](../samples/ms-sql.md) \| [MySQL](../samples/mysql.md) \| [PostgreSQL](../samples/postgres.md) \| [Redis](../samples/redis.md)

## Frameworks

[.NET](../samples/dotnet.md) \| [Angular](../samples/angular.md) \| [Django](../samples/django.md) \| [Express](../samples/express.md) \|[FastAPI](../samples/fastapi.md) \| [Flask](../samples/flask.md) \| [Node.js](../samples/nodejs.md) \| [React](../samples/react.md) \| [Rails](../samples/rails.md) \| [Spark](../samples/spark.md) \| [Spring Boot](../samples/spring.md) \| [Vue.js](../samples/vuejs.md)

## Languages

[Go](../samples/go.md) \| [Java](../samples/java.md) \| [JavaScript](../samples/javascript.md) \| [PHP](../samples/php.md) \| [Python](../samples/python.md) \| [Ruby](../samples/ruby.md) \| [Rust](../samples/rust.md) \| [TypeScript](../samples/typescript.md)

## Platforms

[Gitea](../samples/gitea.md) \| [Nextcloud](../samples/nextcloud.md) \| [Portainer](../samples/portainer.md) \|  [Prometheus](../samples/prometheus.md) \| [WordPress](../samples/wordpress.md)

## Other samples

[Agentic AI](../samples/agentic-ai.md) \| [AI/ML](../samples/ai-ml.md) \| [Cloudflared](../samples/cloudflared.md) \| [Elasticsearch / Logstash / Kibana](../samples/elasticsearch.md) \| [Minecraft](../samples/minecraft.md) \| [NGINX](../samples/nginx.md) \| [Pi-hole](../samples/pi-hole.md) \| [Plex](../samples/plex.md) \| [Traefik](../samples/traefik.md) \| [WireGuard](../samples/wireguard.md)

---

### Get Started Docker Concepts Building Images  Index (`content/get-started/docker-concepts/building-images/_index.md`)

---
title: Building images
weight: 20
keywords: build images, Dockerfile, layers, tag, push, cache, multi-stage
description: |
  Learn how to build Docker images from a Dockerfile. You'll understand the
  structure of a Dockerfile, how to build an image, and how to customize the
  build process.
summary: |
  Building container images is both technical and an art. You want to keep the
  image small and focused to increase your security posture, but also need to
  balance potential tradeoffs, such as caching impacts. In this series, you’ll
  deep dive into the secrets of images, how they are built and best practices.
layout: series
params:
  proficiencyLevel: Beginner
  time: 25 minutes
  prerequisites: None
---

## About this series

Learn how to build production-ready images that are lean and efficient Docker
images, essential for minimizing overhead and enhancing deployment in
production environments.

## What you'll learn

- Understanding image layers
- Writing a Dockerfile
- Build, tag and publish an image
- Using the build cache
- Multi-stage builds

---

### Get Started Docker Concepts Running Containers  Index (`content/get-started/docker-concepts/running-containers/_index.md`)

---
build:
  render: never
title: Running containers
weight: 30
---

---

### Get Started Docker Concepts The Basics  Index (`content/get-started/docker-concepts/the-basics/_index.md`)

---
build:
  render: never
title: The basics
weight: 10
---

---

### Manuals Accounts Company  Index (`content/manuals/accounts/company/_index.md`)

---
title: Company accounts
linkTitle: Company
weight: 20
description: Why a Docker company groups organizations, and what company
  owners administer.
keywords: company, multiple organizations, Docker Home, Docker Business,
  company owners, SSO, SCIM
grid:
  - title: Create a company
    description: Get started by learning how to create a company.
    icon: building-office-2
    link: /accounts/company/new-company/
  - title: Manage your company
    description: Add organizations, manage company owners, and invite members.
    icon: building-storefront
    link: /accounts/company/manage/
  - title: Configure SSO and SCIM
    description: Set up single sign-on and SCIM provisioning for your company.
    icon: key
    link: /security/authentication/single-sign-on/
  - title: Domain management
    description: Add and verify your company's domains.
    icon: check-badge
    link: /security/provisioning/domain-management/
  - title: FAQs
    description: Explore frequently asked questions about companies.
    link: /faqs/accounts/
    icon: question-mark-circle
aliases:
  - /admin/company/
  - /docker-hub/creating-companies/
---

{{< summary-bar feature_name="Company" >}}

A company is where you configure sign-in and administration for multiple
Docker organizations.

> [!TIP]
>
> Organization owners with a Docker Business subscription can
> [create a company](./new-company.md) in
> [Docker Home](https://app.docker.com/).

## Company structure

A company sits above its organizations, giving company owners full
administrative access across every organization in the company.

The following diagram shows that hierarchy:

```mermaid {title="Company structure" caption="Company owners manage a company that contains one or more organizations."}
flowchart TB
  co(("Company owners")) -.->|"manage"| C
  subgraph C["Company"]
    direction TB
    subgraph O1["Organization A"]
      direction TB
      m1(("Members"))
      r1[("Repositories")]
    end
    subgraph O2["Organization B"]
      direction TB
      m2(("Members"))
      r2[("Repositories")]
    end
    O1 ~~~ O2
  end
  style C fill:#3b82f622,stroke:#3b82f6
```

## What a company lets you do

When you create a company, you can:

- Administer every organization in the company from one place.
- Configure single sign-on (SSO) and System for Cross-domain Identity
  Management (SCIM) once for every organization in the company.
- Verify your domains once at the company level instead of in each
  organization. When you turn on auto-provisioning for a domain, you
  choose which organization new users join.
- View members and invitations from every organization in one list, and
  export that list as a CSV.

You can assign up to 10 company owners. Company owners occupy a purchased
seat only when they are also members of an organization. A company owner
who is not an organization member does not occupy a seat.

## Next steps

Learn how to create and manage a company in the following sections.

{{< grid >}}

---

### Manuals Accounts Individual  Index (`content/manuals/accounts/individual/_index.md`)

---
title: Docker individual accounts
linkTitle: Individual
description: >
  Learn what a Docker account is, how Docker IDs, emails, and sign-in methods
  relate, and how individual accounts connect to organizations
keywords: accounts, docker ID, username, email, Google, GitHub, sign-in,
  authentication, account management, docker account, individual account,
  organization account, account types, Docker Hub, SSO, deactivate account
weight: 10
grid:
  - title: Set up your account
    description: Get started with Docker and create an account.
    icon: finger-print
    link: /accounts/individual/create-account/
  - title: Manage account
    description: Learn how to manage the settings for your account.
    icon: cog
    link: /accounts/individual/manage-account/
  - title: Personal access tokens
    description: Learn how to create and manage access tokens for your account.
    icon: lock-closed
    link: /security/access-tokens/
  - title: Set up two-factor authentication
    description: Add an extra layer of authentication to your Docker account.
    link: /security/authentication/2fa/manage/
    icon: device-phone-mobile
  - title: Organization accounts
    description: Learn how to create and manage Docker organizations.
    icon: building-storefront
    link: /accounts/organization/
  - title: Account FAQs
    description: Explore frequently asked questions about Docker accounts.
    icon: question-mark-circle
    link: /faqs/accounts/
---

A Docker account is how Docker identifies you. Use it to access products like
Docker Hub and Docker Desktop, manage settings, and join organizations.

For how individual, organization, and company accounts compare, see
[Accounts](/manuals/accounts/_index.md). For organization accounts, including
companies, see
[Organization accounts](/manuals/accounts/organization/_index.md).

## Docker ID, email, and sign-in

When you create an account, you choose a Docker ID and a sign-in method.
Docker also ties a verified email to the account.

- Docker account: Associates your plans, Hub repositories, and account
  settings.
- Docker ID: A unique username that identifies you.
- Email: How Docker contacts you for notifications and security-related
  communications.
- Sign-in method: Email and password,
  [single sign-on (SSO)](/manuals/security/authentication/single-sign-on/_index.md),
  Google, or GitHub.

## Next steps

{{< grid >}}

---

### Manuals Accounts Organization  Index (`content/manuals/accounts/organization/_index.md`)

---
title: Organization accounts
linkTitle: Organization
description: How Docker organizations relate to members, teams, and
  repositories.
keywords: admin, organization, Docker Home, user accounts, account management,
  roles, members, permissions, organization settings, owners, teams,
  repositories
weight: 15
grid:
  - title: Set up your organization
    description: Create, onboard, and configure your organization.
    icon: magnifying-glass-plus
    link: /accounts/organization/setup/
  - title: Manage your organization
    description: Manage members, teams, seats, and product access.
    icon: user-plus
    link: /accounts/organization/manage/
  - title: Activity logs
    description: Review member activity across your organization and
      repositories.
    icon: clipboard-document-list
    link: /accounts/organization/activity-logs/
  - title: Insights
    description: See how people in your organization use Docker.
    icon: chart-bar
    link: /accounts/organization/insights/
  - title: Security
    description: Explore security features for administrators.
    icon: shield-check
    link: /security/
aliases:
  - /admin/
  - /docker-hub/admin-overview
  - /admin/organization/
  - /accounts/organization/overview/
---

A Docker organization is a shared workspace for members and repositories
under one namespace.
Organization owners administer membership, access, and security.

## Organization structure

Organization owners manage organizations that contain members,
repositories, and teams, which group members within an
organization.

The following diagram shows that hierarchy:

```mermaid {title="Organization structure" caption="Organization owners manage an organization that contains members, repositories, and optional teams."}
flowchart TB
  oo(("Organization owners")) -.->|"manage"| org
  subgraph org["Organization"]
    direction TB
    m(("Members"))
    subgraph t["Teams (optional)"]
      tm(("Members"))
    end
    r[("Repositories")]
  end
  style org fill:#3b82f622,stroke:#3b82f6
  style t stroke-dasharray: 5 5
```

### Owners

Organization owners administer the organization. They invite members, assign
roles, and manage teams and repositories.

An organization can have multiple owners. All owners share the same
predefined permissions. For other roles and their permissions, see
[Roles and permissions](/manuals/security/roles-and-permissions/_index.md).

### Members

A member is a Docker user invited to the organization. Organization owners
assign a role to each member, and that role sets organization-wide access.

### Teams

Teams are optional. They group members so you can grant repository
access to many people at once. Use a team when several members need the
same repositories. Members can belong to the organization without joining
a team.

## Next steps

Learn how to manage organizations in the following sections.

{{< grid >}}

---

### Manuals Ai Docker Agent  Index (`content/manuals/ai/docker-agent/_index.md`)

---
title: Docker Agent
description: Docker Agent lets you build, orchestrate, and share AI agents that work together as a team.
weight: 60
aliases:
  - /ai/cagent/
  - /manuals/ai/cagent/
  - /ai/docker-agent/integrations/
  - /ai/docker-agent/reference/
  - /ai/docker-agent/reference/examples/
params:
  sidebar:
    group: AI and agents
keywords: [ai, agent, docker agent, cagent]
---

[Docker Agent](https://github.com/docker/docker-agent) is an open-source framework
for building teams of specialized AI agents. Instead of prompting one
generalist model, you define agents with specific roles and instructions that
collaborate to solve problems. Run these agent teams from your terminal using
any LLM provider.

> [!NOTE]
> Docker Agent is a framework for building and running custom agent teams.
> For Docker's built-in AI assistant, see [Gordon](/ai/gordon/) (`docker ai`).

## Why agent teams

One agent handling complex work means constant context-switching. Split the work
across focused agents instead - each handles what it's best at. Docker Agent manages
the coordination.

Here's a two-agent team that debugs problems:

```yaml
agents:
  root:
    model: openai/gpt-5-mini # Change to the model that you want to use
    description: Bug investigator
    instruction: |
      Analyze error messages, stack traces, and code to find bug root causes.
      Explain what's wrong and why it's happening.
      Delegate fix implementation to the fixer agent.
    sub_agents: [fixer]
    toolsets:
      - type: filesystem
      - type: mcp
        ref: docker:duckduckgo

  fixer:
    model: anthropic/claude-sonnet-4-5 # Change to the model that you want to use
    description: Fix implementer
    instruction: |
      Write fixes for bugs diagnosed by the investigator.
      Make minimal, targeted changes and add tests to prevent regression.
    toolsets:
      - type: filesystem
      - type: shell
```

The root agent investigates and explains the problem. When it understands the
issue, it hands off to `fixer` for implementation. Each agent stays focused on
its specialty.

## Installation

Docker Agent is included in Docker Desktop 4.63 and later. In Docker Desktop versions 4.49 through 4.62, this feature was called cagent.

For Docker Engine users or custom installations:

- **Homebrew**: `brew install docker-agent`
- **Winget**: `winget install Docker.Agent`
- **Pre-built binaries**: [GitHub
  releases](https://github.com/docker/docker-agent/releases)
- **From source**: See the [Docker Agent
  repository](https://github.com/docker/docker-agent?tab=readme-ov-file#build-from-source)

The `docker-agent` binary should be copied to `~/.docker/cli-plugins` and then can be used with the `docker agent` command. Alternatively, it can be used as a standalone binary.

## Get started

Try the bug analyzer team:

1. Set your API key for the model provider you want to use:

   ```console
   $ export ANTHROPIC_API_KEY=<your_key>  # For Claude models
   $ export OPENAI_API_KEY=<your_key>     # For OpenAI models
   $ export GOOGLE_API_KEY=<your_key>     # For Gemini models
   ```

2. Save the [example configuration](#why-agent-teams) as `debugger.yaml`.

3. Run your agent team:

   ```console
   $ docker agent run debugger.yaml
   ```

You'll see a prompt where you can describe bugs or paste error messages. The
investigator analyzes the problem, then hands off to the fixer for
implementation.

## How it works

You interact with the _root agent_, which can delegate work to sub-agents you
define. Each agent:

- Uses its own model and parameters
- Has its own context (agents don't share knowledge)
- Can access built-in tools like todo lists, memory, and task delegation
- Can use external tools via [MCP
  servers](/manuals/desktop/features/mcp-catalog-and-toolkit/mcp-gateway.md)

The root agent delegates tasks to agents listed under `sub_agents`. Sub-agents
can have their own sub-agents for deeper hierarchies.

## Configuration options

Agent configurations are YAML files. A basic structure looks like this:

```yaml
agents:
  root:
    model: claude-sonnet-4-0
    description: Brief role summary
    instruction: |
      Detailed instructions for this agent...
    sub_agents: [helper]

  helper:
    model: gpt-5-mini
    description: Specialist agent role
    instruction: |
      Instructions for the helper agent...
```

You can also configure model settings (like context limits), tools (including
MCP servers), and more. See the [configuration
reference](./configuration/overview/index.md)
for complete details.

## Share agent teams

Agent configurations are packaged as OCI artifacts. Push and pull them like
container images:

```console
$ docker agent share push ./debugger.yaml myusername/debugger
$ docker agent share pull myusername/debugger
```

Use Docker Hub or any OCI-compatible registry. Pushing creates the repository if
it doesn't exist yet.

## What's next

- Follow the [quickstart](./getting-started/quickstart/index.md) to build your first agent
- Learn [best practices](./guides/tips/index.md) for building effective agents
- Integrate Docker Agent with your [editor](./features/acp/index.md) or use agents as
  [tools in MCP clients](./tools/mcp/index.md)
- Browse example agent configurations in the [Docker Agent
  repository](https://github.com/docker/docker-agent/tree/main/examples)
- Connect agents to external tools via the [Docker MCP
  Gateway](/manuals/desktop/features/mcp-catalog-and-toolkit/mcp-gateway.md)
- Read the full [configuration reference](./configuration/overview/index.md)

---

### Manuals Ai Gordon  Index (`content/manuals/ai/gordon/_index.md`)

---
title: Gordon
description:
  AI assistant for Docker workflows - execute tasks, debug issues, and
  manage containers with intelligent assistance
weight: 40
params:
  sidebar:
    group: AI and agents
aliases:
  - /desktop/features/gordon/
---

{{< summary-bar feature_name="Gordon" >}}

Gordon is an AI-powered assistant that takes action on your Docker workflows.
It analyzes your environment, proposes solutions, and executes commands with
your permission.

## What Gordon does

Gordon takes action to help you with Docker tasks:

- Explains Docker concepts and commands
- Searches Docker documentation and web resources for solutions
- Writes and modifies Dockerfiles following best practices
- Debugs container failures by reading logs and proposing fixes
- Manages containers, images, volumes, and networks

Gordon proposes every action before executing. You approve what it does.

## Where to use Gordon

Gordon is available on four surfaces:

- Open the Gordon view from the Docker Desktop sidebar to run Docker commands
  with your approval. See [Using Gordon in Docker
  Desktop](./how-to/docker-desktop.md).
- Run `docker ai` in the terminal to use the full assistant from the command
  line. See [Using Gordon via CLI](./how-to/cli.md).
- Select the Gordon icon on any repository page at
  [hub.docker.com](https://hub.docker.com) to ask about a repository's
  images, tags, and metadata. Hand off to Docker Desktop to take action.
- Select the Gordon icon on any page at
  [docs.docker.com](https://docs.docker.com) to ask Docker questions.

Docker Desktop and the CLI count against your Gordon plan's [usage
limits](./usage-limits.md). Gordon on Docker Hub and docs.docker.com is free
and does not require a Docker account or a Docker Desktop install. It has
its own shared public usage limit and does not access your Docker
environment.

## Get started

### Prerequisites

Before you begin:

- Docker Desktop 4.74 or later
- Sign in to your Docker account

> [!NOTE]
> Gordon is enabled by default for signed-in Docker users. If your account
> belongs to an organization with a Business subscription, access requires two
> additional steps:
>
> 1. Contact Docker Support to activate Gordon for your organization. Docker
>    will confirm when activation is complete.
> 2. Once confirmed, an organization administrator must turn on Gordon via
>    [Settings Management](/manuals/desktop/enterprise/hardened-desktop/settings-management/_index.md).
>    Set **Enable Gordon** to **Enabled** or **Always enabled**. Ensure all
>    Settings Management prerequisites are met for the setting to take effect
>    on Docker Desktop clients.

### Quick start

{{< tabs >}}
{{< tab name="Docker Desktop" >}}

1. Open Docker Desktop.
2. Select **Gordon** in the sidebar.
3. Select your project directory.
4. Type a question: "What containers are running?"

   

5. Review Gordon's proposed actions and approve.

{{< /tab >}}
{{< tab name="CLI" >}}

1. Open your terminal and run:

   ```console
   $ docker ai
   ```

   This opens the Terminal User Interface (TUI) for Gordon.

2. Type a question: "what containers are running?" and press <kbd>Enter</kbd>.

   

3. Review Gordon's proposed actions and approve by typing `y`.

{{< /tab >}}
{{< /tabs >}}

### Permissions

By default, Gordon asks for approval before executing actions. You can approve
individual actions or allow all actions for the current session.



Permissions reset for each session. To configure default permissions or enable
auto-approve mode, see [Permissions](./how-to/permissions.md).

### Try these examples

Container inspection:

```console
$ docker ai "show me logs from my nginx container"
```

Dockerfile review:

```console
$ docker ai "review my Dockerfile for best practices"
```

Image management:

```console
$ docker ai "list my local images and their sizes"
```

---

### Manuals Ai Model Runner  Index (`content/manuals/ai/model-runner/_index.md`)

---
title: Docker Model Runner
linkTitle: Model Runner
params:
  sidebar:
    group: AI and agents
weight: 30
description: Learn how to use Docker Model Runner to manage and run AI models.
keywords: Docker, ai, model runner, docker desktop, docker engine, llm, openai, ollama, llama.cpp, vllm, diffusers, cpu, nvidia, cuda, amd, rocm, vulkan, cline, continue, cursor, image generation, stable diffusion
aliases:
  - /desktop/features/model-runner/
  - /model-runner/
---

{{< summary-bar feature_name="Docker Model Runner" >}}

Docker Model Runner (DMR) makes it easy to manage, run, and
deploy AI models using Docker. Designed for developers,
Docker Model Runner streamlines the process of pulling, running, and serving
large language models (LLMs) and other AI models directly from Docker Hub,
any OCI-compliant registry, or [Hugging Face](https://huggingface.co/).

With seamless integration into Docker Desktop and Docker
Engine, you can serve models via OpenAI and Ollama-compatible APIs, package GGUF files as
OCI Artifacts, and interact with models from both the command line and graphical
interface.

Whether you're building generative AI applications, experimenting with machine
learning workflows, or integrating AI into your software development lifecycle,
Docker Model Runner provides a consistent, secure, and efficient way to work
with AI models locally.

## Key features

- [Pull and push models to and from Docker Hub or any OCI-compliant registry](https://hub.docker.com/u/ai)
- [Pull models from Hugging Face](https://huggingface.co/)
- Serve models on [OpenAI and Ollama-compatible APIs](api-reference.md) for easy integration with existing apps
- Support for [llama.cpp, vLLM, and Diffusers inference engines](inference-engines.md) (vLLM and Diffusers on Linux with NVIDIA GPUs)
- [Generate images from text prompts](inference-engines.md#diffusers) using Stable Diffusion models with the Diffusers backend
- Package GGUF and Safetensors files as OCI Artifacts and publish them to any Container Registry
- Run and interact with AI models directly from the command line or from the Docker Desktop GUI
- [Connect to AI coding tools](ide-integrations.md) like Cline, Continue, Cursor, and Aider
- [Configure context size and model parameters](configuration.md) to tune performance
- [Set up Open WebUI](openwebui-integration.md) for a ChatGPT-like web interface
- Manage local models and display logs
- Display prompt and response details
- Conversational context support for multi-turn interactions

## Requirements

Docker Model Runner is supported on the following platforms:

{{< tabs >}}
{{< tab name="Windows">}}

Windows(amd64):
-  NVIDIA GPUs
-  NVIDIA drivers 576.57+

Windows(arm64):
- OpenCL for Adreno
- Qualcomm Adreno GPU (6xx series and later)

  > [!NOTE]
  > Some llama.cpp features might not be fully supported on the 6xx series.

{{< /tab >}}
{{< tab name="MacOS">}}

- Apple Silicon

{{< /tab >}}
{{< tab name="Linux">}}

Docker Engine only:

- Supports CPU, NVIDIA (CUDA), AMD (ROCm), and Vulkan backends
- Requires NVIDIA driver 575.57.08+ when using NVIDIA GPUs

{{< /tab >}}
{{</tabs >}}

## How Docker Model Runner works

Models are pulled from Docker Hub, an OCI-compliant registry, or
[Hugging Face](https://huggingface.co/) the first time you use them and are
stored locally. They load into memory only at runtime when a request is made,
and unload when not in use to optimize resources. Because models can be large,
the initial pull may take some time. After that, they're cached locally for
faster access. You can interact with the model using
[OpenAI and Ollama-compatible APIs](api-reference.md).

### Inference engines

Docker Model Runner supports three inference engines:

| Engine | Best for | Model format |
|--------|----------|--------------|
| [llama.cpp](inference-engines.md#llamacpp) | Local development, resource efficiency | GGUF (quantized) |
| [vLLM](inference-engines.md#vllm) | Production, high throughput | Safetensors |
| [Diffusers](inference-engines.md#diffusers) | Image generation (Stable Diffusion) | Safetensors |

llama.cpp is the default engine and works on all platforms. vLLM requires NVIDIA GPUs and is supported on Linux x86_64 and Windows with WSL2. Diffusers enables image generation and requires NVIDIA GPUs on Linux (x86_64 or ARM64). See [Inference engines](inference-engines.md) for detailed comparison and setup.

### Context size

Models have a configurable context size (context length) that determines how many tokens they can process. The default varies by model but is typically 2,048-8,192 tokens. You can adjust this per-model:

```console
$ docker model configure --context-size 8192 ai/qwen2.5-coder
```

See [Configuration options](configuration.md) for details on context size and other parameters.

> [!TIP]
>
> Using Testcontainers or Docker Compose?
> [Testcontainers for Java](https://java.testcontainers.org/modules/docker_model_runner/)
> and [Go](https://golang.testcontainers.org/modules/dockermodelrunner/), and
> [Docker Compose](/manuals/compose/how-tos/models-and-compose.md) support Docker
> Model Runner.

## Security and isolation

### Execution environment

Docker Model Runner isolates inference engines from your host:

- On Linux, Docker Model Runner and its inference engines, such as Diffusers,
  run inside a container, which provides the isolation boundary.
- On macOS and Windows, the engines don't run inside a container, so Docker
  Model Runner runs them in a sandboxed environment (seatbelt/sandbox-exec and Job Objects respectively)

### Networking

The Model Runner API is not authenticated. Any client that can reach it,
including other containers on the same Docker network, can pull, load, and
run models, and send inference requests.

## Known issues

### `docker model` is not recognised

If you run a Docker Model Runner command and see:

```text
docker: 'model' is not a docker command
```

It means Docker can't find the plugin because it's not in the expected CLI plugins directory.

To fix this, create a symlink so Docker can detect it:

```console
$ ln -s /Applications/Docker.app/Contents/Resources/cli-plugins/docker-model ~/.docker/cli-plugins/docker-model
```

Once linked, rerun the command.

## Privacy and data collection

Docker Model Runner respects your privacy settings in Docker Desktop. Data collection is controlled by the **Send usage statistics** setting:

- **Disabled**: No usage data is collected
- **Enabled**: Only minimal, non-personal data is collected:
  - [Model names](https://github.com/docker/model-runner/blob/eb76b5defb1a598396f99001a500a30bbbb48f01/pkg/metrics/metrics.go#L96) (via HEAD requests to Docker Hub)
  - User agent information
  - Whether requests originate from the host or containers

When using Docker Model Runner with Docker Engine, HEAD requests to Docker Hub are made to track model names, regardless of any settings.

No prompt content, responses, or personally identifiable information is ever collected.

## Share feedback

Thanks for trying out Docker Model Runner. To report bugs or request features, [open an issue on GitHub](https://github.com/docker/model-runner/issues). You can also give feedback through the **Give feedback** link next to the **Enable Docker Model Runner** setting.

## Next steps

- [Get started with DMR](get-started.md) - Enable DMR and run your first model
- [API reference](api-reference.md) - OpenAI and Ollama-compatible API documentation
- [Configuration options](configuration.md) - Context size and runtime parameters
- [Inference engines](inference-engines.md) - llama.cpp, vLLM, and Diffusers details
- [IDE integrations](ide-integrations.md) - Connect Cline, Continue, Cursor, and more
- [Open WebUI integration](openwebui-integration.md) - Set up a web chat interface

---

### Manuals Ai Sandboxes Api  Index (`content/manuals/ai/sandboxes-api/_index.md`)

---
title: Docker Sandboxes API and SDK
linkTitle: Sandboxes API and SDK
description: Use the Docker Sandboxes API and TypeScript SDK to manage cloud sandboxes programmatically.
keywords: docker sandboxes API, cloud sandboxes API, sandbox SDK, TypeScript SDK, JavaScript
weight: 15
params:
  apiReferenceBanner: false
  sidebar:
    group: AI and agents
aliases:
  - /ai/sandboxes/api/
---

Use the Docker Sandboxes API to create cloud sandboxes, run commands, and
transfer files from your applications and automated workflows. You can also
manage related resources, including images, snapshots, volumes, and secrets.

To try it, [run your first cloud sandbox](get-started.md) with the TypeScript
SDK. The tutorial uses a bundled kit that supplies a shell environment for
running commands.

## Activate cloud access

To use the API or SDK, [activate a Docker Agentic Platform subscription](/manuals/agentic-platform/signup.md#activate-cloud-access).
Use the same Docker account to [authenticate your application](authentication.md).

Cloud compute is billed separately from your Docker subscription. See
[Billing](/manuals/agentic-platform/signup.md#billing) for details.

## Choose an interface

Use the TypeScript SDK in your JavaScript or TypeScript application. The SDK
provides typed requests and responses, waits for sandboxes to start or stop,
and handles file transfers and interactive processes.
See [Install the SDK](install.md) for installation instructions.

You can also call the REST API directly from any language or HTTP tool.
See the [API reference](/reference/api/sandboxes/latest/) for operations,
request fields, responses, and the downloadable OpenAPI specification.

To run agents from your terminal, see [Docker Sandboxes](../sandboxes/_index.md).

## Develop your application

- [SDK cookbook](cookbook/_index.md): follow examples for processes, files,
  storage, networking, and other sandbox operations.
- [API concepts](concepts.md): choose a kit or image, identify resources, and
  wait for actions to finish.
- [Authentication and authorization](authentication.md): authenticate requests
  and understand which permissions your application needs.
- [Errors and retries](errors.md): handle failures and retry requests without
  duplicating work.
- [Compute sizes and limits](limits.md): choose resources and handle account
  quotas and request rate limits.

---

### Manuals Ai Sandboxes  Index (`content/manuals/ai/sandboxes/_index.md`)

---
title: Docker Sandboxes
description: Run AI coding agents in isolated environments
keywords: docker sandboxes, sbx, ai agents, sandboxed agents, microVM
weight: 10
params:
  sidebar:
    group: AI and agents
---

Docker Sandboxes run AI coding agents in isolated environments on your machine
or on Docker-managed cloud infrastructure. Use the `sbx` CLI to create and
manage either kind of sandbox.

The `sbx` CLI and local sandbox compute are free to use, including for commercial
work. Cloud compute uses a
[pay-as-you-go subscription](/manuals/agentic-platform/signup.md#billing).
Model-provider charges are separate.

Organization admins can
[centrally manage sandbox network, filesystem, and MCP policies](governance/access-controls/organization.md),
for local sandboxes across developer machines.
Available on a separate paid subscription.

## Get started

[Install the `sbx` CLI](install.md) and sign in, then choose where to run your
agent:

| Environment | Use it for | Start here |
| --- | --- | --- |
| Local sandboxes | Work with files and supported hardware on your machine | [Get started locally](get-started.md) |
| Cloud sandboxes | Run on Docker-managed compute without local virtualization | [Get started in the cloud](cloud/_index.md#get-started) |

The two environments have separate credentials, network policies, and lifecycle
controls. See [Compare local and cloud sandboxes](cloud/local-vs-cloud.md)
before adapting a workflow.

To create and manage cloud sandboxes from your application, see
[Sandboxes API and SDK](../sandboxes-api/_index.md).

## Learn more

The following guides describe local sandbox workflows. For cloud workflows,
see [Cloud sandboxes](cloud/).

- [Agents](agents/) — supported agents and per-agent configuration
- [Workflows](workflows/) — patterns for Git, local development,
  authentication, agent skills, and automation
- [Configuration](configuration/) — manage credentials, declare project
  environments, turn on GPU passthrough, and configure an upstream proxy
- [Integrations](integrations/) — connect editors and apps like VS Code and
  Cursor to a sandbox over SSH
- [MCP gateway](mcp-gateway.md) — register MCP servers and connect them to
  sandboxed agents
- [Kits](customize/) — package tools and configuration into reusable
  sandbox environments
- [Architecture](architecture.md) — microVM isolation, workspace mounting,
  networking
- [Security](security/) — isolation model, credential handling, and
  network policies
- [CLI reference](/reference/cli/sbx/) — full list of `sbx` commands and options
- [Troubleshooting](troubleshooting.md) — common issues and fixes
- [FAQ](faq.md) — login requirements, telemetry, etc

## Feedback

Your feedback shapes what gets built next. If you run into a bug, hit a
missing feature, or have a suggestion, open an issue at
[github.com/docker/sbx-releases/issues](https://github.com/docker/sbx-releases/issues).

---

### Manuals Ai Skills  Index (`content/manuals/ai/skills/_index.md`)

---
title: Docker Skills
description: Use Docker's official skills to give compatible AI coding agents guidance for Docker tasks.
keywords: [docker skills, agent skills, ai coding agents, dockerfile, compose]
weight: 70
params:
  sidebar:
    group: AI and agents
---

Docker Skills are Docker's official, open-source guidance for compatible AI
coding agents. They help agents with Docker tasks, such as improving a Dockerfile
or setting up a Compose application. The collection evolves and doesn't cover
every Docker product. Browse the [repository catalog](https://github.com/docker/skills#readme)
for available skills and their descriptions.

## Get started

1. [Install Docker Skills](install.md) with a method supported by your agent,
   and start a new agent session.
2. Ask for an outcome in plain language, for example, “Make this Dockerfile
   smaller and run as a non-root user.”
3. Review the proposed changes and commands, run your project's tests, and
   confirm destructive operations before approving them. Skills guide the
   agent; they don't replace validation.

## How agents use skills

A compatible agent matches your request to descriptions of skills it can
access, then loads the relevant instructions. You don't need to name a skill in
your prompt. A skill is a directory containing a `SKILL.md` file that describes
when and how to use it, with optional references or assets. An agent can use
more than one skill when a task spans Docker products.

---

### Manuals Compose Bridge  Index (`content/manuals/compose/bridge/_index.md`)

---
description: Learn how Compose Bridge transforms Docker Compose files into Kubernetes manifests for seamless platform transitions
keywords: docker compose bridge, compose to kubernetes, docker compose kubernetes integration, docker compose kustomize, compose bridge docker desktop
title: Overview of Compose Bridge
linkTitle: Compose Bridge
weight: 50
---

{{< summary-bar feature_name="Compose bridge" >}}

Compose Bridge converts your Docker Compose configuration into platform-specific deployment formats such as Kubernetes manifests. By default, it generates:

- Kubernetes manifests 
- A Kustomize overlay

These outputs are ready for deployment on Docker Desktop with [Kubernetes enabled](/manuals/desktop/settings-and-maintenance/settings.md#kubernetes).  

Compose Bridge helps you bridge the gap between Compose and Kubernetes, making it easier to adopt Kubernetes while keeping the simplicity and efficiency of Compose.

It's a flexible tool that lets you either take advantage of the [default transformation](usage.md) or [create a custom transformation](customize.md) to suit specific project needs and requirements. 

## How it works

Compose Bridge uses transformations to convert a Compose model into another form. 

A transformation is packaged as a Docker image that receives the fully resolved Compose model as `/in/compose.yaml` and can produce any target format file under `/out`.

Compose Bridge provides its own transformation for Kubernetes using Go templates, so that it is easy to extend for customization by replacing or appending your own templates.

For more detailed information on how these transformations work and how you can customize them for your projects, see [Customize](customize.md).

Compose Bridge also supports applications that use LLMs via Docker Model Runner.

For more details, see [Use Model Runner](use-model-runner.md).

## Apply organizational standards at scale 


Compose Bridge supports custom transformation templates, which lets platform teams encode
organizational standards once and apply them consistently whenever a `compose.yaml` file
is converted to Kubernetes manifests or other formats.

Developers continue to write standard Compose files. During conversion, Compose Bridge
runs your custom transformation and automatically injects the required security contexts,
resource limits, labels, and network policies into the output manifests — without
requiring developers to know or manage those details.

When your requirements change, update the transformation template in one place. Every team
picks up the changes on their next conversion, with no edits to individual Compose files.

This separation of concerns keeps developers focused on application configuration, while
platform teams control governance and enforce policy through the transformation layer.

To get started, see [Customize Compose Bridge](/manuals/compose/bridge/customize.md).

## What's next?

- [Use Compose Bridge](usage.md)
- [Explore how you can customize Compose Bridge](customize.md)

---

### Manuals Compose How Tos  Index (`content/manuals/compose/how-tos/_index.md`)

---
build:
  render: never
title: How-tos
weight: 40
---

---

### Manuals Compose Install  Index (`content/manuals/compose/install/_index.md`)

---
description: Learn how to install Docker Compose. Compose is available natively on
  Docker Desktop, as a Docker Engine plugin, and as a standalone tool.
keywords: install docker compose, docker compose plugin, install compose linux, install docker desktop, docker compose windows, standalone docker compose, docker compose not found
title: Overview of installing Docker Compose
linkTitle: Install
weight: 20
toc_max: 3
---

This page summarizes the different ways you can install Docker Compose, depending on your platform and needs.

## Installation scenarios 

### Docker Desktop (Recommended)

The easiest and recommended way to get Docker Compose is to install Docker Desktop. 

Docker Desktop includes Docker Compose along with Docker Engine and Docker CLI which are Compose prerequisites. 

Docker Desktop is available for:
- [Linux](/manuals/desktop/setup/install/linux/_index.md)
- [Mac](/manuals/desktop/setup/install/mac-install.md)
- [Windows](/manuals/desktop/setup/install/windows-install.md)

> [!TIP]
> 
> If you have already installed Docker Desktop, you can check which version of Compose you have by selecting **About Docker Desktop** from the Docker menu {{< inline-image src="../../desktop/images/whale-x.svg" alt="whale menu" >}}.

### Plugin (Linux only)

> [!IMPORTANT]
>
> This method is only available on Linux.

If you already have Docker Engine and Docker CLI installed, you can install the Docker Compose plugin from the command line, by either:
- [Using Docker's repository](linux.md#install-using-the-repository)
- [Downloading and installing manually](linux.md#install-the-plugin-manually)

### Standalone (Legacy)

> [!WARNING]
>
> This install scenario is not recommended and is only supported for backward compatibility purposes.

You can [install the Docker Compose standalone](standalone.md) on Linux or on Windows Server.

---

### Manuals Compose Intro  Index (`content/manuals/compose/intro/_index.md`)

---
build:
  render: never
title: Introduction to Compose
weight: 10
---

---

### Manuals Compose Support And Feedback  Index (`content/manuals/compose/support-and-feedback/_index.md`)

---
build:
  render: never
title: Support and feedback
weight: 80
---

---

### Manuals Desktop Enterprise  Index (`content/manuals/desktop/enterprise/_index.md`)

---
build:
  render: never
title: Enterprise
weight: 230
---

---

### Manuals Desktop Features  Index (`content/manuals/desktop/features/_index.md`)

---
build:
  render: never
title: Features and capabilities
weight: 30
---

---

### Manuals Desktop Previous Versions  Index (`content/manuals/desktop/previous-versions/_index.md`)

---
build:
  render: never
title: Previous releases
weight: 200
sitemap: false
---

---

### Manuals Desktop Settings And Maintenance  Index (`content/manuals/desktop/settings-and-maintenance/_index.md`)

---
build:
  render: never
title: Settings and maintenance
weight: 40
---

---

### Manuals Desktop Setup  Index (`content/manuals/desktop/setup/_index.md`)

---
build:
  render: never
title: Setup
weight: 10
---

---

### Manuals Desktop Troubleshoot And Support  Index (`content/manuals/desktop/troubleshoot-and-support/_index.md`)

---
build:
  render: never
title: Troubleshoot and support
weight: 50
---

---

### Manuals Desktop Use Desktop  Index (`content/manuals/desktop/use-desktop/_index.md`)

---
description: Learn how to use the Docker Desktop Dashboard within Docker Desktop, including Quick search, the Docker menu, and more
keywords: Docker Desktop Dashboard, manage, containers, gui, dashboard, images, user manual,
  whale menu
title: Explore Docker Desktop
weight: 30
aliases:
- /desktop/dashboard/
---

When you open Docker Desktop, the Docker Desktop Dashboard is the first thing you see. 

It provides a centralized interface to manage your [containers](container.md), [images](images.md), [volumes](volumes.md), [builds](builds.md), [Kubernetes resources](kubernetes.md), and [logs](logs.md).

The Dashboard also gives you quick access to AI tooling, extensions, settings, and help, so you rarely need to leave Docker Desktop. Use Quick search in the header any time to jump straight to a container, image, extension, volume, or doc.

> [!TIP]
>
> You can customize the left-hand navigation to show only the tabs that matter to you, and hide the ones that don’t. Right-click the left-hand navigation, select **Customize**, and then select, deselect, or re-order the tabs.

## Sign in

Docker recommends signing in with the **Sign in** option in the top-right corner of the Dashboard. Signing in lets you:

- Access your Docker Hub repositories directly from Docker Desktop.
- Increase your pull rate limit compared to anonymous users. See [Usage and limits](/manuals/docker-hub/usage/_index.md).
- Enhance your organization's security posture for containerized development with [Hardened Desktop](/manuals/desktop/enterprise/hardened-desktop/_index.md).

Docker Desktop automatically signs you out after 90 days, or after 30 days of inactivity.

In large enterprises where admin access is restricted, administrators can [enforce sign-in](/manuals/desktop/enterprise/enforce-sign-in/_index.md).

> [!TIP]
>
> Explore [Docker's core subscriptions](https://www.docker.com/pricing?ref=Docs&refAction=DocsDesktopSignIn) to see what else Docker can offer you.

## Use AI features

- [Gordon](/manuals/ai/gordon/_index.md): A personal AI assistant built into Docker Desktop and the Docker CLI, designed to streamline your workflow and help you get more out of the Docker ecosystem.
- [Docker Model Runner](/manuals/ai/model-runner/_index.md): Manage, run, and deploy AI models using Docker.
- [Docker MCP Toolkit](/manuals/desktop/features/mcp-catalog-and-toolkit/_index.md): A management interface integrated into Docker Desktop that lets you set up, manage, and run containerized MCP servers in profiles and connect them to AI agents.

### Extend Docker Desktop

- [Docker Offload](/manuals/offload/_index.md): Run builds and containers in the cloud when local resources aren't enough.
- [Docker Hub](/manuals/docker-hub/_index.md): Search, browse, pull, run, or view details for images.
- [Docker Extensions](/manuals/extensions/_index.md): Add third-party tools directly into Docker Desktop.

### Configure, troubleshoot, and stay updated

- **Settings**: Select the Settings icon in the Dashboard header to configure Docker Desktop.
- **Troubleshoot**: Select the Troubleshoot icon in the Dashboard header to debug issues or restart Docker Desktop.
- **Notifications center**: Select the bell icon in the bottom-right corner to see new releases, installation progress, and other updates.
- Learning center: Open it from the Dashboard header for in-app walkthroughs and other learning resources.

---

### Manuals Dhi Explore  Index (`content/manuals/dhi/explore/_index.md`)

---
linktitle: Explore
title: Explore Docker Hardened Images
description: Learn about Docker Hardened Images, their purpose, how they are built and tested, and the shared responsibility model for security.
weight: 10
params:
  grid_about:
    - title: What are hardened images and why use them?
      description: Learn what a hardened image is, how Docker Hardened Images are built, what sets them apart from typical base and application images, and why you should use them.
      icon: information-circle
      link: /dhi/explore/what/
    - title: Build process
      description: Learn how Docker builds, tests, and maintains Docker Hardened Images through an automated, security-focused pipeline.
      icon: wrench-screwdriver
      link: /dhi/explore/build-process/
    - title: Image types
      description: Learn about the different image types, distributions, and variants offered in the Docker Hardened Images catalog.
      icon: squares-2x2
      link: /dhi/explore/available/
    - title: Scanner integrations
      description: Discover which vulnerability scanners integrate with Docker Hardened Images and support open standards like OpenVEX.
      icon: shield-check
      link: /dhi/explore/scanner-integrations/
    - title: Image testing
      description: See how Docker Hardened Images are automatically tested for standards compliance, functionality, and security.
      icon: beaker
      link: /dhi/explore/test/
    - title: Malware scanning
      description: Learn how Docker scans Docker Hardened Images for viruses and malware, and how to view and verify the scan attestation.
      icon: bug-ant
      link: /dhi/explore/malware-scanning/
    - title: Responsibility overview
      description: Understand Docker's role and your responsibilities when using Docker Hardened Images as part of your secure software supply chain.
      icon: user-group
      link: /dhi/explore/responsibility/
    - title: EU data residency
      description: Learn how Docker stores your mirrored and customized images in the EU when your subscription is in the EU region.
      icon: globe-alt
      link: /dhi/explore/eu-region/
    - title: Security concepts
      description: Learn the core concepts behind Docker Hardened Images — signed attestations, immutable digests, SLSA, VEX, and more.
      icon: clipboard-document-check
      link: /dhi/explore/security-concepts/

aliases:
  - /dhi/about/
---

Docker Hardened Images (DHI) are minimal, secure, and production-ready container
base and application images maintained by Docker. Designed to reduce
vulnerabilities and simplify compliance, DHI integrates easily into your
existing Docker-based workflows with little to no retooling required.

This section helps you understand what Docker Hardened Images are, how they're
built and tested, the different types available, and how responsibility is
shared between Docker and you as a user.

## Learn more about Docker Hardened Images

{{< grid
  items="grid_about"
>}}

---

### Manuals Dhi How To  Index (`content/manuals/dhi/how-to/_index.md`)

---
title: How-tos
description: Step-by-step guidance for working with Docker Hardened Images, from discovery to governance.
weight: 20
aliases:
  - /dhi/how-to/manage/
params:
  grid_discover:
    - title: Search and evaluate Docker Hardened Images
      description: Learn how to find and compare image repositories, variants, and metadata in the DHI catalog.
      icon: globe-alt
      link: /dhi/how-to/search-evaluate/
  grid_adopt:
    - title: Get started with DHI Select and Enterprise
      description: Learn how to mirror repositories, customize images, and access compliance variants with DHI Select and Enterprise subscriptions.
      icon: rocket-launch
      link: /dhi/how-to/select-enterprise/
    - title: Mirror a Docker Hardened Image repository
      description: Learn how to mirror an image into your organization's namespace and optionally push it to another private registry.
      icon: arrows-right-left
      link: /dhi/how-to/mirror/
    - title: Customize a Docker Hardened Image or chart
      description: Learn how to customize Docker Hardened Images and charts.
      icon: cog-6-tooth
      link: /dhi/how-to/customize/
    - title: Use hardened system packages
      description: Learn how to use Docker's hardened system packages in your images.
      icon: archive-box
      link: /dhi/how-to/hardened-packages/
    - title: Use a Docker Hardened Image
      description: Learn how to pull, run, and reference Docker Hardened Images in Dockerfiles, CI pipelines, and standard development workflows.
      icon: play
      link: /dhi/how-to/use/
    - title: Use a Docker Hardened Image chart
      description: Learn how to use a Docker Hardened Image chart.
      icon: chart-bar
      link: /dhi/how-to/helm/
  grid_verify:
    - title: Verify a Docker Hardened Image or chart
      description: Use Docker Scout or cosign to verify signed attestations like SBOMs, provenance, and vulnerability data for Docker Hardened Images and charts.
      icon: check-circle
      link: /dhi/how-to/verify/
    - title: Scan Docker Hardened Images
      description: Learn how to scan Docker Hardened Images for known vulnerabilities using Docker Scout, Grype, or Trivy.
      icon: bug-ant
      link: /dhi/how-to/scan/
    - title: Query VEX for a Docker Hardened Image
      description: Use the DHI GraphQL API to fetch VEX statements and suppressed CVEs for a Docker Hardened Image by digest, at scale.
      icon: bug-ant
      link: /dhi/how-to/vex-api/
  grid_govern:
    - title: Apply Docker Hardened Image policies to your images
      description: Learn how to hold your own images to Docker Hardened Image security and compliance standards using the Docker Scout CLI.
      icon: shield-check
      link: /dhi/how-to/policies/
  grid_troubleshoot:
    - title: Troubleshoot
      description: Resolve common issues when building, running, or debugging Docker Hardened Images, such as non-root behavior, missing shells, and port access.
      icon: question-mark-circle
      link: /dhi/how-to/troubleshoot/
---

This section provides practical, task-based guidance for working with Docker
Hardened Images (DHIs). Whether you're evaluating DHIs for the first time or
integrating them into a production CI/CD pipeline, these topics cover the key
tasks across the adoption journey: discover, adopt, verify, and govern.

The topics are organized around the typical lifecycle of working with DHIs, but
you can use them as needed based on your specific workflow.

Explore the topics below that match your current needs.

## Discover

Explore available images and metadata in the DHI catalog.

{{< grid
  items="grid_discover"
>}}

## Adopt

Mirror trusted images, customize as needed, and integrate into your workflows.

{{< grid
  items="grid_adopt"
>}}

## Verify

Check signatures, SBOMs, and provenance, and scan for vulnerabilities.

{{< grid
  items="grid_verify"
>}}

## Govern

Enforce policies to maintain security and compliance.

{{< grid
  items="grid_govern"
>}}

## Troubleshoot

{{< grid
  items="grid_troubleshoot"
>}}

---

### Manuals Dhi Migration  Index (`content/manuals/dhi/migration/_index.md`)

---
title: Migration
description: Learn how to migrate your existing applications to Docker Hardened Images
weight: 18
keywords: migrate, docker hardened images, dhi, migration guide
aliases:
  - /dhi/how-to/migrate/
params:
  grid_migration_paths:
    - title: Migrate with Gordon
      description: Use Gordon to automatically migrate your Dockerfile to Docker Hardened Images with guidance and recommendations.
      icon: sparkles
      link: /dhi/migration/migrate-with-ai/
    - title: Migrate from Alpine or Debian images
      description: Manual migration guide for moving from Docker Official Images (Alpine or Debian-based) to Docker Hardened Images.
      icon: code-bracket
      link: /dhi/migration/migrate-from-doi/
    - title: Migrate from Ubuntu
      description: Manual migration guide for transitioning from Ubuntu-based images to Docker Hardened Images.
      icon: arrow-up-circle
      link: /dhi/migration/migrate-from-ubuntu/
    - title: Migrate from Wolfi
      description: Manual migration guide for transitioning from Wolfi-based images to Docker Hardened Images.
      icon: arrow-path
      link: /dhi/migration/migrate-from-wolfi/
  
  grid_migration_resources:
    - title: Migration checklist
      description: A comprehensive checklist of migration considerations to ensure successful transition to Docker Hardened Images.
      icon: clipboard-document-check
      link: /dhi/migration/checklist/
    - title: Examples
      description: Example Dockerfile migrations for different programming languages and frameworks to guide your migration process.
      icon: eye
      link: /dhi/migration/examples/
---

This section provides guidance for migrating your applications to Docker
Hardened Images (DHI). Migrating to DHI enhances the security posture of your
containerized applications by leveraging hardened base images with built-in
security features.

## Migration paths

Choose the migration approach that best fits your needs:

{{< grid items="grid_migration_paths" >}}

## Resources

{{< grid items="grid_migration_resources" >}}

---

### Manuals Dhi Release Notes  Index (`content/manuals/dhi/release-notes/_index.md`)

---
build:
  render: never
title: Release notes
weight: 999
---

---

### Manuals Dhi Tools  Index (`content/manuals/dhi/tools/_index.md`)

---
title: Tools
description: Interfaces and tools for browsing, managing, and automating Docker Hardened Images.
weight: 25
params:
  grid_tools:
    - title: Use Docker Hub
      description: Browse the DHI catalog on Docker Hub to search repositories, inspect image metadata, and view SBOMs, CVEs, and attestations.
      icon: squares-2x2
      link: /dhi/tools/hub/
    - title: CLI
      description: Install and use the `docker dhi` command-line interface to browse the catalog, inspect images, and manage mirrors from your terminal.
      icon: command-line
      link: /dhi/tools/cli/
    - title: MCP server
      description: Connect an AI assistant to the DHI catalog to search repositories, inspect images, retrieve SBOMs, and check CVEs using plain language.
      icon: cpu-chip
      link: /dhi/tools/mcp/
    - title: Use the DHI Terraform provider
      description: Use the DHI Terraform provider to manage mirrors and automate DHI configuration as infrastructure as code.
      icon: wrench-screwdriver
      link: /dhi/tools/terraform/
    - title: Use the DHI API
      description: Query Docker Hardened Images data programmatically using the DHI GraphQL API.
      icon: code-bracket
      link: /dhi/tools/api/
---

Docker Hardened Images can be accessed and managed through several interfaces.
Choose the tool that fits your workflow.

{{< grid items="grid_tools" >}}

---

### Manuals Docker Hub Image Library  Index (`content/manuals/docker-hub/image-library/_index.md`)

---
description: Learn about Docker Hub's library of images, extensions, and plugins.
keywords: Docker Hub, Hub, content library
title: Content library
linkTitle: Library
weight: 20
---

Docker Hub's content library is the world's largest collection of
container images, extensions, and plugins. It provides a central location to
discover pre-built images and tools designed to streamline your container
workflows, making it easier to share and collaborate.

In this section, learn about:

- [Search](./search.md): Discover how to browse and search Docker Hub's extensive resources.
- [Trusted content](./trusted-content.md): Dive into Docker Hardened Images,
  Docker Official Images, Verified Publisher content, and Docker-Sponsored Open
  Source Software images, all vetted for security and reliability to streamline
  your workflows.
- [Generative AI](./catalogs.md): Explore Docker Hub's generative AI catalogs
  and sandbox kits.
- [Mirroring](./mirror.md): Learn how to create a mirror of Docker Hub's
  container image library as a pull-through cache.

---

### Manuals Docker Hub Repos  Index (`content/manuals/docker-hub/repos/_index.md`)

---
description: Learn how to manage repositories on Docker Hub
keywords: Docker Hub, Hub, repositories
title: Repositories
weight: 20
aliases:
- /engine/tutorials/dockerrepos/
- /docker-hub/repos/configure/
---

A Docker Hub repository is a collection of container images, enabling you to
store, manage, and share Docker images publicly or privately. Each repository
serves as a dedicated space where you can store images associated with a
particular application, microservice, or project. Content in repositories is
organized by tags, which represent different versions of the same application,
allowing users to pull the right version when needed.

In this section, learn how to:

- [Create](./create.md) a repository.
- Manage a repository, including how to manage:

   - [Repository information](./manage/information.md): Add descriptions,
     overviews, and categories to help users understand the purpose and usage of
     your repository. Clear repository information aids discoverability and
     usability.

   - [Access](./manage/access.md): Control who can access your repositories with
     flexible options. Make repositories public or private, add collaborators,
     and, for organizations, manage roles and teams to maintain security and
     control.

   - [Images](./manage/hub-images/_index.md): Repositories support diverse
     content types, including OCI artifacts, and allow version control through
     tagging. Push new images and manage existing content across repositories
     for flexibility.

   - [Image security insights](./manage/vulnerability-scanning.md): Utilize
     continuous Docker Scout analysis and static vulnerability scanning to
     detect, understand, and address security issues within container images.

   - [Webhooks](./manage/webhooks.md): Automate responses to repository events
     like image pushes or updates by setting up webhooks, which can trigger
     notifications or actions in external systems, streamlining workflows.

   - [Automated builds](./manage/builds/_index.md): Integrate with GitHub or
     Bitbucket for automated builds. Every code change triggers an image
     rebuild, supporting continuous integration and delivery.

   - [Trusted content](./manage/trusted-content/_index.md): Contribute to Docker
     Official Images or manage repositories in the Verified Publisher and
     Sponsored Open Source programs, including tasks like setting logos,
     accessing analytics, and enabling vulnerability scanning.

- [Archive](./archive.md) an outdated or unsupported repository.
- [Delete](./delete.md) a repository.

---

### Manuals Docker Hub Usage  Index (`content/manuals/docker-hub/usage/_index.md`)

---
description: Learn about usage and limits for Docker Hub.
keywords: Docker Hub, limit, usage
title: Docker Hub usage and limits
linkTitle: Usage and limits
weight: 30
aliases:
  /docker-hub/download-rate-limit/
---

The following table provides an overview of the included usage and limits for each
user type, subject to fair use:


| User type                | Pull rate limit per 6 hours             | Number of public repositories | Number of private repositories |
|--------------------------|-----------------------------------------|-------------------------------|--------------------------------|
| Business (authenticated) | Unlimited                               | Unlimited                     | Unlimited                      |
| Team (authenticated)     | Unlimited                               | Unlimited                     | Unlimited                      |
| Pro (authenticated)      | Unlimited                               | Unlimited                     | Unlimited                      |
| Personal (authenticated) | 200                                     | Unlimited                     | Up to 1                        |
| Unauthenticated users    | 100 per IPv4 address or IPv6 /64 subnet | Not applicable                | Not applicable                 |

For more details, see [Pull usage and limits](./pulls.md).

## Fair use

When utilizing the Docker Platform, users should be aware that excessive data
transfer, pull rates, or data storage can lead to throttling, or additional
charges. To ensure fair resource usage and maintain service quality, we reserve
the right to impose restrictions or apply additional charges to accounts
exhibiting excessive data and storage consumption.

### Abuse rate limit

Docker Hub has an abuse rate limit to protect the application and
infrastructure. This limit applies to all requests to Hub properties including
web pages, APIs, and image pulls. The limit is applied per IPv4 address or per
IPv6 /64 subnet, and while the limit changes over time depending on load and
other factors, it's in the order of thousands of requests per minute. The abuse
limit applies to all users equally regardless of account level.

You can differentiate between the pull rate limit and abuse rate limit by
looking at the error code. The abuse limit returns a simple `429 Too Many
Requests` response. The pull limit returns a longer error message that includes
a link to documentation.

---

### Manuals Engine Cli  Index (`content/manuals/engine/cli/_index.md`)

---
build:
  render: never
title: CLI
weight: 50
---

---

### Manuals Engine Containers  Index (`content/manuals/engine/containers/_index.md`)

---
title: Containers
build:
  render: never
weight: 40
---

---

### Manuals Engine Daemon  Index (`content/manuals/engine/daemon/_index.md`)

---
description: Configuring the Docker daemon
keywords: docker, daemon, configuration
title: Docker daemon configuration overview
linkTitle: Daemon
weight: 60
aliases:
  - /articles/chef/
  - /articles/configuring/
  - /articles/dsc/
  - /articles/puppet/
  - /config/thirdparty/
  - /config/thirdparty/ansible/
  - /config/thirdparty/chef/
  - /config/thirdparty/dsc/
  - /config/thirdparty/puppet/
  - /engine/admin/
  - /engine/admin/ansible/
  - /engine/admin/chef/
  - /engine/admin/configuring/
  - /engine/admin/dsc/
  - /engine/admin/puppet/
  - /engine/articles/chef/
  - /engine/articles/configuring/
  - /engine/articles/dsc/
  - /engine/articles/puppet/
  - /engine/userguide/
  - /config/daemon/
---

This page shows you how to customize the Docker daemon, `dockerd`.

> [!NOTE]
>
> This page is for users who've installed Docker Engine manually. If you're
> using Docker Desktop, refer to the [settings page](/manuals/desktop/settings-and-maintenance/settings.md#docker-engine).

## Configure the Docker daemon

There are two ways to configure the Docker daemon:

- Use a JSON configuration file. This is the preferred option, since it keeps
  all configurations in a single place.
- Use flags when starting `dockerd`.

You can use both of these options together as long as you don't specify the same
option both as a flag and in the JSON file. If that happens, the Docker daemon
won't start and prints an error message.

### Configuration file

The following table shows the location where the Docker daemon expects to find
the configuration file by default, depending on your system and how you're
running the daemon.

| OS and configuration | File location                              |
| -------------------- | ------------------------------------------ |
| Linux, regular setup | `/etc/docker/daemon.json`                  |
| Linux, rootless mode | `~/.config/docker/daemon.json`             |
| Windows              | `C:\ProgramData\docker\config\daemon.json` |

For rootless mode, the daemon respects the `XDG_CONFIG_HOME` variable. If set,
the expected file location is `$XDG_CONFIG_HOME/docker/daemon.json`.

You can also explicitly specify the location of the configuration file on
startup, using the `dockerd --config-file` flag.

Learn about the available configuration options in the
[dockerd reference docs](/reference/cli/dockerd.md#daemon-configuration-file)

### Configuration using flags

You can also start the Docker daemon manually and configure it using flags.
This can be useful for troubleshooting problems.

Here's an example of how to manually start the Docker daemon, using the same
configurations as shown in the previous JSON configuration:

```console
$ dockerd --debug \
  --tls=true \
  --tlscert=/var/docker/server.pem \
  --tlskey=/var/docker/serverkey.pem \
  --host tcp://192.168.59.3:2376
```

#### Listen on a Unix socket on Windows

Starting with Docker Engine 29.5, you can configure `dockerd` on Windows to
listen on a Unix socket. This setting is optional. The default Windows endpoint
remains the `npipe` named pipe.

Run `dockerd` from an elevated PowerShell session:

```powershell
PS C:\> dockerd -H unix://C:/Users/<USER>/docker.sock --group docker-users
```

Replace `<USER>` with the name of your Windows user profile directory.
Without `--group`, only members of the Administrators group and the `SYSTEM`
account can access the socket. Use a comma-separated list to grant access to
multiple users or groups.

Use a path in the user profile when granting access with `--group`. A socket
created directly under `C:\` can inherit a high integrity level that blocks
access for the configured users and groups.

Configure the Docker client to use the same socket:

```powershell
PS C:\> docker -H unix://C:/Users/<USER>/docker.sock info
```

Learn about the available configuration options in the
[dockerd reference docs](/reference/cli/dockerd.md), or by
running:

```console
$ dockerd --help
```

## Daemon data directory

The Docker daemon persists all data in a single directory. This tracks
everything related to Docker, including containers, images, volumes, service
definition, and secrets.

By default the daemon stores data in:

- `/var/lib/docker` on Linux
- `C:\ProgramData\docker` on Windows

When using the [containerd image store](/manuals/engine/storage/containerd.md)
(the default for Docker Engine 29.0 and later on fresh installations), image
contents and container snapshots are stored in `/var/lib/containerd`. Other
daemon data (volumes, configs) remains in `/var/lib/docker`.

When using [classic storage drivers](/manuals/engine/storage/drivers/_index.md)
like `overlay2` (the default for upgraded installations), all data is stored in
`/var/lib/docker`.

### Configure the data directory location

You can configure the Docker daemon to use a different storage directory using
the `data-root` configuration option.

```json
{
  "data-root": "/mnt/docker-data"
}
```

The `data-root` option does not affect image and container data stored in
`/var/lib/containerd` when using the containerd image store. To change the
storage location of containerd snapshotters, use the system containerd
configuration file:

```toml {title="/etc/containerd/config.toml"}
version = 2
root = "/mnt/containerd-data"
```

Make sure you use a dedicated directory for each daemon. If two daemons share
the same directory, for example an NFS share, you will experience errors that
are difficult to troubleshoot.

## Next steps

Many specific configuration options are discussed throughout the Docker
documentation. Some places to go next include:

- [Automatically start containers](/manuals/engine/containers/start-containers-automatically.md)
- [Run containerd in the Docker daemon](/manuals/engine/daemon/embedded-containerd.md)
- [Limit a container's resources](/manuals/engine/containers/resource_constraints.md)
- [Configure storage drivers](/manuals/engine/storage/drivers/select-storage-driver.md)
- [Container security](/manuals/engine/security/_index.md)
- [Configure the Docker daemon to use a proxy](./proxy.md)

---

### Manuals Engine Install  Index (`content/manuals/engine/install/_index.md`)

---
title: Install Docker Engine
linkTitle: Install
weight: 10
description: Learn how to choose the best method for you to install Docker Engine. This client-server
  application is available on Linux, Mac, Windows, and as a static binary.
keywords: install engine, docker engine install, install docker engine, docker engine
  installation, engine install, docker ce installation, docker ce install, engine
  installer, installing docker engine, docker server install, docker desktop vs docker engine
aliases:
- /cs-engine/
- /cs-engine/1.12/
- /cs-engine/1.12/upgrade/
- /cs-engine/1.13/
- /cs-engine/1.13/upgrade/
- /ee/docker-ee/oracle/
- /ee/supported-platforms/
- /en/latest/installation/
- /engine/installation/
- /engine/installation/frugalware/
- /engine/installation/linux/
- /engine/installation/linux/archlinux/
- /engine/installation/linux/cruxlinux/
- /engine/installation/linux/docker-ce/
- /engine/installation/linux/docker-ee/
- /engine/installation/linux/docker-ee/oracle/
- /engine/installation/linux/frugalware/
- /engine/installation/linux/gentoolinux/
- /engine/installation/linux/oracle/
- /engine/installation/linux/other/
- /engine/installation/oracle/
- /enterprise/supported-platforms/
- /install/linux/docker-ee/oracle/
- /ee/docker-ee/sles/
- /ee/docker-ee/suse/
- /engine/installation/linux/docker-ce/sles/
- /engine/installation/linux/docker-ee/sles/
- /engine/installation/linux/docker-ee/suse/
- /engine/installation/linux/sles/
- /engine/installation/linux/SUSE/
- /engine/installation/linux/suse/
- /engine/installation/sles/
- /engine/installation/SUSE/
- /install/linux/docker-ce/sles/
- /install/linux/docker-ee/sles/
- /install/linux/docker-ee/suse/
- /install/linux/sles/
- /installation/sles/
---

This section describes how to install Docker Engine on Linux. Docker Engine is
also available for Windows, macOS, and Linux,
through Docker Desktop. For instructions on how to install Docker Desktop,
see: [Overview of Docker Desktop](/manuals/desktop/_index.md).

## Installation procedures for supported platforms

Click on a platform's link to view the relevant installation procedure.

| Platform                                       | x86_64 / amd64 | arm64 / aarch64 | arm (32-bit) | ppc64le | s390x |
| :--------------------------------------------- | :------------: | :-------------: | :----------: | :-----: | :---: |
| [CentOS](centos.md)                            |       ✅       |       ✅        |              |   ✅    |       |
| [Debian](debian.md)                            |       ✅       |       ✅        |      ✅      |   ✅    |       |
| [Fedora](fedora.md)                            |       ✅       |       ✅        |              |   ✅    |       |
| [Raspberry Pi OS (32-bit)](raspberry-pi-os.md) |                |                 |      ⚠️      |         |       |
| [RHEL](rhel.md)                                |       ✅       |       ✅        |              |         |  ✅   |
| [Ubuntu](ubuntu.md)                            |       ✅       |       ✅        |      ✅      |   ✅    |  ✅   |
| [Binaries](binaries.md)                        |       ✅       |       ✅        |      ✅      |         |       |

### Other Linux distributions

> [!NOTE]
>
> While the following instructions may work, Docker doesn't test or verify
> installation on distribution derivatives.

- If you use Debian derivatives such as "BunsenLabs Linux", "Kali Linux" or
  "LMDE" (Debian-based Mint) should follow the installation instructions for
  [Debian](debian.md), substitute the version of your distribution for the
  corresponding Debian release. Refer to the documentation of your distribution to find
  which Debian release corresponds with your derivative version.
- Likewise, if you use Ubuntu derivatives such as "Kubuntu", "Lubuntu" or "Xubuntu"
  you should follow the installation instructions for [Ubuntu](ubuntu.md),
  substituting the version of your distribution for the corresponding Ubuntu release.
  Refer to the documentation of your distribution to find which Ubuntu release
  corresponds with your derivative version.
- Some Linux distributions provide a package of Docker Engine through their
  package repositories. These packages are built and maintained by the Linux
  distribution's package maintainers and may have differences in configuration
  or are built from modified source code. Docker isn't involved in releasing these
  packages and you should report any bugs or issues involving these packages to
  your Linux distribution's issue tracker.

Docker provides [binaries](binaries.md) for manual installation of Docker Engine.
These binaries are statically linked and you can use them on any Linux distribution.

## Release channels

Docker Engine has two types of update channels, **stable** and **test**:

* The **stable** channel gives you the latest versions released for general availability.
* The **test** channel gives you pre-release versions that are ready for testing before
  general availability.

Use the test channel with caution. Pre-release versions include experimental and
early-access features that are subject to breaking changes.

## Support

Docker Engine is an open source project, supported by the Moby project maintainers
and community members. Docker doesn't provide support for Docker Engine.
Docker provides support for Docker products, including Docker Desktop, which uses
Docker Engine as one of its components.

For information about the open source project, refer to the
[Moby project website](https://mobyproject.org/).

### Upgrade path

Patch releases are always backward compatible with its major and minor version.

### Licensing

Commercial use of Docker Engine obtained via Docker Desktop
within larger enterprises (exceeding 250 employees OR with annual revenue surpassing
$10 million USD), requires a [paid subscription](https://www.docker.com/pricing?ref=Docs&refAction=DocsEngineInstall).
Apache License, Version 2.0. See [LICENSE](https://github.com/moby/moby/blob/master/LICENSE) for the full license.

## Reporting security issues

If you discover a security issue, we request that you bring it to our attention immediately.

DO NOT file a public issue. Instead, submit your report privately to security@docker.com.

Security reports are greatly appreciated, and Docker will publicly thank you for it.

## Get started

After setting up Docker, you can learn the basics with
[Build and share a containerized application](/get-started/tutorials/run-an-app.md).

---

### Manuals Engine Logging  Index (`content/manuals/engine/logging/_index.md`)

---
description: Learn how to write to, view, and configure a container's logs
keywords: docker, logging
title: View container logs
linkTitle: Logs and metrics
weight: 70
aliases:
  - /engine/admin/logging/
  - /engine/admin/logging/view_container_logs/
  - /config/containers/logging/
---

The `docker logs` command shows information logged by a running container. The
`docker service logs` command shows information logged by all containers
participating in a service. The information that's logged and the format of the
log depends almost entirely on the container's endpoint command.

By default, `docker logs` or `docker service logs` shows the command's output
just as it would appear if you ran the command interactively in a terminal. Unix
and Linux commands typically open three I/O streams when they run, called
`STDIN`, `STDOUT`, and `STDERR`. `STDIN` is the command's input stream, which
may include input from the keyboard or input from another command. `STDOUT` is
usually a command's normal output, and `STDERR` is typically used to output
error messages. By default, `docker logs` shows the command's `STDOUT` and
`STDERR`. To read more about I/O and Linux, see the
[Linux Documentation Project article on I/O redirection](https://tldp.org/LDP/abs/html/io-redirection.html).

In some cases, `docker logs` may not show useful information unless you take
additional steps.

- If you use a [logging driver](configure.md) which sends logs to a file, an
  external host, a database, or another logging back-end, and have ["dual logging"](dual-logging.md)
  disabled, `docker logs` may not show useful information.
- If your image runs a non-interactive process such as a web server or a
  database, that application may send its output to log files instead of `STDOUT`
  and `STDERR`.

In the first case, your logs are processed in other ways and you may choose not
to use `docker logs`. In the second case, the official `nginx` image shows one
workaround, and the official Apache `httpd` image shows another.

The official `nginx` image creates a symbolic link from `/var/log/nginx/access.log`
to `/dev/stdout`, and creates another symbolic link
from `/var/log/nginx/error.log` to `/dev/stderr`, overwriting the log files and
causing logs to be sent to the relevant special device instead. See the
[Dockerfile](https://github.com/nginxinc/docker-nginx/blob/8921999083def7ba43a06fabd5f80e4406651353/mainline/jessie/Dockerfile#L21-L23).

The official `httpd` driver changes the `httpd` application's configuration to
write its normal output directly to `/proc/self/fd/1` (which is `STDOUT`) and
its errors to `/proc/self/fd/2` (which is `STDERR`). See the
[Dockerfile](https://github.com/docker-library/httpd/blob/b13054c7de5c74bbaa6d595dbe38969e6d4f860c/2.2/Dockerfile#L72-L75).

## Next steps

- Configure [logging drivers](configure.md).
- Write a [Dockerfile](/reference/dockerfile.md).

---

### Manuals Engine Manage Resources  Index (`content/manuals/engine/manage-resources/_index.md`)

---
build:
  render: never
title: Manage resources
weight: 60
---

---

### Manuals Engine Network  Index (`content/manuals/engine/network/_index.md`)

---
title: Networking overview
linkTitle: Networking
weight: 30
description: Learn how networking works from the container's point of view
keywords: networking, container, standalone, IP address, DNS resolution
aliases:
  - /articles/networking/
  - /config/containers/container-networking/
  - /engine/tutorials/networkingcontainers/
  - /engine/userguide/networking/
  - /engine/userguide/networking/configure-dns/
  - /engine/userguide/networking/default_network/binding/
  - /engine/userguide/networking/default_network/configure-dns/
  - /engine/userguide/networking/default_network/container-communication/
  - /engine/userguide/networking/dockernetworks/
  - /network/
---

Container networking refers to the ability for containers to connect to and
communicate with each other, and with non-Docker network services.

Containers have networking enabled by default, and they can make outgoing
connections. A container has no information about what kind of network it's
attached to, or whether its network peers are also Docker containers. A
container only sees a network interface with an IP address, a gateway, a
routing table, DNS services, and other networking details.

This page describes networking from the point of view of the container,
and the concepts around container networking.

When Docker Engine on Linux starts for the first time, it has a single
built-in network called the "default bridge" network. When you run a
container without the `--network` option, it is connected to the default
bridge.

Containers attached to the default bridge have access to network services
outside the Docker host. They use "masquerading" which means, if the
Docker host has Internet access, no additional configuration is needed
for the container to have Internet access.

For example, to run a container on the default bridge network, and have
it ping an Internet host:

```console
$ docker run --rm -ti busybox ping -c1 docker.com
PING docker.com (23.185.0.4): 56 data bytes
64 bytes from 23.185.0.4: seq=0 ttl=62 time=6.564 ms

--- docker.com ping statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min/avg/max = 6.564/6.564/6.564 ms
```

## User-defined networks

With the default configuration, containers attached to the default
bridge network have unrestricted network access to each other using
container IP addresses. They cannot refer to each other by name.

It can be useful to separate groups of containers that should have full
access to each other, but restricted access to containers in other groups.

You can create custom, user-defined networks, and connect groups of containers
to the same network. Once connected to a user-defined network, containers
can communicate with each other using container IP addresses or container names.

The following example creates a network using the `bridge` network driver and
runs a container in that network:

```console
$ docker network create -d bridge my-net
$ docker run --network=my-net -it busybox
```

### Drivers

Docker Engine has a number of network drivers, as well as the default "bridge".
On Linux, the following built-in network drivers are available:

| Driver                          | Description                                                         |
| :------------------------------ | :------------------------------------------------------------------ |
| [bridge](./drivers/bridge.md)   | The default network driver.                                         |
| [host](./drivers/host.md)       | Remove network isolation between the container and the Docker host. |
| [none](./drivers/none.md)       | Completely isolate a container from the host and other containers.  |
| [overlay](./drivers/overlay.md) | Swarm Overlay networks connect multiple Docker daemons together.    |
| [ipvlan](./drivers/ipvlan.md)   | Connect containers to external VLANs.                               |
| [macvlan](./drivers/macvlan.md) | Containers appear as devices on the host's network.                 |

More information can be found in the network driver specific pages, including
their configuration options and details about their functionality.

Native Windows containers have a different set of drivers, see
[Windows container network drivers](https://learn.microsoft.com/en-us/virtualization/windowscontainers/container-networking/network-drivers-topologies).

### Connecting to multiple networks

Connecting a container to a network can be compared to connecting an Ethernet
cable to a physical host. Just as a host can be connected to multiple Ethernet
networks, a container can be connected to multiple Docker networks.

For example, a frontend container may be connected to a bridge network
with external access, and a
[`--internal`](/reference/cli/docker/network/create/#internal) network
to communicate with containers running backend services that do not need
external network access.

A container may also be connected to different types of network. For example,
an `ipvlan` network to provide internet access, and a `bridge` network for
access to local services.

Containers can also share networking stacks, see [Container networks](#container-networks).

When sending packets, if the destination is an address in a directly connected
network, packets are sent to that network. Otherwise, packets are sent to
a default gateway for routing to their destination. In the example above,
the `ipvlan` network's gateway must be the default gateway.

The default gateway is selected by Docker, and may change whenever a
container's network connections change.
To make Docker choose a specific default gateway when creating the container
or connecting a new network, set a gateway priority. See option `gw-priority`
for the [`docker run`](/reference/cli/docker/container/run/) and
[`docker network connect`](/reference/cli/docker/network/connect/) commands.

The default `gw-priority` is `0` and the gateway in the network with the
highest priority is the default gateway. So, when a network should always
be the default gateway, it is enough to set its `gw-priority` to `1`.

```console
$ docker run --network name=gwnet,gw-priority=1 --network anet1 --name myctr myimage
$ docker network connect anet2 myctr
```

## Published ports

When you create or run a container using `docker create` or `docker run`, all
ports of containers on bridge networks are accessible from the Docker host and
other containers connected to the same network. Ports are not accessible from
outside the host or, with the default configuration, from containers in other
networks.

Use the `--publish` or `-p` flag to make a port available outside the host,
and to containers in other bridge networks.

For more information about port mapping, including how to disable it and use
direct routing to containers, see
[port publishing](./port-publishing.md).

## IP address and hostname

When creating a network, IPv4 address allocation is enabled by default, it
can be disabled using `--ipv4=false`. IPv6 address allocation can be enabled
using `--ipv6`.

```console
$ docker network create --ipv6 --ipv4=false v6net
```

By default, the container gets an IP address for every Docker network it attaches to.
A container receives an IP address out of the IP subnet of the network.
The Docker daemon performs dynamic subnetting and IP address allocation for containers.
Each network also has a default subnet mask and gateway.

You can connect a running container to multiple networks,
either by passing the `--network` flag multiple times when creating the container,
or using the `docker network connect` command for already running containers.
In both cases, you can use the `--ip` or `--ip6` flags to specify the container's IP address on that particular network.

In the same way, a container's hostname defaults to be the container's ID in Docker.
You can override the hostname using `--hostname`.
When connecting to an existing network using `docker network connect`,
you can use the `--alias` flag to specify an additional network alias for the container on that network.

### Subnet allocation

Docker networks can use either explicitly configured subnets or automatically allocated ones from default pools.

#### Explicit subnet configuration

You can specify exact subnets when creating a network:

```console
$ docker network create --ipv6 --subnet 192.0.2.0/24 --subnet 2001:db8::/64 mynet
```

#### Automatic subnet allocation

When no `--subnet` option is provided, Docker automatically selects a subnet from predefined "default address pools".
These pools can be configured in `/etc/docker/daemon.json`. Docker's built-in default is equivalent to:

```json
{
  "default-address-pools": [
    { "base": "172.17.0.0/16", "size": 16 },
    { "base": "172.18.0.0/16", "size": 16 },
    { "base": "172.19.0.0/16", "size": 16 },
    { "base": "172.20.0.0/14", "size": 16 },
    { "base": "172.24.0.0/14", "size": 16 },
    { "base": "172.28.0.0/14", "size": 16 },
    { "base": "192.168.0.0/16", "size": 20 }
  ]
}
```

- `base`: The subnet that can be allocated from.
- `size`: The prefix length used for each allocated subnet.

When an IPv6 subnet is required and there are no IPv6 addresses in `default-address-pools`, Docker allocates
subnets from a Unique Local Address (ULA) prefix. To use specific IPv6 subnets instead, add them to your
`default-address-pools`. See [Dynamic IPv6 subnet allocation](../daemon/ipv6.md#dynamic-ipv6-subnet-allocation)
for more information.

Docker attempts to avoid address prefixes already in use on the host. However, you may need to customize
`default-address-pools` to prevent routing conflicts in some network environments.

The default pools use large subnets, which limits the number of networks you can create. You can divide base
subnets into smaller pools to support more networks.

For example, this configuration allows Docker to create 256 networks from `172.17.0.0/16`.
Docker will allocate subnets `172.17.0.0/24`, `172.17.1.0/24`, and so on, up to `172.17.255.0/24`:

```json
{
  "default-address-pools": [{ "base": "172.17.0.0/16", "size": 24 }]
}
```

You can also request a subnet with a specific prefix length from the default pools by using unspecified
addresses in the `--subnet` option:

```console
$ docker network create --ipv6 --subnet ::/56 --subnet 0.0.0.0/24 mynet
6686a6746b17228f5052528113ddad0e6d68e2e3905d648e336b33409f2d3b64
$ docker network inspect mynet -f '{{json .IPAM.Config}}' | jq .
[
  {
    "Subnet": "172.19.0.0/24",
    "Gateway": "172.19.0.1"
  },
  {
    "Subnet": "fdd3:6f80:972c::/56",
    "Gateway": "fdd3:6f80:972c::1"
  }
]
```

> [!NOTE]
>
> Support for unspecified addresses in `--subnet` was introduced in Docker 29.0.0.
> If Docker is downgraded to an older version, networks created in this way will become unusable.
> They can be removed and re-created, or will function again if the daemon is restored to 29.0.0 or later.

## DNS services

Containers use the same DNS servers as the host by default, but you can
override this with `--dns`.

By default, containers inherit the DNS settings as defined in the
`/etc/resolv.conf` configuration file.
Containers that attach to the default `bridge` network receive a copy of this file.
Containers that attach to a
[custom network](drivers/bridge.md#use-user-defined-bridge-networks)
use Docker's embedded DNS server.
The embedded DNS server forwards external DNS lookups to the DNS servers configured on the host.
The embedded DNS server address is `127.0.0.11`.
There is no IPv6 equivalent; the IPv4 address works even in IPv6-only containers.
If an application requires an explicit DNS server address, use `127.0.0.11`.

> [!NOTE]
>
> When you configure multiple DNS servers for a container on the default
> `bridge` network, the container's resolver library determines how it queries
> them. Some resolvers query the servers in order. Others query them in parallel
> and use the first response received, even if that response is `NXDOMAIN`.
> On a custom network, Docker's embedded DNS server queries upstream servers in
> order and stops after a successful response or an `NXDOMAIN` response.

You can configure DNS resolution on a per-container basis, using flags for the
`docker run` or `docker create` command used to start the container.
The following table describes the available `docker run` flags related to DNS
configuration.

| Flag           | Description                                                                                                                                                                                                                                           |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--dns`        | The IP address of a DNS server. To specify multiple DNS servers, use multiple `--dns` flags. DNS requests will be forwarded from the container's network namespace so, for example, `--dns=127.0.0.1` refers to the container's own loopback address. |
| `--dns-search` | A DNS search domain to search non-fully qualified hostnames. To specify multiple DNS search prefixes, use multiple `--dns-search` flags.                                                                                                              |
| `--dns-opt`    | A key-value pair representing a DNS option and its value. See your operating system's documentation for `resolv.conf` for valid options.                                                                                                              |
| `--hostname`   | The hostname a container uses for itself. Defaults to the container's ID if not specified.                                                                                                                                                            |

### Custom hosts

Your container will have lines in `/etc/hosts` which define the hostname of the
container itself, as well as `localhost` and a few other common things. Custom
hosts, defined in `/etc/hosts` on the host machine, aren't inherited by
containers. To pass additional hosts into a container, refer to [add entries to
container hosts file](/reference/cli/docker/container/run/#add-host) in the
`docker run` reference documentation.

## Container networks

In addition to user-defined networks, you can attach a container to another
container's networking stack directly, using the `--network
container:<name|id>` flag format.

The following flags aren't supported for containers using the `container:`
networking mode:

- `--add-host`
- `--hostname`
- `--dns`
- `--dns-search`
- `--dns-option`
- `--mac-address`
- `--publish`
- `--publish-all`
- `--expose`

The following example runs a Redis container, with Redis binding to
127.0.0.1, then running the `redis-cli` command and connecting to the Redis
server over 127.0.0.1.

```console
$ docker run -d --name redis redis --bind 127.0.0.1
$ docker run --rm -it --network container:redis redis redis-cli -h 127.0.0.1
```

---

### Manuals Engine Release Notes  Index (`content/manuals/engine/release-notes/_index.md`)

---
build:
  render: never
title: Release notes
sidebar:
  reverse: true
---

---

### Manuals Engine Security  Index (`content/manuals/engine/security/_index.md`)

---
description: Review of the Docker Daemon attack surface
keywords: Docker, Docker documentation, security
title: Docker Engine security
linkTitle: Security
weight: 80
aliases:
- /articles/security/
- /engine/articles/security/
- /engine/security/security/
- /security/security/
---

There are four major areas to consider when reviewing Docker security:

 - The intrinsic security of the kernel and its support for
   namespaces and cgroups
 - The attack surface of the Docker daemon itself
 - Loopholes in the container configuration profile, either by default,
   or when customized by users.
 - The "hardening" security features of the kernel and how they
   interact with containers.

## Kernel namespaces

Docker containers are very similar to LXC containers, and they have
similar security features. When you start a container with
`docker run`, behind the scenes Docker creates a set of namespaces and control
groups for the container.

Namespaces provide the first and most straightforward form of
isolation. Processes running within a container cannot see, and even
less affect, processes running in another container, or in the host
system.

Each container also gets its own network stack, meaning that a
container doesn't get privileged access to the sockets or interfaces
of another container. Of course, if the host system is setup
accordingly, containers can interact with each other through their
respective network interfaces — just like they can interact with
external hosts. When you specify public ports for your containers or use
[links](/manuals/engine/network/links.md)
then IP traffic is allowed between containers. They can ping each other,
send/receive UDP packets, and establish TCP connections, but that can be
restricted if necessary. From a network architecture point of view, all
containers on a given Docker host are sitting on bridge interfaces. This
means that they are just like physical machines connected through a
common Ethernet switch; no more, no less.

How mature is the code providing kernel namespaces and private
networking? Kernel namespaces were introduced [between kernel version
2.6.15 and
2.6.26](https://man7.org/linux/man-pages/man7/namespaces.7.html).
This means that since July 2008 (date of the 2.6.26 release
), namespace code has been exercised and scrutinized on a large
number of production systems. And there is more: the design and
inspiration for the namespaces code are even older. Namespaces are
actually an effort to reimplement the features of [OpenVZ](
https://en.wikipedia.org/wiki/OpenVZ) in such a way that they could be
merged within the mainstream kernel. And OpenVZ was initially released
in 2005, so both the design and the implementation are pretty mature.

## Control groups

Control Groups are another key component of Linux containers. They
implement resource accounting and limiting. They provide many
useful metrics, but they also help ensure that each container gets
its fair share of memory, CPU, disk I/O; and, more importantly, that a
single container cannot bring the system down by exhausting one of those
resources.

So while they do not play a role in preventing one container from
accessing or affecting the data and processes of another container, they
are essential to fend off some denial-of-service attacks. They are
particularly important on multi-tenant platforms, like public and
private PaaS, to guarantee a consistent uptime (and performance) even
when some applications start to misbehave.

Control Groups have been around for a while as well: the code was
started in 2006, and initially merged in kernel 2.6.24.

## Docker daemon attack surface

Running containers (and applications) with Docker implies running the
Docker daemon. This daemon requires `root` privileges unless you opt-in
to [Rootless mode](rootless.md), and you should therefore be aware of
some important details.

First of all, only trusted users should be allowed to control your
Docker daemon. This is a direct consequence of some powerful Docker
features. Specifically, Docker allows you to share a directory between
the Docker host and a guest container; and it allows you to do so
without limiting the access rights of the container. This means that you
can start a container where the `/host` directory is the `/` directory
on your host; and the container can alter your host filesystem
without any restriction. This is similar to how virtualization systems
allow filesystem resource sharing. Nothing prevents you from sharing your
root filesystem (or even your root block device) with a virtual machine.

This has a strong security implication: for example, if you instrument Docker
from a web server to provision containers through an API, you should be
even more careful than usual with parameter checking, to make sure that
a malicious user cannot pass crafted parameters causing Docker to create
arbitrary containers.

For this reason, the REST API endpoint (used by the Docker CLI to
communicate with the Docker daemon) changed in Docker 0.5.2, and now
uses a Unix socket instead of a TCP socket bound on 127.0.0.1 (the
latter being prone to cross-site request forgery attacks if you happen to run
Docker directly on your local machine, outside of a VM). You can then
use traditional Unix permission checks to limit access to the control
socket.

You can also expose the REST API over HTTP if you explicitly decide to do so.
However, if you do that, be aware of the above mentioned security implications.
Note that even if you have a firewall to limit accesses to the REST API 
endpoint from other hosts in the network, the endpoint can be still accessible
from containers, and it can easily result in the privilege escalation.
Therefore it is *mandatory* to secure API endpoints with 
[HTTPS and certificates](protect-access.md).
Exposing the daemon API over HTTP without TLS is not permitted,
and such a configuration causes the daemon to fail early on startup, see
[Unauthenticated TCP connections](../deprecated.md#unauthenticated-tcp-connections).
It is also recommended to ensure that it is reachable only from a trusted
network or VPN.

You can also use `DOCKER_HOST=ssh://USER@HOST` or `ssh -L /path/to/docker.sock:/var/run/docker.sock`
instead if you prefer SSH over TLS.

The daemon is also potentially vulnerable to other inputs, such as image
loading from either disk with `docker load`, or from the network with
`docker pull`. As of Docker 1.3.2, images are now extracted in a chrooted
subprocess on Linux/Unix platforms, being the first-step in a wider effort
toward privilege separation. As of Docker 1.10.0, all images are stored and
accessed by the cryptographic checksums of their contents, limiting the
possibility of an attacker causing a collision with an existing image.

Finally, if you run Docker on a server, it is recommended to run
exclusively Docker on the server, and move all other services within
containers controlled by Docker. Of course, it is fine to keep your
favorite admin tools (probably at least an SSH server), as well as
existing monitoring/supervision processes, such as NRPE and collectd.

## Linux kernel capabilities

By default, Docker starts containers with a restricted set of
capabilities. What does that mean?

Capabilities turn the binary "root/non-root" dichotomy into a
fine-grained access control system. Processes (like web servers) that
just need to bind on a port below 1024 do not need to run as root: they
can just be granted the `net_bind_service` capability instead. And there
are many other capabilities, for almost all the specific areas where root
privileges are usually needed. This means a lot for container security.

Typical servers run several processes as `root`, including the SSH daemon,
`cron` daemon, logging daemons, kernel modules, network configuration tools,
and more. A container is different, because almost all of those tasks are
handled by the infrastructure around the container:

 - SSH access are typically managed by a single server running on
   the Docker host
 - `cron`, when necessary, should run as a user
   process, dedicated and tailored for the app that needs its
   scheduling service, rather than as a platform-wide facility
 - Log management is also typically handed to Docker, or to
   third-party services like Loggly or Splunk
 - Hardware management is irrelevant, meaning that you never need to
   run `udevd` or equivalent daemons within
   containers
 - Network management happens outside of the containers, enforcing
   separation of concerns as much as possible, meaning that a container
   should never need to perform `ifconfig`,
   `route`, or ip commands (except when a container
   is specifically engineered to behave like a router or firewall, of
   course)

This means that in most cases, containers do not need "real" root
privileges at all* And therefore, containers can run with a reduced
capability set; meaning that "root" within a container has much less
privileges than the real "root". For instance, it is possible to:

 - Deny all "mount" operations
 - Deny access to raw sockets (to prevent packet spoofing)
 - Deny access to some filesystem operations, like creating new device
   nodes, changing the owner of files, or altering attributes (including
   the immutable flag)
 - Deny module loading

This means that even if an intruder manages to escalate to root within a
container, it is much harder to do serious damage, or to escalate
to the host.

This doesn't affect regular web apps, but reduces the vectors of attack by
malicious users considerably. By default Docker
drops all capabilities except [those
needed](https://github.com/moby/moby/blob/master/daemon/pkg/oci/caps/defaults.go#L6-L19),
an allowlist instead of a denylist approach. You can see a full list of
available capabilities in [Linux
manpages](https://man7.org/linux/man-pages/man7/capabilities.7.html).

One primary risk with running Docker containers is that the default set
of capabilities and mounts given to a container may provide incomplete
isolation, either independently, or when used in combination with
kernel vulnerabilities.

Docker supports the addition and removal of capabilities, allowing use
of a non-default profile. This may make Docker more secure through
capability removal, or less secure through the addition of capabilities.
The best practice for users would be to remove all capabilities except
those explicitly required for their processes.

## Docker Content Trust signature verification

Docker Engine can be configured to only run signed images. The Docker Content 
Trust signature verification feature is built directly into the `dockerd` binary.  
This is configured in the Dockerd configuration file. 

To enable this feature, trustpinning can be configured in `daemon.json`, whereby 
only repositories signed with a user-specified root key can be pulled and run.
  
This feature provides more insight to administrators than previously available with
the CLI for enforcing and performing image signature verification. 

For more information on configuring Docker Content Trust Signature Verification, go to 
[Content trust in Docker](trust/_index.md).

## Other kernel security features

Capabilities are just one of the many security features provided by
modern Linux kernels. It is also possible to leverage existing,
well-known systems like TOMOYO, AppArmor, SELinux, GRSEC, etc. with
Docker.

While Docker currently only enables capabilities, it doesn't interfere
with the other systems. This means that there are many different ways to
harden a Docker host. Here are a few examples.

 - You can run a kernel with GRSEC and PAX. This adds many safety
   checks, both at compile-time and run-time; it also defeats many
   exploits, thanks to techniques like address randomization. It doesn't
   require Docker-specific configuration, since those security features
   apply system-wide, independent of containers.
 - If your distribution comes with security model templates for
   Docker containers, you can use them out of the box. For instance, we
   ship a template that works with AppArmor and Red Hat comes with SELinux
   policies for Docker. These templates provide an extra safety net (even
   though it overlaps greatly with capabilities).
 - You can define your own policies using your favorite access control
   mechanism.

Just as you can use third-party tools to augment Docker containers, including
special network topologies or shared filesystems, tools exist to harden Docker
containers without the need to modify Docker itself.

As of Docker 1.10 User Namespaces are supported directly by the docker
daemon. This feature allows for the root user in a container to be mapped
to a non uid-0 user outside the container, which can help to mitigate the
risks of container breakout. This facility is available but not enabled
by default.

Refer to the [daemon command](/reference/cli/dockerd.md#daemon-user-namespace-options)
in the command line reference for more information on this feature.
Additional information on the implementation of User Namespaces in Docker
can be found in
[this blog post](https://integratedcode.us/2015/10/13/user-namespaces-have-arrived-in-docker/).

## Conclusions

Docker containers are, by default, quite secure; especially if you
run your processes as non-privileged users inside the container.

You can add an extra layer of safety by enabling AppArmor, SELinux,
GRSEC, or another appropriate hardening system.

If you think of ways to make docker more secure, we welcome feature requests,
pull requests, or comments on the Docker community forums.

## Related information

* [Use trusted images](trust/_index.md)
* [Seccomp security profiles for Docker](seccomp.md)
* [AppArmor security profiles for Docker](apparmor.md)
* [On the Security of Containers (2014)](https://medium.com/@ewindisch/on-the-security-of-containers-2c60ffe25a9e)
* [Docker swarm mode overlay network security model](/manuals/engine/network/drivers/overlay.md)

---

### Manuals Engine Storage  Index (`content/manuals/engine/storage/_index.md`)

---
description: Overview of persisting data in containers
title: Storage
weight: 20
keywords: storage, persistence, data persistence, volumes, mounts, bind mounts, tmpfs
aliases:
  - /engine/admin/volumes/
  - /storage/
---

Docker storage covers two different concepts:

**Container data persistence** (this page): How to store application data
outside containers using volumes, bind mounts, and tmpfs mounts. This data
persists independently of container lifecycle.

**Daemon storage backends** ([containerd image store](containerd.md) and
[storage drivers](drivers/)): How the daemon stores image layers and container
writable layers on disk.

This page focuses on container data persistence. For information about how
Docker stores images and container layers, see
[containerd image store](containerd.md) or [Storage drivers](drivers/).

## Container layer basics

By default all files created inside a container are stored on a writable
container layer that sits on top of the read-only, immutable image layers.

Data written to the container layer doesn't persist when the container is
destroyed. This means that it can be difficult to get the data out of the
container if another process needs it.

The writable layer is unique per container. You can't easily extract the data
from the writeable layer to the host, or to another container.

## Storage mount options

Docker supports the following types of storage mounts for storing data outside
of the writable layer of the container:

- [Volume mounts](#volume-mounts)
- [Bind mounts](#bind-mounts)
- [tmpfs mounts](#tmpfs-mounts)
- [Image mounts](#image-mounts)
- [Named pipes](#named-pipes)

No matter which type of mount you choose to use, the data looks the same from
within the container. It is exposed as either a directory or an individual file
in the container's filesystem.

### Volume mounts

Volumes are persistent storage mechanisms managed by the Docker daemon. They
retain data even after the containers using them are removed. Volume data is
stored on the filesystem on the host, but in order to interact with the data in
the volume, you must mount the volume to a container. Directly accessing or
interacting with the volume data is unsupported, undefined behavior, and may
result in the volume or its data breaking in unexpected ways.

Volumes are ideal for performance-critical data processing and long-term
storage needs. Since the storage location is managed on the daemon host,
volumes provide the same raw file performance as accessing the host filesystem
directly.

### Bind mounts

Bind mounts create a direct link between a host system path and a container,
allowing access to files or directories stored anywhere on the host. Since they
aren't isolated by Docker, both non-Docker processes on the host and container
processes can modify the mounted files simultaneously.

Use bind mounts when you need to be able to access files from both the
container and the host.

### tmpfs mounts

A tmpfs mount stores files directly in the host machine's memory, ensuring the
data is not written to disk. This storage is ephemeral: the data is lost when
the container is stopped or restarted, or when the host is rebooted. tmpfs
mounts do not persist data either on the Docker host or within the container's
filesystem.

These mounts are suitable for scenarios requiring temporary, in-memory storage,
such as caching intermediate data, handling sensitive information like
credentials, or reducing disk I/O. Use tmpfs mounts only when the data does not
need to persist beyond the current container session.

### Image mounts

An image mount makes the contents of another image available inside a container
at a path you choose. The mounted image is read-only and isn't part of the
container's own image, so you can bring in tools or assets from one image
without rebuilding another.

Use image mounts when you need to consume files packaged as an image, such as
mounting a tool-rich image to debug a minimal container, or sharing read-only
assets across containers running different images. Image mounts require the
[containerd image store](containerd.md).

### Named pipes

[Named pipes](https://docs.microsoft.com/en-us/windows/desktop/ipc/named-pipes)
can be used for communication between the Docker host and a container. Common
use case is to run a third-party tool inside of a container and connect to the
Docker Engine API using a named pipe.

## Next steps

Learn more about container data persistence:

- [Volumes](./volumes.md)
- [Bind mounts](./bind-mounts.md)
- [tmpfs mounts](./tmpfs.md)
- [Image mounts](./image-mounts.md)

Learn more about daemon storage backends:

- [containerd image store](containerd.md)
- [Storage drivers](drivers/)

---

### Manuals Engine Swarm  Index (`content/manuals/engine/swarm/_index.md`)

---
description: Docker Engine Swarm mode overview
keywords: docker, container, cluster, swarm, docker engine
title: Swarm mode
weight: 80
aliases:
- /api/swarm-api/
- /engine/userguide/networking/overlay-standalone-swarm/
- /network/overlay-standalone.swarm/
- /release-notes/docker-swarm/
- /swarm/
- /swarm/api/
- /swarm/configure-tls/
- /swarm/discovery/
- /swarm/get-swarm/
- /swarm/install-manual/
- /swarm/install-w-machine/
- /swarm/multi-host-networking/
- /swarm/multi-manager-setup/
- /swarm/networking/
- /swarm/overview/
- /swarm/plan-for-production/
- /swarm/provision-with-machine/
- /swarm/reference/
- /swarm/reference/create/
- /swarm/reference/help/
- /swarm/reference/join/
- /swarm/reference/list/
- /swarm/reference/manage/
- /swarm/reference/swarm/
- /swarm/release-notes/
- /swarm/scheduler/
- /swarm/scheduler/filter/
- /swarm/scheduler/rescheduling/
- /swarm/scheduler/strategy/
- /swarm/secure-swarm-tls/
- /swarm/status-code-comparison-to-docker/
- /swarm/swarm-api/
- /swarm/swarm_at_scale/
- /swarm/swarm_at_scale/02-deploy-infra/
- /swarm/swarm_at_scale/03-create-cluster/
- /swarm/swarm_at_scale/04-deploy-app/
- /swarm/swarm_at_scale/about/
- /swarm/swarm_at_scale/deploy-app/
- /swarm/swarm_at_scale/deploy-infra/
- /swarm/swarm_at_scale/troubleshoot/
---

{{% include "swarm-mode.md" %}}

Current versions of Docker include Swarm mode for natively managing a cluster
of Docker Engines called a swarm. Use the Docker CLI to create a swarm, deploy
application services to a swarm, and manage swarm behavior.

Docker Swarm mode is built into the Docker Engine. Do not confuse Docker Swarm mode
with [Docker Classic Swarm](https://github.com/docker/classicswarm)
which is no longer actively developed.

## Feature highlights

### Cluster management integrated with Docker Engine

Use the Docker Engine CLI to create a swarm of Docker Engines where you can deploy application
services. You don't need additional orchestration software to create or manage
a swarm.

### Decentralized design

Instead of handling differentiation between node roles at deployment time, the Docker Engine handles any specialization at runtime. You can deploy both kinds of nodes, managers and workers, using the
Docker Engine. This means you can build an entire swarm from a single disk
image.

### Declarative service model

Docker Engine uses a declarative approach to
let you define the desired state of the various services in your application
stack. For example, you might describe an application comprised of a web front
end service with message queueing services and a database backend.

### Scaling 

For each service, you can declare the number of tasks you want to
run. When you scale up or down, the swarm manager automatically adapts by
adding or removing tasks to maintain the desired state.

### Desired state reconciliation

The swarm manager node constantly monitors
the cluster state and reconciles any differences between the actual state and your
expressed desired state. For example, if you set up a service to run 10
replicas of a container, and a worker machine hosting two of those replicas
crashes, the manager creates two new replicas to replace the replicas that
crashed. The swarm manager assigns the new replicas to workers that are
running and available.

### Multi-host networking

You can specify an overlay network for your
services. The swarm manager automatically assigns addresses to the containers
on the overlay network when it initializes or updates the application.

### Service discovery

Swarm manager nodes assign each service in the swarm a
unique DNS name and load balance running containers. You can query every
container running in the swarm through a DNS server embedded in the swarm.

### Load balancing

You can expose the ports for services to an
external load balancer. Internally, the swarm lets you specify how to distribute
service containers between nodes.

### Secure by default

Each node in the swarm enforces TLS mutual
authentication and encryption to secure communications between itself and all
other nodes. You have the option to use self-signed root certificates or
certificates from a custom root CA.

### Rolling updates

At rollout time you can apply service updates to nodes
incrementally. The swarm manager lets you control the delay between service
deployment to different sets of nodes. If anything goes wrong, you can
roll back to a previous version of the service.

## What's next?

* Learn Swarm mode [key concepts](key-concepts.md).
* Get started with the [Swarm mode tutorial](swarm-tutorial/_index.md).
* Explore Swarm mode CLI commands
  * [swarm init](/reference/cli/docker/swarm/init/)
  * [swarm join](/reference/cli/docker/swarm/join/)
  * [service create](/reference/cli/docker/service/create/)
  * [service inspect](/reference/cli/docker/service/inspect/)
  * [service ls](/reference/cli/docker/service/ls/)
  * [service rm](/reference/cli/docker/service/rm/)
  * [service scale](/reference/cli/docker/service/scale/)
  * [service ps](/reference/cli/docker/service/ps/)
  * [service update](/reference/cli/docker/service/update/)

---

### Manuals Extensions Extensions Sdk  Index (`content/manuals/extensions/extensions-sdk/_index.md`)

---
title: Overview of the Extensions SDK
linkTitle: Extensions SDK
description: Overall index for Docker Extensions SDK documentation
keywords: Docker, Extensions, sdk
aliases:
 - /desktop/extensions-sdk/dev/overview/
 - /desktop/extensions-sdk/
grid:
  - title: "The build and publish process"
    description: Understand the process for building and publishing an extension.
    icon: clipboard-document-check
    link: "/extensions/extensions-sdk/process/"
  - title: "Quickstart guide"
    description: Follow the quickstart guide to create a basic Docker extension quickly.
    icon: magnifying-glass-plus
    link: "/extensions/extensions-sdk/quickstart/"
  - title: "View the design guidelines"
    description: Ensure your extension aligns to Docker's design guidelines and principles.
    icon: paint-brush
    link: "/extensions/extensions-sdk/design/design-guidelines/"
  - title: "Publish your extension"
    description: Understand how to publish your extension to the Marketplace.
    icon: arrow-up-tray
    link: "/extensions/extensions-sdk/extensions/"
  - title: "Interacting with Kubernetes"
    description: Find information on how to interact indirectly with a Kubernetes cluster from your Docker extension.
    icon: arrows-right-left
    link: "/extensions/extensions-sdk/guides/kubernetes/"
  - title: "Multi-arch extensions"
    description: Build your extension for multiple architectures.
    icon: document-duplicate
    link: "/extensions/extensions-sdk/extensions/multi-arch/"
---

> [!IMPORTANT]
>
> New submissions to the Docker Extensions Marketplace are paused while Docker reviews Marketplace security. You can still update existing extensions, and private Marketplace extensions are unaffected. Contact extensions@docker.com if you have additional questions.

The resources in this section help you create your own Docker extension.

The Docker CLI tool provides a set of commands to help you build and publish your extension, packaged as a 
specially formatted Docker image.

At the root of the image filesystem is a `metadata.json` file which describes the content of the extension. 
It's a fundamental element of a Docker extension.

An extension can contain a UI part and backend parts that run either on the host or in the Desktop virtual machine.
For further information, see [Architecture](architecture/_index.md).

You distribute extensions through Docker Hub. However, you can develop them locally without the need to push 
the extension to Docker Hub. See [Extensions distribution](extensions/DISTRIBUTION.md) for further details.

{{% include "extensions-form.md" %}}

{{< grid >}}

---

### Manuals Extensions Extensions Sdk Quickstart (`content/manuals/extensions/extensions-sdk/quickstart.md`)

---
title: Quickstart
description: Guide on how to build an extension quickly
keywords: quickstart, extensions
aliases:
 - desktop/extensions-sdk/tutorials/initialize/
 - /desktop/extensions-sdk/quickstart/
weight: 20
---

Follow this guide to get started with creating a basic Docker extension. The Quickstart guide automatically generates boilerplate files for you.

## Prerequisites

- [Docker Desktop](/manuals/desktop/release-notes.md)
- [NodeJS](https://nodejs.org/)
- [Go](https://go.dev/dl/)

> [!NOTE]
>
> NodeJS and Go are only required when you follow the quickstart guide to create an extension. It uses the `docker extension init` command to automatically generate boilerplate files. This command uses a template based on a ReactJS and Go application.

In Docker Desktop settings, ensure you can install the extension you're developing. You may need to navigate to the **Extensions** tab in Docker Desktop settings and deselect **Allow only extensions distributed through the Docker Marketplace**.

## Step one: Set up your directory

To set up your directory, use the `init` subcommand and provide a name for your extension.

```console
$ docker extension init <my-extension>
```

The command asks a series of questions about your extension, such as its name, a description, and the name of your Hub repository. This helps the CLI generate a set of boilerplate files for you to get started. It stores the boilerplate files in the `my-extension` directory.

The automatically generated extension contains:

- A Go backend service in the `backend` folder that listens on a socket. It has one endpoint `/hello` that returns a JSON payload.
- A React frontend in the `frontend` folder that can call the backend and output the backend’s response.

For more information and guidelines on building the UI, see the [Design and UI styling section](design/design-guidelines.md).

## Step two: Build the extension

To build the extension, move into the newly created directory and run:

```console
$ docker build -t <name-of-your-extension> .
```

`docker build` builds the extension and generates an image named the same as the chosen hub repository. For example, if you typed `john/my-extension` as the answer to the following question:

```console
? Hub repository (eg. namespace/repository on hub): john/my-extension`
```

The `docker build` generates an image with name `john/my-extension`.

## Step three: Install and preview the extension

To install the extension in Docker Desktop, run:

```console
$ docker extension install <name-of-your-extension>
```

To preview the extension in Docker Desktop, once the installation is complete and you should
see a **Quickstart** item underneath the **Extensions** menu. Selecting this item opens the extension's frontend.

> [!TIP]
>
> During UI development, it’s helpful to use hot reloading to test your changes without rebuilding your entire
> extension. See [Preview whilst developing the UI](dev/test-debug.md#hot-reloading-whilst-developing-the-ui) for more information.

You may also want to inspect the containers that belong to the extension. By default, extension containers are
hidden from the Docker Dashboard. You can change this in **Settings**, see
[how to show extension containers](dev/test-debug.md#show-the-extension-containers) for more information.

## Step four: Submit and publish your extension to the Marketplace

> [!IMPORTANT]
>
> New submissions to the Docker Extensions Marketplace are paused while Docker reviews Marketplace security. You can still update existing extensions, and private Marketplace extensions are unaffected. Contact extensions@docker.com if you have additional questions.

If you want to make your extension available to all Docker Desktop users, you can submit it for publication in the Marketplace. For more information, see [Publish](extensions/_index.md).

## Clean up

To remove the extension, run:

```console
$ docker extension rm <name-of-your-extension>
```

## What's next

- Build a more [advanced frontend](build/frontend-extension-tutorial.md) for your extension.
- Learn how to [test and debug](dev/test-debug.md) your extension.
- Learn how to [setup CI for your extension](dev/continuous-integration.md).
- Learn more about extensions [architecture](architecture/_index.md).
- Learn more about [designing the UI](design/design-guidelines.md).

---

### Manuals Scout Deep Dive  Index (`content/manuals/scout/deep-dive/_index.md`)

---
build:
  render: never
title: Deep dive
weight: 60
---

---

### Manuals Scout Explore  Index (`content/manuals/scout/explore/_index.md`)

---
build:
  render: never
title: Explore
weight: 40
---

---

### Manuals Scout How Tos  Index (`content/manuals/scout/how-tos/_index.md`)

---
build:
  render: never
title: How-tos
weight: 50
---

---

### Manuals Scout Integrations  Index (`content/manuals/scout/integrations/_index.md`)

---
description: How to set up Docker Scout with other systems.
keywords: supply chain, security, integrations, registries, ci, environments
title: Integrating Docker Scout with other systems
linkTitle: Integrations
weight: 80
---

By default, Docker Scout integrates with your Docker organization and your
Docker Scout-enabled repositories on Docker Hub. You can integrate Docker Scout
with additional third-party systems to get access to even more insights,
including real-time information about you running workloads.

## Integration categories

You'll get different insights depending on where and how you choose to integrate
Docker Scout.

### Container registries

Integrating Docker Scout with third-party container
registries enables Docker Scout to run image analysis on those repositories,
so that you can get insights into the composition of those images even if they
aren't hosted on Docker Hub.

Docker Scout integrates with any Docker/OCI-compliant registry using
[`docker scout watch`](./registry.md), including Amazon ECR, Azure
Container Registry, JFrog Artifactory, Harbor, and Sonatype Nexus.

### Continuous Integration

Integrating Docker Scout with Continuous Integration (CI) systems is a great way
to get instant, automatic feedback about your security posture in your inner
loop. Analysis running in CI also gets the benefit of additional context that's
useful for getting even more insights.

The following CI integrations are available:

- [GitHub Actions](./ci/gha.md)
- [GitLab](./ci/gitlab.md)
- [Microsoft Azure DevOps Pipelines](./ci/azure.md)
- [Circle CI](./ci/circle-ci.md)
- [Jenkins](./ci/jenkins.md)

### Environment monitoring

Environment monitoring refers to integrating Docker Scout with your deployments.
This can give you information in real-time about your running container workloads.

Integrating with environments lets you compare production workloads to other
versions, in your image repositories or in your other environments.

The following environment monitoring integrations are available:
- [Docker Scout GitHub Action](./environment/_index.md)
- [Generic CLI integration](./environment/cli.md)
For more information about environment integrations, see
[Environments](./environment/_index.md).

---

### Manuals Scout Policy  Index (`content/manuals/scout/policy/_index.md`)

---
title: Policy Evaluation
linkTitle: Policy Evaluation
weight: 70
keywords: scout, supply chain, vulnerabilities, packages, cves, policy
description: |
  Policy Evaluation in Docker Scout lets you define supply chain rules for your
  artifacts and evaluate image compliance
---

Policy Evaluation in Docker Scout lets you define supply chain rules for your
artifacts and evaluate compliance using the `docker scout policy` command. Run
evaluations locally, in CI pipelines, with custom Rego policies, or using OCI
bundles. See [Evaluate policies](./local.md).

## How Policy Evaluation works

When you run `docker scout policy`, the CLI indexes the image into an SBOM and
enriches it with CVE and VEX data. It then evaluates each configured policy
in-process against that data. No data is sent to the Scout service, and an
organization is not required for most use cases.

A policy defines image quality criteria your artifacts should meet. For
example, the **No copyleft licenses** policy flags any image containing
packages distributed under a copyleft license. If an image contains such a
package, it's non-compliant with that policy.

## Policy types

Docker Scout includes the following built-in policy types:

- [Severity-Based Vulnerability](#severity-based-vulnerability)
- [No copyleft licenses](#no-copyleft-licenses)
- [No outdated base images](#no-outdated-base-images)
- [High-Profile Vulnerabilities](#high-profile-vulnerabilities)
- [Supply Chain Attestations](#supply-chain-attestations)
- [Default Non-Root User](#default-non-root-user)
- [Approved Base Images](#approved-base-images)

For configuration options for each policy type, see
[Evaluate policies](./local.md#configure-built-in-policies).



### Severity-Based Vulnerability

The **Severity-Based Vulnerability** policy type checks whether your artifacts
are exposed to known vulnerabilities. By default, it flags critical and high
severity vulnerabilities where a fix version is available.

Configurable parameters include severity levels, a grace period for newly
disclosed CVEs, fixable-only filtering, and package type filtering.

### No copyleft licenses

The **No copyleft licenses** policy type checks whether your images contain
packages distributed under an inappropriate license. You can configure the
list of licenses to flag and add package-level exceptions.

### No outdated base images

The **No outdated base images** policy type checks whether the base images you
use are current. Images are non-compliant if the tag you built from points to
a different digest than what you're using.

Your images need provenance attestations for this policy to evaluate
successfully. For more information, see [No base image data](#no-base-image-data).

### High-Profile Vulnerabilities

The **High-Profile Vulnerabilities** policy type checks whether your images
contain vulnerabilities from a [curated list of widely recognized, high-impact
CVEs](./local.md#default-high-profile-cves), including Log4Shell, Spring4Shell,
and XZ backdoor. The list is updated as new high-profile vulnerabilities are
disclosed.

You can configure which CVEs are considered high-profile and enable tracking
of CISA's Known Exploited Vulnerabilities catalog.

### Supply Chain Attestations

The **Supply Chain Attestations** policy type checks whether your images have
[SBOM](/manuals/build/metadata/attestations/sbom.md) and
[provenance](/manuals/build/metadata/attestations/slsa-provenance.md)
attestations. Images are non-compliant if they lack either attestation type.

To ensure compliance, build with attestations:

```console
$ docker buildx build --provenance=true --sbom=true -t <IMAGE> --push .
```

### Default Non-Root User

The **Default Non-Root User** policy type detects images configured to run as
the `root` user. Use the
[`USER`](/reference/dockerfile.md#user) Dockerfile instruction to set a
non-root default user for the runtime stage.

### Approved Base Images

The **Approved Base Images** policy type ensures the base images you use match
a configurable allowlist of glob patterns. Images are non-compliant if the
base image reference doesn't match any of the allowed patterns.

Your images need provenance attestations for this policy to evaluate
successfully. For more information, see [No base image data](#no-base-image-data).



## No base image data

The **No outdated base images** and **Approved Base Images** policies require
provenance attestations to determine the base image used in your build. Without
them, these policies report **No data**.

To ensure Docker Scout always has base image information, attach provenance
attestations at build time:

```console
$ docker buildx build --provenance=true -t <IMAGE> --push .
```

---

### Manuals Scout Release Notes  Index (`content/manuals/scout/release-notes/_index.md`)

---
build:
  render: never
title: Release notes
weight: 999
---

---

### Manuals Security Access Tokens  Index (`content/manuals/security/access-tokens/_index.md`)

---
title: Access tokens
linkTitle: Access tokens
description: >-
  Choose a personal or organization access token to authenticate to
  Docker Hub.
keywords: >-
  access tokens, personal access tokens, organization access tokens,
  PAT, OAT, Docker Hub, Docker security
weight: 10
grid:
  - title: Personal access tokens
    description: Authenticate the Docker CLI and tools with a token tied to your account.
    icon: lock-closed
    link: /security/access-tokens/personal-access-tokens/
  - title: Organization access tokens
    description: Grant org-owned Hub access to CI/CD and other automation.
    icon: building-office-2
    link: /security/access-tokens/organization-access-tokens/
  - title: Reference
    description: Look up PAT permissions, OAT scopes, and Hub API support.
    icon: list-bullet
    link: /security/access-tokens/reference/
---

Access tokens authenticate to Docker Hub in place of a password. Docker
Hub offers two types: personal access tokens (PATs), tied to your
account, and organization access tokens (OATs), owned by an
organization. Both work with `docker login` and in automation, and you
can deactivate or delete a token at any time without changing a
password.

## Choose a token type

## PATs

Use a PAT for Docker Desktop, for environments governed by
[Image Access Management](/manuals/desktop/enterprise/hardened-desktop/image-access-management.md),
and for other tools that run as you. A PAT is also required to sign in
to the CLI when two-factor authentication (2FA) is turned on or single
sign-on (SSO) is enforced, because the CLI doesn't accept your password
in those cases.

A PAT uses
[one permission level](/manuals/security/access-tokens/reference.md#personal-access-token-permissions)
for every repository the account can access.

## OATs

Use an OAT for production systems that pull images during deployment,
monitoring or backup tools that check repository status or pull images,
third-party services that integrate with your repositories, and scripts
that call the
[Docker Hub API](/manuals/security/access-tokens/reference.md#docker-hub-api).
OATs don't work with Docker Desktop or Image Access Management.

An OAT can be limited to specific repositories and operations, and it
has its own Docker Hub usage limits, separate from individual accounts.
To see scopes, see
[Access token reference](/manuals/security/access-tokens/reference.md).

## OIDC connections

If your automation runs in GitHub Actions, you don't need to store a token.
An [OIDC connection](/manuals/security/authentication/oidc-connections/_index.md)
lets a workflow exchange GitHub's short-lived identity token for Docker
access on each run, so there is no long-lived credential to rotate,
scope, or leak. Organization owners set up OIDC connections, and they
require a Docker Team or Docker Business subscription.

Use an OAT instead when the automation runs outside GitHub Actions, or
when you need a credential that works with `docker login` from any
system.

## Next steps

{{< grid >}}

---

### Manuals Security Authentication  Index (`content/manuals/security/authentication/_index.md`)

---
title: Authentication
linkTitle: Authentication
description: Configure single sign-on, OIDC connections, and two-factor authentication.
keywords: authentication, SSO, OIDC, two-factor authentication, 2FA, Docker security
weight: 20
grid:
  - title: Single sign-on
    description: Authenticate users through your identity provider.
    icon: key
    link: /security/authentication/single-sign-on/
  - title: Two-factor authentication
    description: Add a TOTP security code to an individual Docker account.
    icon: device-phone-mobile
    link: /security/authentication/2fa/
  - title: OIDC connections
    description: Authenticate GitHub Actions with short-lived tokens.
    icon: lock-closed
    link: /security/authentication/oidc-connections/
---

Authentication in Docker Home is how users and workloads prove who they are
before they access Docker products.

Two-factor authentication (2FA) protects an individual account. Single
sign-on (SSO) federates sign-in for an organization or company. OpenID
Connect (OIDC) connections authenticate CI workloads such as GitHub Actions.

## Choose an authentication method

| Method | Who it covers | Who configures it | How authentication works |
| --- | --- | --- | --- |
| Two-factor authentication (2FA) | An individual Docker account | The account holder | Password plus a time-based one-time password (TOTP) from an authenticator app |
| Single sign-on (SSO) | An organization or company | An organization or company owner | Users sign in through the organization's identity provider (IdP) |
| OIDC connections | GitHub Actions and similar workloads | An organization owner or editor | Docker exchanges short-lived tokens issued per workflow run |

SSO requires a Docker Business subscription. OIDC connections require a
Docker Team or Business subscription.

To require Docker Desktop users to sign in as organization members, see
[Enforce sign-in](/manuals/desktop/enterprise/enforce-sign-in/_index.md).
Enforce sign-in is configured in Enterprise, not in this section.

## Next steps

{{< grid >}}

---

### Manuals Security Provisioning  Index (`content/manuals/security/provisioning/_index.md`)

---
description: >-
  Provision Docker organization users with SCIM, JIT, group mapping, or
  auto-provisioning, and map SSO and SAML attributes from your identity
  provider.
keywords: provision users, user provisioning, JIT, SCIM, group mapping,
  auto-provisioning, SSO, SAML, identity provider, dockerOrg, dockerRole,
  dockerTeam, dockerSessionMinutes, Docker Home, admin, security
title: User provisioning overview
linkTitle: Provision
weight: 30
aliases:
  - /security/for-admins/provisioning/
  - /enterprise/security/provisioning/
grid:
  - title: Add and manage domains
    description: Add, verify, and manage domains for auto-provisioning.
    icon: globe-alt
    link: "domain-management/"
  - title: SCIM provisioning
    description: Sync user data between your IdP and Docker with SCIM.
    icon: arrow-path
    link: "scim/"
  - title: Just-in-Time (JIT) provisioning
    description: Create user accounts automatically on first SSO sign-in.
    icon: clock
    link: "just-in-time/"
  - title: Auto-provisioning
    description: Add users whose email addresses match a verified domain.
    icon: user-group
    link: "auto-provisioning/"
---

{{< summary-bar feature_name="SSO" >}}

After you configure single sign-on (SSO), provision users so they can
access your organization through automated account management.

## Provisioning methods

Provisioning automates account creation, updates, and deactivation using
data from your identity provider (IdP). Docker supports the following
methods:

| Provisioning method | When it runs | Lifecycle management | Default setting |
| :--- | :--- | :--- | :--- |
| [System for Cross-domain Identity Management (SCIM)](/manuals/security/provisioning/scim/_index.md) | On the IdP's synchronization schedule or through Provision on Demand | Creates and updates users, synchronizes configured groups, and deprovisions users | Disabled |
| [Just-in-Time (JIT)](/manuals/security/provisioning/just-in-time.md) | When a user signs in through SSO | Creates users and applies attributes from the SSO assertion. It doesn't deprovision users | Enabled when you configure SSO |
| [Auto-provisioning](/manuals/security/provisioning/auto-provisioning.md) | When an existing Docker user signs in or verifies their email, and that address uses a verified domain | Adds the user to the organization. It doesn't create or deprovision accounts | Disabled |

[Group mapping](/manuals/security/provisioning/scim/group-mapping.md) assigns
users to Docker organizations and teams. Use it with SAML SSO or SCIM. You can
also invite users manually when automatic provisioning isn't configured.

## Default provisioning setup

Docker turns on JIT provisioning when you configure an SSO connection. If you
also enable SCIM, Docker recommends choosing one provisioning source to manage
users and attributes. Before configuring SCIM, review
[how SCIM works with JIT](/manuals/security/provisioning/scim/_index.md#choose-how-scim-works-with-jit).

For a domain that belongs to an SSO connection, JIT adds the user instead of
auto-provisioning.

## SSO attributes

Each time a user signs in through SSO, Docker reads attributes from your
IdP to set the user's identity and permissions:

| Attribute | Required | Description |
| :--- | :--- | :--- |
| Email address | Yes | Unique identifier for the user |
| Full name | Yes | User's complete name |
| Groups | No | Group-based access control |
| Docker Org | No | Organization the user belongs to |
| Docker Team | No | Team within the organization |
| Docker Role | No | Permissions in Docker |
| Docker session minutes | No | Session duration, in minutes, before users must re-authenticate with their IdP. Must be a positive integer greater than 0. If omitted, default session timeouts apply |

> [!NOTE]
>
> Default session timeouts apply when Docker session minutes is not
> specified. Docker Desktop sessions expire after 90 days or 30 days of
> inactivity. Docker Hub and Docker Home sessions expire after 24 hours.

## SAML attribute mapping

If your organization uses SAML for SSO, Docker reads these attributes
from the SAML assertion. Identity providers may use different names for
the same attributes.

| SSO attribute | SAML assertion attributes |
| :--- | :--- |
| Email address | `"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier"`, `"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/upn"`, `"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"`, `email` |
| Full name | `"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name"`, `name`, `"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname"`, `"http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname"` |
| Groups (optional) | `"http://schemas.xmlsoap.org/claims/Group"`, `"http://schemas.microsoft.com/ws/2008/06/identity/claims/groups"`, `Groups`, `groups` |
| Docker Org (optional) | `dockerOrg` |
| Docker Team (optional) | `dockerTeam` |
| Docker Role (optional) | `dockerRole` |
| Docker session minutes (optional) | `dockerSessionMinutes`, must be a positive integer greater than 0 |

## Next steps

Choose the provisioning method that fits your organization:

{{< grid >}}

If users get the wrong role or team after you change methods, see
[Troubleshoot provisioning](/manuals/security/provisioning/troubleshoot-provisioning.md).

---

### Manuals Security Roles And Permissions  Index (`content/manuals/security/roles-and-permissions/_index.md`)

---
title: Docker organization roles and permissions
linkTitle: Roles and permissions
description: >-
  Choose core or custom roles to control access to repositories, teams, and
  organization settings
keywords: >-
  Docker organization roles, permissions, core roles, custom roles, Member,
  Editor, Owner, access control, least privilege, Docker Business, security
tags: [admin]
weight: 40
aliases:
  - /admin/organization/roles/
  - /security/for-admins/roles-and-permissions/
  - /docker-hub/roles-and-permissions/
  - /enterprise/security/roles-and-permissions/
grid:
  - title: Core roles
    description: >-
      Compare permissions for the built-in Member, Editor, and Owner roles.
    icon: shield-check
    link: /security/roles-and-permissions/core-roles/
  - title: Custom roles
    description: >-
      Build permission sets that match your organization's access control needs.
    icon: adjustments-horizontal
    link: /security/roles-and-permissions/custom-roles/
  - title: Custom roles permissions
    description: >-
      Review every permission you can assign to a custom role.
    icon: list-bullet
    link: /security/roles-and-permissions/custom-roles/permissions-reference/
---

{{< summary-bar feature_name="General admin" >}}

Roles determine what members can do in your Docker organization. When you
invite a user or create a team, you assign a role that grants permissions
for repositories, teams, and organization settings.

Docker provides two role types. Users and teams get either a core role or a
custom role, but not both.

## Core roles

Core roles are Docker's built-in Member, Editor, and Owner roles. Their
permissions are predefined. Use core roles when Docker's permission sets match
your organization's needs.

## Custom roles

Custom roles are permission sets you build by selecting individual
permissions, such as billing or team management. Use custom roles when you
need a combination that core roles don't offer. For example, you may create a custom role for a billing
administrator or a security auditor, or when you want to grant
least-privilege access.

Custom roles require a Docker Business subscription.

## Roles and team permissions

Roles apply organization-wide. Team permissions apply to specific
repositories. The two systems work together: a user's role sets their
organization-wide access and team membership can extend their access to
individual repositories.

## Next steps

{{< grid >}}

---

### Manuals Subscription Billing Manage  Index (`content/manuals/subscription-billing/manage/_index.md`)

---
title: Manage billing
linkTitle: Manage
description: Manage Docker plans, payment methods, billing details, invoices, and taxes.
keywords: manage plans, billing, payment methods, invoices, taxes, docker subscription
weight: 20
grid:
  - title: Manage plans
    description: Add a new plan, upgrade an active plan, or cancel auto-renewal.
    icon: shopping-cart
    link: /subscription-billing/manage/plans/
  - title: Add or update a payment method
    description: Add or update a payment method for your personal account or organization.
    icon: credit-card
    link: /subscription-billing/manage/payment-method/
  - title: Update billing information
    description: Update billing information for your personal account or organization.
    icon: pencil-square
    link: /subscription-billing/manage/details/
  - title: View billing history
    description: View billing history and download past invoices.
    icon: credit-card
    link: /subscription-billing/manage/history/
  - title: 3D Secure authentication
    description: Learn how 3DS works and how to troubleshoot verification issues.
    icon: wallet
    link: /subscription-billing/manage/3d-secure/
  - title: Taxes
    description: Submit a US tax exemption certificate or add a VAT number.
    icon: document-text
    link: /subscription-billing/manage/tax-certificate/
---

You manage Docker plans, payment methods, invoices, credits, and taxes from
Docker Home. Billing is scoped to the account you
select. To manage billing:

1. Sign in to [Docker Home](https://app.docker.com/), then choose your
   personal account or organization.
1. Select **Billing**.
1. Select the page you want in the sidebar, or stay on **Overview**.

To add or upgrade a plan, see
[Manage plans](/manuals/subscription-billing/manage/plans.md). To compare
plan types, see [Plans](/manuals/subscription-billing/plans/_index.md).

## Overview

When you select **Billing**, you are taken to the **Overview** page, where you review active plans, payment
method, and subscription totals for that account. From there you add
self-serve products, manage a plan you already have, or open another
billing page in the sidebar.

## Invoices

The billing **Invoices** page lists invoices issued when a plan renews or
changes. You can open an invoice, check payment status, and download a
copy. 

## Usage

The billing **Usage** page helps you compare usage-based charges across
billing periods. You can track usage by changing the period, product,
and how the product is metered.

## Costs

The billing **Costs** page aggregates all costs by billing period. It
breaks down charges by resource (the product accruing a charge), the
status of your billing period, and costs to date.

## Credits

The billing **Credits** page shows credits applied to your costs. If you
received a promotional credit, you can see how it applies to your bill
from this page.

## Next steps

{{< grid >}}

---

### Manuals Subscription Billing Plans  Index (`content/manuals/subscription-billing/plans/_index.md`)

---
title: Plans
linkTitle: Plans
description:
  Browse available Docker plans and add-ons for individuals, teams, and
  organizations.
keywords:
  docker products, docker subscriptions, docker core, ai governance, dhi select,
  docker build cloud, gordon plans, product catalog
weight: 10
aliases:
  - /subscription/plans/
  - /subscription/products/
  - /subscription/scale/
  - /subscription/details/
  - /subscription/downgrade/
  - /docker-hub/cancel-downgrade/
  - /docker-hub/billing/downgrade/
grid:
  - title: Docker
    description: Personal and organization plans, including build and runtime minutes.
    link: /subscription-billing/plans/docker/
    icon: credit-card
  - title: Gordon plans
    description: Usage plans that increase your Gordon allowance.
    link: /subscription-billing/plans/gordon/
    icon: /icons/gordon.svg
  - title: Docker Hardened Images (DHI)
    description: Hardened image repositories for organization accounts.
    link: /subscription-billing/plans/dhi/
    icon: /icons/dhi.svg
  - title: AI Governance
    description: Licenses for organization-wide AI policy enforcement.
    link: /subscription-billing/plans/ai-governance/
    icon: shield-check
  - title: Docker Verified Publisher (DVP)
    description: Publisher analytics and reporting plans for organization accounts.
    link: /subscription-billing/plans/docker-verified-publisher/
    icon: check-badge
---

> [!TIP]
> Interested in pricing details? Check out the
> <a href="https://www.docker.com/pricing/" id="dkr_docs_index_pricing" class="link" rel="noopener">pricing page</a> to compare plans.

Docker plans attach to a personal account, an organization, or a specific
product. Personal plans (Docker Personal and Docker Pro) upgrade an individual
account. Organization plans (Docker Team and Docker Business) upgrade an
organization. Product add-ons add usage or features without changing that
account's Docker plan type: Gordon increases usage on a personal account, and
DHI, AI Governance, and DVP add product features on an organization.

Topping up extends a plan's entitlements, such as seats, licenses, or
minutes, without changing the plan type. For the units you can top up, see
[Top up your plan](/manuals/subscription-billing/_index.md#top-up-your-plan).

Each plan page covers usage entitlements, billing cycle, and management
options. To add or upgrade a plan, see
[Manage plans](/manuals/subscription-billing/manage/plans.md).

## Product catalog

{{< grid >}}

---

### Reference Api Ai Governance  Index (`content/reference/api/ai-governance/_index.md`)

---
title: Docker AI Governance API
description: HTTP API reference for managing Docker AI Governance policies and rules programmatically.
keywords: docker sandboxes, governance API, policy API, organization policy, REST API, openapi
build:
  render: never
---

---

### Reference Api Dvp  Index (`content/reference/api/dvp/_index.md`)

---
title: DVP Data API
build:
  render: never
---

---

### Reference Api Engine  Index (`content/reference/api/engine/_index.md`)

---
title: Docker Engine API
description: Learn how you can use Docker Engine API and SDKs in the language of your choice.
keywords: developing, api, Docker Engine API, API versions, SDK versions
aliases:
  - /reference/api/docker_remote_api/
  - /reference/api/docker_remote_api_v1.0/
  - /reference/api/docker_remote_api_v1.1/
  - /reference/api/docker_remote_api_v1.2/
  - /reference/api/docker_remote_api_v1.3/
  - /reference/api/docker_remote_api_v1.4/
  - /reference/api/docker_remote_api_v1.5/
  - /reference/api/docker_remote_api_v1.6/
  - /reference/api/docker_remote_api_v1.7/
  - /reference/api/docker_remote_api_v1.8/
  - /reference/api/docker_remote_api_v1.9/
  - /reference/api/docker_remote_api_v1.10/
  - /reference/api/docker_remote_api_v1.11/
  - /reference/api/docker_remote_api_v1.12/
  - /reference/api/docker_remote_api_v1.13/
  - /reference/api/docker_remote_api_v1.14/
  - /reference/api/docker_remote_api_v1.15/
  - /reference/api/docker_remote_api_v1.16/
  - /reference/api/docker_remote_api_v1.17/
  - /engine/reference/api/
  - /engine/reference/api/docker_remote_api/
  - /engine/api/
---

Docker provides an API for interacting with the Docker daemon (called the Docker
Engine API), as well as SDKs for Go and Python. The SDKs allow you to efficiently build and
scale Docker apps and solutions. If Go or Python don't work
for you, you can use the Docker Engine API directly.

For information about Docker Engine SDKs, see [Develop with Docker Engine SDKs](sdk/_index.md).

The Docker Engine API is a RESTful API accessed by an HTTP client such as `wget` or
`curl`, or the HTTP library which is part of most modern programming languages.

## View the API reference

You can
[view the reference for the latest version of the API](/reference/api/engine/version/v{{% param latest_engine_api_version %}}.md)
or [choose a specific version](/reference/api/engine/#api-version-matrix).

## Versioned API and SDK

The version of the Docker Engine API you should use depends upon the version of
your Docker daemon and Docker client.

A given version of the Docker Engine SDK supports a specific version of the
Docker Engine API, as well as all earlier versions. If breaking changes occur,
they are documented prominently.

> [!NOTE]
>
> The Docker daemon and client don't necessarily need to be the same version
> at all times. However, keep the following in mind.
>
> - If the daemon is newer than the client, the client doesn't know about new
>   features or deprecated API endpoints in the daemon.
>
> - If the client is newer than the daemon, the client can request API
>   endpoints that the daemon doesn't know about.

A new version of the API is released when new features are added. The Docker API
is backward-compatible, so you don't need to update code that uses the API
unless you need to take advantage of new features.

To see the highest and lowest version of the API your Docker daemon and client
support, use `docker version`:

```console
$ docker version
Client: Docker Engine - Community
 Version:           {{% param "docker_ce_version" %}}
 API version:       {{% param "latest_engine_api_version" %}}
 ...

Server: Docker Engine - Community
 Engine:
  Version:          {{% param "docker_ce_version" %}}
  API version:      {{% param "latest_engine_api_version" %}} (minimum version 1.40)
  ...
```

You can specify the API version to use in any of the following ways:

- When using the SDK, use the latest version. At a minimum, use the version
  that incorporates the API version with the features you need.
- When using `curl` directly, specify the version as the first part of the URL.
  For instance, if the endpoint is `/containers/` you can use
  `/v{{% param "latest_engine_api_version" %}}/containers/`.
- To force the Docker CLI or the Docker Engine SDKs to use an older version
  of the API than the version reported by `docker version`, set the
  environment variable `DOCKER_API_VERSION` to the correct version. This works
  on Linux, Windows, and macOS clients.

  {{% apiVersionPrevious.inline %}}
  {{- $version := site.Params.latest_engine_api_version }}
  {{- $parts := strings.Split $version "." }}
  {{- $major := cast.ToInt (index $parts 0) }}
  {{- $minor := cast.ToInt (index $parts 1) }}
  ```console
  $ DOCKER_API_VERSION={{ $major }}.{{ math.Sub $minor 1 }}
  ```
  {{% /apiVersionPrevious.inline %}}

  While the environment variable is set, that version of the API is used, even
  if the Docker daemon supports a newer version. This environment variable
  disables API version negotiation, so you should only use it if you must
  use a specific version of the API, or for debugging purposes.

- The Docker Go SDK allows you to enable API version negotiation, automatically
  selects an API version that's supported by both the client and the Docker Engine
  that's in use.
- For the SDKs, you can also specify the API version programmatically as a
  parameter to the `client` object. See the
  [Go constructor](https://pkg.go.dev/github.com/docker/docker/client#NewClientWithOpts)
  or the
  [Python SDK documentation for `client`](https://docker-py.readthedocs.io/en/stable/client.html).

### Minimum API version

The Docker Engine API server and client support API-version negotiation. If
a client connects to an older version of the Docker Engine, it negotiates
the highest version of the API supported by both the client and daemon,
downgrading to an older version of the API if necessary.

When downgrading to an older API version, features introduced in later API
versions are disabled, and API requests and responses are adjusted for the
API version negotiated.

API version negotiation allows tools that have not been upgraded yet to the
latest API version specification to communicate with newer Docker Engines
(and vice versa), but compatibility is "best effort"; while Docker strives
to provide full compatibility, some functionality may not be available.

### API version matrix

| Docker version | Maximum API version                          | Minimum API version                          | Change log                                                         |
|:---------------|:---------------------------------------------|:---------------------------------------------|:-------------------------------------------------------------------|
| 29.8           | [1.55](/reference/api/engine/version/v1.56/) | [1.40](/reference/api/engine/version/v1.40/) | [changes](/reference/api/engine/version-history/#v156-api-changes) |
| 29.7           | [1.55](/reference/api/engine/version/v1.55/) | [1.40](/reference/api/engine/version/v1.40/) | [changes](/reference/api/engine/version-history/#v155-api-changes) |
| 29.6           | [1.55](/reference/api/engine/version/v1.55/) | [1.40](/reference/api/engine/version/v1.40/) | [changes](/reference/api/engine/version-history/#v155-api-changes) |
| 29.5           | [1.54](/reference/api/engine/version/v1.54/) | [1.40](/reference/api/engine/version/v1.40/) | [changes](/reference/api/engine/version-history/#v154-api-changes) |
| 29.4           | [1.54](/reference/api/engine/version/v1.54/) | [1.40](/reference/api/engine/version/v1.40/) | [changes](/reference/api/engine/version-history/#v154-api-changes) |
| 29.3           | [1.54](/reference/api/engine/version/v1.54/) | [1.40](/reference/api/engine/version/v1.40/) | [changes](/reference/api/engine/version-history/#v154-api-changes) |
| 29.2           | [1.53](/reference/api/engine/version/v1.53/) | [1.44](/reference/api/engine/version/v1.44/) | [changes](/reference/api/engine/version-history/#v153-api-changes) |
| 29.1           | [1.52](/reference/api/engine/version/v1.52/) | [1.44](/reference/api/engine/version/v1.44/) | [changes](/reference/api/engine/version-history/#v152-api-changes) |
| 29.0           | [1.52](/reference/api/engine/version/v1.52/) | [1.44](/reference/api/engine/version/v1.44/) | [changes](/reference/api/engine/version-history/#v152-api-changes) |
| 28.5           | [1.51](/reference/api/engine/version/v1.51/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v151-api-changes) |
| 28.4           | [1.51](/reference/api/engine/version/v1.51/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v151-api-changes) |
| 28.3           | [1.51](/reference/api/engine/version/v1.51/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v151-api-changes) |
| 28.2           | [1.50](/reference/api/engine/version/v1.50/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v150-api-changes) |
| 28.1           | [1.49](/reference/api/engine/version/v1.49/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v149-api-changes) |
| 28.0           | [1.48](/reference/api/engine/version/v1.48/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v148-api-changes) |
| 27.5           | [1.47](/reference/api/engine/version/v1.47/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v147-api-changes) |
| 27.4           | [1.47](/reference/api/engine/version/v1.47/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v147-api-changes) |
| 27.3           | [1.47](/reference/api/engine/version/v1.47/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v147-api-changes) |
| 27.2           | [1.47](/reference/api/engine/version/v1.47/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v147-api-changes) |
| 27.1           | [1.46](/reference/api/engine/version/v1.46/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v146-api-changes) |
| 27.0           | [1.46](/reference/api/engine/version/v1.46/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v146-api-changes) |
| 26.1           | [1.45](/reference/api/engine/version/v1.45/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v145-api-changes) |
| 26.0           | [1.45](/reference/api/engine/version/v1.45/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v145-api-changes) |
| 25.0           | [1.44](/reference/api/engine/version/v1.44/) | 1.24                                         | [changes](/reference/api/engine/version-history/#v144-api-changes) |
| 24.0           | [1.43](/reference/api/engine/version/v1.43/) | 1.12                                         | [changes](/reference/api/engine/version-history/#v143-api-changes) |
| 23.0           | [1.42](/reference/api/engine/version/v1.42/) | 1.12                                         | [changes](/reference/api/engine/version-history/#v142-api-changes) |
| 20.10          | [1.41](/reference/api/engine/version/v1.41/) | 1.12                                         | [changes](/reference/api/engine/version-history/#v141-api-changes) |
| 19.03          | [1.40](/reference/api/engine/version/v1.40/) | 1.12                                         | [changes](/reference/api/engine/version-history/#v140-api-changes) |

### Deprecated API versions

API versions before v1.40 are deprecated and no longer supported by current
versions of the Docker Engine and CLI. You can find archived documentation
for deprecated versions of the API [in the code repository on GitHub](https://github.com/moby/moby/tree/docker-v{{% param "docker_ce_version" %}}/api/docs):

| Docker version | Maximum API version | Minimum API version | Change log                                                         |
|:---------------|:--------------------|:--------------------|:-------------------------------------------------------------------|
| 18.09          | 1.39                | 1.12                | [changes](/reference/api/engine/version-history/#v139-api-changes) |
| 18.06          | 1.38                | 1.12                | [changes](/reference/api/engine/version-history/#v138-api-changes) |
| 18.05          | 1.37                | 1.12                | [changes](/reference/api/engine/version-history/#v137-api-changes) |
| 18.04          | 1.37                | 1.12                | [changes](/reference/api/engine/version-history/#v137-api-changes) |
| 18.03          | 1.37                | 1.12                | [changes](/reference/api/engine/version-history/#v137-api-changes) |
| 18.02          | 1.36                | 1.12                | [changes](/reference/api/engine/version-history/#v136-api-changes) |
| 17.12          | 1.35                | 1.12                | [changes](/reference/api/engine/version-history/#v135-api-changes) |
| 17.11          | 1.34                | 1.12                | [changes](/reference/api/engine/version-history/#v134-api-changes) |
| 17.10          | 1.33                | 1.12                | [changes](/reference/api/engine/version-history/#v133-api-changes) |
| 17.09          | 1.32                | 1.12                | [changes](/reference/api/engine/version-history/#v132-api-changes) |
| 17.07          | 1.31                | 1.12                | [changes](/reference/api/engine/version-history/#v131-api-changes) |
| 17.06          | 1.30                | 1.12                | [changes](/reference/api/engine/version-history/#v130-api-changes) |
| 17.05          | 1.29                | 1.12                | [changes](/reference/api/engine/version-history/#v129-api-changes) |
| 17.04          | 1.28                | 1.12                | [changes](/reference/api/engine/version-history/#v128-api-changes) |
| 17.03.1        | 1.27                | 1.12                | [changes](/reference/api/engine/version-history/#v127-api-changes) |
| 17.03          | 1.26                | 1.12                | [changes](/reference/api/engine/version-history/#v126-api-changes) |
| 1.13.1         | 1.26                | 1.12                | [changes](/reference/api/engine/version-history/#v126-api-changes) |
| 1.13           | 1.25                | 1.12                | [changes](/reference/api/engine/version-history/#v125-api-changes) |
| 1.12           | 1.24                | 1.12                | [changes](/reference/api/engine/version-history/#v124-api-changes) |
| 1.11           | 1.23                | 1.12                | [changes](/reference/api/engine/version-history/#v123-api-changes) |
| 1.10           | 1.22                | 1.12                | [changes](/reference/api/engine/version-history/#v122-api-changes) |
| 1.9            | 1.21                | 1.12                | [changes](/reference/api/engine/version-history/#v121-api-changes) |
| 1.8            | 1.20                | 1.12                | [changes](/reference/api/engine/version-history/#v120-api-changes) |
| 1.7            | 1.19                | 1.0                 | [changes](/reference/api/engine/version-history/#v119-api-changes) |
| 1.6            | 1.18                | 1.0                 | [changes](/reference/api/engine/version-history/#v118-api-changes) |
| 1.5            | 1.17                | 1.0                 | [changes](/reference/api/engine/version-history/#v117-api-changes) |
| 1.4            | 1.16                | 1.0                 | [changes](/reference/api/engine/version-history/#v116-api-changes) |
| 1.3            | 1.15                | 1.0                 | [changes](/reference/api/engine/version-history/#v115-api-changes) |
| 1.2            | 1.14                | 1.0                 | [changes](/reference/api/engine/version-history/#v114-api-changes) |
| 1.1            | 1.13                | 1.0                 | [changes](/reference/api/engine/version-history/#v113-api-changes) |
| 1.0            | 1.12                | 1.0                 | [changes](/reference/api/engine/version-history/#v112-api-changes) |
| 0.12           | 1.12                | 1.0                 | [changes](/reference/api/engine/version-history/#v112-api-changes) |
| 0.11           | 1.11                | 1.0                 | [changes](/reference/api/engine/version-history/#v111-api-changes) |
| 0.10           | 1.10                | 1.0                 | [changes](/reference/api/engine/version-history/#v110-api-changes) |
| 0.9            | 1.10                | 1.0                 | [changes](/reference/api/engine/version-history/#v110-api-changes) |
| 0.8            | 1.9                 | 1.0                 | [changes](/reference/api/engine/version-history/#v19-api-changes)  |
| 0.7.1          | 1.8                 | 1.0                 | [changes](/reference/api/engine/version-history/#v18-api-changes)  |
| 0.7            | 1.7                 | 1.0                 | [changes](/reference/api/engine/version-history/#v17-api-changes)  |
| 0.6.4          | 1.6                 | 1.0                 | [changes](/reference/api/engine/version-history/#v16-api-changes)  |
| 0.6.2          | 1.5                 | 1.0                 | [changes](/reference/api/engine/version-history/#v15-api-changes)  |
| 0.6            | 1.4                 | 1.0                 | [changes](/reference/api/engine/version-history/#v14-api-changes)  |
| 0.5            | 1.3                 | 1.0                 | [changes](/reference/api/engine/version-history/#v13-api-changes)  |
| 0.4.1          | 1.2                 | 1.0                 | [changes](/reference/api/engine/version-history/#v12-api-changes)  |
| 0.3.4          | 1.1                 | 1.0                 | [changes](/reference/api/engine/version-history/#v11-api-changes)  |
| 0.3.3          | 1.0                 | 1.0                 | [changes](/reference/api/engine/version-history/#v10-api-changes)  |
| 0.3.2          | -                   | -                   |                                                                    |
| 0.2            | -                   | -                   |                                                                    |
| 0.1            | -                   | -                   |                                                                    |

---

### Reference Api Extensions Sdk  Index (`content/reference/api/extensions-sdk/_index.md`)

---
title: Extensions API Reference
linkTitle: Extensions API
description: Docker extension API reference
keywords: Docker, extensions, sdk, API, reference
aliases: 
 - /desktop/extensions-sdk/dev/api/reference/README/
 - /extensions/extensions-sdk/dev/api/reference/README/
---

## Dashboard interfaces

- [Host](Host.md)
- [NavigationIntents](NavigationIntents.md)
- [Toast](Toast.md)

## Other interfaces

- [ExecResultV0](ExecResultV0.md)
- [RequestConfigV0](RequestConfigV0.md)
- [BackendV0](BackendV0.md)
- [OpenDialogResult](OpenDialogResult.md)
- [Dialog](Dialog.md)
- [Docker](Docker.md)
- [DockerCommand](DockerCommand.md)
- [ExecOptions](ExecOptions.md)
- [SpawnOptions](SpawnOptions.md)
- [Exec](Exec.md)
- [ExecProcess](ExecProcess.md)
- [ExecStreamOptions](ExecStreamOptions.md)
- [ExecResult](ExecResult.md)
- [RawExecResult](RawExecResult.md)
- [Extension](Extension.md)
- [DesktopUI](DesktopUI.md)
- [ExtensionVM](ExtensionVM.md)
- [ExtensionHost](ExtensionHost.md)
- [ExtensionCli](ExtensionCli.md)
- [HttpService](HttpService.md)
- [RequestConfig](RequestConfig.md)
- [ServiceError](ServiceError.md)
- [DockerDesktopClient](DockerDesktopClient.md)

---

### Reference Api Hub  Index (`content/reference/api/hub/_index.md`)

---
title: Docker Hub API
build:
  render: never
---

---

### Reference Api Registry  Index (`content/reference/api/registry/_index.md`)

---
title: Registry API
build:
  render: never
---

---

### Reference Api Sandboxes  Index (`content/reference/api/sandboxes/_index.md`)

---
title: Docker Sandboxes API
description: HTTP API reference for Docker Cloud Sandboxes.
keywords: Docker Sandboxes, API reference, OpenAPI
build:
  render: never
---

---

### Manuals Accounts Organization Manage  Index (`content/manuals/accounts/organization/manage/_index.md`)

---
title: Manage your organization
linkTitle: Manage
weight: 20
description: Learn how to manage your Docker organization, including members, teams, licenses, seats, product access, and settings.
keywords: manage organization, members, teams, licenses, seats, product access, organization management, docker home, organization settings, deactivate organization
grid:
  - title: Members
    description: Invite, manage, and assign roles to your organization members.
    icon: user-plus
    link: /accounts/organization/manage/members/
  - title: Teams
    description: Create teams and manage repository access for groups of members.
    icon: user-group
    link: /accounts/organization/manage/manage-a-team/
  - title: Products
    description: Manage access and view usage for Docker products across your organization.
    icon: squares-2x2
    link: /accounts/organization/manage/manage-products/
  - title: Licenses
    description: View your license inventory and assign licenses to teams or individual members.
    icon: key
    link: /accounts/organization/manage/manage-licenses/
  - title: Seats
    description: Add or remove seats for Docker Team and Business subscriptions.
    icon: user-circle
    link: /accounts/organization/manage/manage-seats/
  - title: Information
    description: Update your organization's general information and settings.
    icon: pencil-square
    link: /accounts/organization/manage/general-settings/
  - title: Deactivation
    description: Deactivate an organization after completing the required steps.
    icon: minus-circle
    link: /accounts/organization/manage/deactivate-account/
  - title: Security
    description: Configure single sign-on, provisioning, and access management.
    icon: shield-check
    link: /security/
  - title: Billing
    description: Manage payment methods and view billing history.
    icon: credit-card
    link: /subscription-billing/
aliases:
  - /admin/organization/manage/
---

As an organization owner, you manage your organization's membership, access,
product usage, and settings. You can invite members, group them into teams,
assign or revoke licenses and seats, change access to Docker products, update
organization information, and deactivate the organization.

## Managing your organization

You manage your organization from [Docker Home](https://app.docker.com) and
must be assigned the
[organization owner role](/manuals/security/roles-and-permissions/_index.md).

## Seats and licenses

Seats and licenses both control access, but they apply to different kinds of
plans. The following table summarizes the difference.

| Entitlement | What it grants                                          | Applies to                                       | Managed from                 |
| ----------- | ------------------------------------------------------- | ------------------------------------------------ | ---------------------------- |
| Seat        | Membership in your Docker Team or Business subscription | Docker Core subscription                         | Billing                      |
| License     | Access to a specific product or add-on                  | AI Governance, Docker Offload, and other add-ons | Licenses, Teams, and Members |

For details, see [Seats](/manuals/accounts/organization/manage/manage-seats.md)
and [Manage licenses](/manuals/accounts/organization/manage/manage-licenses.md).

## Next steps

Explore the following sections to manage your organization.

{{< grid >}}

---

### Manuals Accounts Organization Setup  Index (`content/manuals/accounts/organization/setup/_index.md`)

---
title: Set up a Docker organization
linkTitle: Setup
weight: 10
description: >
  Create, convert, or onboard a Docker organization under one namespace and
  subscription.
keywords:
  - Docker organization setup
  - create organization
  - onboard organization
  - convert Docker account
  - organization namespace
  - Docker Home
grid:
  - title: Create your organization
    description: Choose a new namespace and subscription.
    icon: building-storefront
    link: /accounts/organization/setup/orgs/
  - title: Convert your account
    description: Keep an existing Docker ID as the organization namespace.
    icon: arrows-right-left
    link: /accounts/organization/setup/convert-account/
  - title: Onboard your organization
    description: Invite members and configure sign-in.
    icon: magnifying-glass-plus
    link: /accounts/organization/setup/onboard/
  - title: Manage your organization
    description: Add members, teams, licenses, and seats after setup.
    icon: user-group
    link: /accounts/organization/manage/
  - title: Security
    description: Configure single sign-on, provisioning, and access management.
    icon: shield-check
    link: /security/
aliases:
  - /admin/organization/setup/
---

An organization groups members and teams under one namespace and one
subscription. Anyone with a [Docker ID](/manuals/accounts/_index.md) can
create an organization or convert an individual account into one.

You start by creating a new organization or converting an individual
account. After creating or converting, you can onboard your organization.

## Names versus namespaces

When you create an organization, you set two values:

- Organization namespace is the permanent, unique identifier for your
  organization. It becomes the first part of every image name you push, as
  in `namespace/image:tag`. You can't change it after you create the
  organization.
  - Docker IDs and organization namespaces must be unique.
  - If a Docker ID is `acme`, no organization can use `acme` as its
    namespace.
- Organization name is the display name shown on your organization's
  Docker profile. You can change it at any time. See
  [Change organization information](/manuals/accounts/organization/manage/general-settings.md).

## Choose how to set up

The difference between creating and converting is what happens to your
existing repositories.

- Create an organization: Choose a new namespace. Your existing
  repositories stay under your personal Docker ID.
- Convert your account: Your Docker ID becomes the organization’s
  namespace. Your repositories and image names stay the same, so anyone
  pulling your images can keep using their existing image references.

## Next steps

{{< grid >}}

---

### Manuals Ai Gordon Concepts  Index (`content/manuals/ai/gordon/concepts/_index.md`)

---
build:
  render: never
title: Concepts
weight: 20
---

---

### Manuals Ai Gordon How To  Index (`content/manuals/ai/gordon/how-to/_index.md`)

---
build:
  render: never
title: How-to guides
weight: 30
---

---

### Manuals Ai Sandboxes Api Cookbook  Index (`content/manuals/ai/sandboxes-api/cookbook/_index.md`)

---
title: Docker Sandboxes SDK cookbook
linkTitle: Cookbook
description: Build agent workflows with the Docker Sandboxes SDK for TypeScript.
keywords: cloud sandboxes, sandboxes sdk, typescript, agent kits
weight: 60
params:
  recipeCatalog: true
  sidebar:
    activeChildrenOnly: true
---

Use these recipes to add file transfers, processes, storage, and other sandbox
operations to your application. Each recipe shows the relevant SDK calls and
an expandable complete TypeScript example.

Start with [Get started](../get-started.md) to run your first sandbox, or
[install the SDK](../install.md) to use these examples in an existing project.
For HTTP operations and request fields, see the
[API reference](/reference/api/sandboxes/latest/).

## Get started

Authenticate and launch a kit before exploring individual SDK operations.

{{< recipe-list group="Get started" >}}

## Working in a sandbox

Use a running sandbox for commands, project files, and web applications.

{{< recipe-list group="Working in a sandbox" >}}

## Packaging and state

Keep an environment or its state for later work.

{{< recipe-list group="Packaging and state" >}}

## Security and policy

Give agents the access they need without embedding credentials in application code.

{{< recipe-list group="Security and policy" >}}

## Connect and configure

Choose a different image, control lifetime, or connect additional storage and clients.

{{< recipe-list group="Connect and configure" >}}

## Requests and responses

Handle request options and failures deliberately.

{{< recipe-list group="Requests and responses" >}}

## Long-running work

Continue work across lost connections or coordinate several sandboxes.

{{< recipe-list group="Long-running work" >}}

---

### Manuals Ai Sandboxes Agents  Index (`content/manuals/ai/sandboxes/agents/_index.md`)

---
title: Supported agents
linkTitle: Agents
weight: 40
description: AI coding agents supported by Docker Sandboxes.
keywords: docker sandboxes, ai agents, claude code, codex, cursor, devin, gemini
---

Docker Sandboxes runs the following agents in local sandboxes:

- [Claude Code](claude-code/)
- [Codex](codex/)
- [Copilot](copilot/)
- [Cursor](cursor/)
- [Devin](devin/)
- [Docker Agent](docker-agent/)
- [Droid](droid/)
- [Gemini](gemini/)
- [Kiro](kiro/)
- [OpenCode](opencode/)
- [Shell](shell/) — agent-less sandbox for manual setup or testing

Want to pre-install tools or customize an agent's environment?
See [Customize](../customize/).

---

### Manuals Ai Sandboxes Cloud  Index (`content/manuals/ai/sandboxes/cloud/_index.md`)

---
title: Cloud sandboxes
description: Run Docker Sandboxes on Docker-managed cloud infrastructure and understand the cloud-specific command, storage, and billing model.
keywords: docker sandboxes, cloud sandboxes, sbx cloud, ai agents, agentic platform
weight: 35
---

Cloud sandboxes run AI agents on Docker-managed infrastructure instead of your
local machine. Use them when you need an isolated environment that doesn't
depend on the compute resources or virtualization support of your host.

Cloud sandboxes use the same `sbx` CLI as local sandboxes. Add the global
`--cloud` flag to send a supported command to the Cloud Sandboxes API:

```console
$ sbx --cloud ls
```

Cloud and local sandboxes have separate state and different capabilities. A
cloud sandbox can't mount a host workspace or use host hardware, and its
secrets, network policy, ports, and lifecycle are managed in the cloud. See
[Local and cloud differences](local-vs-cloud.md) before adapting a local
workflow.

## Prerequisites

To use cloud sandboxes, you need:

- The [`sbx` CLI](../install.md), version 0.45.0 or later
- An active [Docker Agentic Platform subscription](/manuals/agentic-platform/signup.md#activate-cloud-access)

Follow [Signup and billing](/manuals/agentic-platform/signup.md) to activate
cloud access and review compute charges. Then return here to sign in from the
CLI and configure your agent.

### Sign in from the CLI

Sign in with the same Docker account you used to subscribe:

```console
$ sbx login
```

For CI and other environments without a browser, sign in with a Docker
Personal Access Token (PAT) for the subscribed account:

```console
$ echo "$DOCKER_PAT" | sbx login --username <your-docker-id> --password-stdin
```

For PAT setup instructions, see [CI and headless use](../workflows/automation.md).

Check cloud connectivity and account access:

```console
$ sbx --cloud diagnose
```

If the check reports that your account doesn't have access, follow
[Check account access](/manuals/agentic-platform/signup.md#check-account-access).

## Get started

Credentials configured for local sandboxes aren't available to cloud
sandboxes. Configure a cloud credential for your agent before launching it.
For Claude Code, store an Anthropic API key:

```console
$ sbx --cloud secret set anthropic
```

See [Authenticate cloud agents](credentials.md) for other agents and credential
options.

Cloud sandboxes expire after one hour by default. On expiration, the service
stops sandboxes that can be resumed and deletes the rest. Check the timeout
action before relying on a sandbox to retain your work. See
[Configure expiration](usage.md#configure-expiration).

Create a sandbox without attaching, allowing access to GitHub for this example:

```console
$ sbx --cloud create --name cloud-project --allow-network github.com:443 claude
```

Cloud sandboxes don't accept a local workspace path. Clone the public
[Welcome to Docker repository](https://github.com/docker/welcome-to-docker)
inside the sandbox:

```console
$ sbx --cloud exec cloud-project git clone \
    https://github.com/docker/welcome-to-docker.git /home/agent/workspace/project
```

Attach to the agent:

```console
$ sbx --cloud attach cloud-project
```

Ask Claude to inspect `/home/agent/workspace/project` and write a description
of the application to `/home/agent/workspace/review.md`. When the file is ready,
press `Ctrl+\` to detach and leave the agent running.

Copy the result to your machine:

```console
$ sbx --cloud cp cloud-project:/home/agent/workspace/review.md ./review.md
```

Read the result, then remove the sandbox when you're finished:

```console
$ sbx --cloud rm cloud-project
```

Removal deletes files stored only in the sandbox. For your own projects, see
[Transfer files](usage.md#transfer-files) and
[Authenticate cloud agents](credentials.md) before cloning private repositories.

## Learn more

- [Signup and billing](/manuals/agentic-platform/signup.md) covers activation
  and compute charges
- [Local and cloud differences](local-vs-cloud.md) compares the two execution
  environments
- [Use cloud sandboxes](usage.md) covers creation, files, ports, and lifecycle
- [Authenticate cloud agents](credentials.md) covers cloud-specific secrets,
  API keys, and OAuth
- [Manage cloud network policy](network-policy.md) covers account-level and
  sandbox-level network access
- [Move a sandbox](move.md) explains filesystem transfers between local and
  cloud environments
- [`sbx` CLI reference](/reference/cli/sbx/) lists commands and options

---

### Manuals Ai Sandboxes Configuration  Index (`content/manuals/ai/sandboxes/configuration/_index.md`)

---
title: Configure Docker Sandboxes
linkTitle: Configuration
weight: 60
description: Configure Docker Sandboxes settings, credentials, models, project environments, GPU passthrough, registry mirrors, and upstream proxies.
keywords: docker sandboxes, sbx, configuration, settings, credentials, models, environment files, gpu passthrough, registry mirror, upstream proxy
---

Configure credentials and how Docker Sandboxes run for a project, host, or
network environment. These settings control sandbox creation, authentication,
and connectivity. To change the tools and agent configuration inside a
sandbox, see [Customize](../customize/).

- [Settings](settings.md) lists host-level settings, environment variable
  equivalents, and commands to inspect and change values.
- [Credentials](credentials.md) configures API keys, authentication
  credentials, and registry access for sandboxed agents.
- [Models](models.md) selects local models, hosted providers, or custom
  inference endpoints for sandboxed agents.
- [Environment files](environment-files.md) declare reusable project
  configuration in `sbxenv.yaml` for local or cloud sandboxes.
- [GPU passthrough](gpu-passthrough.md) configures a Linux host and sandbox for
  NVIDIA GPU workloads.
- [Registry mirror](registry-mirror.md) routes Docker Hub template, kit, and
  in-sandbox Docker image pulls through an organization's registry mirror.
- [Upstream proxy](upstream-proxy.md) routes sandbox and daemon traffic through
  an operating system or corporate proxy.

---

### Manuals Ai Sandboxes Customize  Index (`content/manuals/ai/sandboxes/customize/_index.md`)

---
title: Kits
description: Use sandbox kits and share environments as kit sets composed from workloads and mixins.
keywords: sandboxes, sbx, kits, v3, workloads, mixins
weight: 90
linkTitle: Kits
aliases:
  - /ai/sandboxes/agents/custom-environments/
---

{{< summary-bar feature_name="Docker Sandboxes sbx" >}}

Kits let you shape a sandbox around the way you work. Use a custom base image,
add the tools your project needs, and give your agent instructions for using
them. You also control which services the sandbox can access, how it
authenticates, and what runs when the sandbox starts.

A kit can define the whole environment or add something to an existing one,
such as a toolchain or your team's shared configuration. Package those choices
once, then reuse them across projects and share them with your team.

Docker recommends v3 kits. This section covers v3. For the supported v2
format, see [Kits v2](/manuals/ai/sandboxes/customize/kits-v2.md).

## What is a kit?

A kit packages software and configuration for a sandbox. A YAML file, called
its descriptor, tells Docker Sandboxes what the kit needs: network access,
credentials, setup commands, or instructions for the agent. You publish the
kit as a container image containing its files and descriptor.

You identify a published kit by its container image reference, such as
`docker.io/docker/sbx-kit-claude:2.1.267`. When you use the kit, `sbx`
prepares its files and applies its settings. You can use one kit for a
complete environment or combine kits that contribute different parts.

## What kits can do

Use kits to:

- Package a custom agent, or configure an existing agent for your team's
  projects.
- Include the tools the agent needs, such as linters, language runtimes,
  test runners, and compilers.
- Share linter rules, editor settings, helper scripts, and reference material.
  Give the agent instructions and skills for using them.
- Connect the agent to services through network rules and credentials,
  including internal APIs and private package registries.
- Initialize each sandbox and run supporting services when it starts, such
  as a development server for previewing the agent's work.

## Workloads and mixins

Kits have two roles in a sandbox: a workload supplies the base environment
and launch command, and mixins add tools or behavior to it.

| Kind | What it supplies | How you use it |
| --- | --- | --- |
| `workload` | The environment and command to run, such as an agent or a shell | Pass it to `sbx run` or `sbx create` |
| `mixin` | Additional tools, configuration, or runtime behavior | Add it with `--kit` |

For example, this command runs a workload with a mixin:

```console
$ sbx run docker.io/docker/sbx-kit-claude:2.1.267 --kit docker.io/sbx/playwright:1.61.1
```

The Claude Code workload starts the agent, and the Playwright mixin adds
browser-testing tools.

## Kit sets

A kit set combines kits into a single kit that you can publish and reuse.
Use it to package a workload with the mixins you need, so you and your team
can run the environment from one reference.

The set specifies which kits and versions to combine. It can also add setup
commands, agent instructions, network access, and other settings for the
combined environment.

If the set includes a workload, you run the published kit with `sbx run`.
If it contains only mixins, you add it to a workload with `--kit`.

To share a combination without publishing another kit, list the workload and
mixins in a [sandbox environment file](/manuals/ai/sandboxes/configuration/environment-files.md).
Docker Sandboxes composes those kits when it creates the sandbox. An environment
file can also configure the workspace and host resources. Choose a set when you
want one published reference with a fixed list of components; the set records
their image digests when you build it. You can also use a set in an environment
file.

See [Use kits](/manuals/ai/sandboxes/customize/use-kits.md) for how to run kits
and add mixins. To customize and publish your own combination, see
[Compose a kit set](/manuals/ai/sandboxes/customize/author/kit-sets.md).

## Version compatibility

V3 requires `sbx` v0.45 or later. Every kit in a v3 sandbox must use v3:
select a v3 workload and add only v3 mixins.

Built-in agent names such as `claude` and `codex` select v2 kits, so
`sbx run claude --kit ./some-v3-mixin` fails. To use that mixin, choose a
[v3 workload](/manuals/ai/sandboxes/customize/use-kits.md#published-v3-workloads)
by its image, local path, or Git reference.

A kit's capabilities can require a later release or a local sandbox. See
[Kit capability support](/manuals/ai/sandboxes/customize/author/capabilities.md)
for details. V2 remains supported and is not deprecated.

## Choose your next step

- [Use kits](/manuals/ai/sandboxes/customize/use-kits.md) to run a published environment or combine
  a workload with mixins.
- [Author kits](/manuals/ai/sandboxes/customize/author/_index.md) to build an agent environment,
  package a tool, or combine kits into a set to share with your team.
- Explore the [sandbox-kit-spec repository](https://github.com/docker/sandbox-kit-spec)
  for the authoritative v3 specification, build frontend, and examples.

To save an environment you've configured inside a sandbox,
see [Save a sandbox as a template](/manuals/ai/sandboxes/usage.md#saving-a-sandbox-as-a-template).

---

### Manuals Ai Sandboxes Governance  Index (`content/manuals/ai/sandboxes/governance/_index.md`)

---
title: Governance
weight: 120
description: Control what sandboxes can access, from local developer rules to org-wide enforcement.
keywords: docker sandboxes, governance, policy, network access, filesystem access, mcp policy, organization policy
---

The governance described here applies to local sandboxes. Cloud sandboxes
use separate network policy configuration. See
[Cloud network policy](../cloud/network-policy.md) for cloud controls.

Sandbox governance covers the policy system that controls what sandboxes can
access over the network, on the filesystem, and through MCP. For MCP setup and
server registration, see [MCP gateway](../mcp-gateway.md). Governance operates
at two layers:

**Local policy** is configured per machine using the `sbx policy` CLI. It
lets individual developers customize which domains their sandboxes can reach.
See [Local policy](access-controls/local.md).

**Organization policy** is configured centrally in Docker Home. Network and
filesystem policies can also be managed via the
[Governance API](/reference/api/ai-governance/). Controls defined at the org
level apply uniformly across every local sandbox in the organization. Organization
governance can also include MCP policies for sandbox MCP activity. When
organization governance is active, only organization allow rules grant access:
local `sbx policy` allow rules are no longer evaluated, while local deny rules
still apply on top. See
[Organization policies](access-controls/organization.md).

Alongside this access-control policy, admins can require developers to sign in
as members of their organization before using sandboxes at all.
[Sign-in enforcement](monitor-and-enforce/sign-in-enforcement.md) is deployed
through endpoint management and ensures developers can't bypass organization
policy by using a personal account.

> [!NOTE]
> Organization governance is available on a separate paid subscription.
> [Contact Docker Sales](https://www.docker.com/products/ai-governance/#contact-sales)
> to request access.

## Learn more

Start with [Policy concepts](concepts.md) for the resource model, rule syntax,
MCP policy basics, evaluation, and precedence.

### Access controls

- [Local policy](access-controls/local.md): configure network rules on your
  machine with the `sbx policy` CLI.
- [Organization policies](access-controls/organization.md): centrally manage
  sandbox policies across your organization.
- [Network access policies](access-controls/network.md): control outbound network
  access from sandboxes, by host or by HTTP method and path.
- [Filesystem access policies](access-controls/filesystem.md): control which
  host paths sandboxes can mount as workspaces.
- [MCP access policies](access-controls/mcp.md): control MCP server registration,
  tool calls, resources, prompts, and approval gates.

### Monitor and enforce

- [Monitoring policies](monitor-and-enforce/monitoring.md): inspect active
  rules and monitor sandbox network traffic with `sbx policy ls` and
  `sbx policy log`.
- [Audit logs](audit/): view, configure, export, and collect governance audit
  records.
- [Sign-in enforcement](monitor-and-enforce/sign-in-enforcement.md): require
  developers to sign in as organization members, enforced through endpoint
  management.

### Reference

- [AI Governance API](/reference/api/ai-governance/): manage network and
  filesystem org policies programmatically.
- [MCP policy reference](reference/mcp-policy.md): look up Docker MCP policy
  actions, resources, attributes, context fields, and approval behavior.

---

### Manuals Ai Sandboxes Integrations  Index (`content/manuals/ai/sandboxes/integrations/_index.md`)

---
title: Editor and app integrations
linkTitle: Integrations
weight: 70
description: Connect editors and desktop apps to a Docker Sandbox over SSH.
keywords: docker sandboxes, ssh, integrations, vs code, cursor, remote development, sbx
---

{{< summary-bar feature_name="Docker Sandboxes SSH" >}}

These integrations use local sandbox SSH access. Cloud sandboxes use a
different SSH configuration and address: see
[Connect with SSH](../cloud/usage.md#connect-with-ssh).

You can connect an external editor or desktop app to a running sandbox over
SSH. This lets you use the tools you already know — VS Code, Cursor, Claude
Desktop, and others — while your code runs, builds, and executes inside the
isolated sandbox instead of on your host.

Each sandbox is reachable at `<name>.sbx`, where `<name>` is the sandbox name.
Once SSH is set up, `<name>.sbx` behaves like any other SSH host, so any tool
that supports remote development over SSH can connect to it.

## Prerequisites

- The `sbx` CLI installed and signed in. See [Get started](../get-started.md).
- An SSH client. macOS and most Linux distributions include OpenSSH. On
  Windows, install the OpenSSH client.
- The editor or app you want to connect, with its remote-over-SSH support
  installed.

## Enable SSH access

Run the SSH setup command once:

```console
$ sbx setup ssh
```

The command starts the Docker Sandboxes daemon if needed and configures your
SSH client. You can re-run it at any time.

## Set up desktop app connections

On macOS and Windows, Docker Sandboxes can add connections to ChatGPT and Claude
Desktop that create a dedicated sandbox on first use. This workflow uses a
workspace inside the sandbox. To work directly on a mounted host project,
[create a sandbox](#create-or-identify-a-sandbox) and connect to its hostname
instead.

This setup requires Docker Sandboxes v0.48.0 or later. Launch each installed
app at least once, then quit the apps before running:

```console
$ sbx setup ssh --auto-create
```

Setup adds the following connections to the apps and configures their SSH
hostnames. It creates the sandboxes when the connections are used.

| App | Connection name | SSH hostname | Sandbox name |
| --- | --- | --- | --- |
| ChatGPT | Docker Sandbox (Codex) | `codex.sbx` | `ssh-codex` |
| Claude Desktop | Docker Sandbox (Claude) | `claude.sbx` | `ssh-claude` |

Reopen each app and select its added connection. Connecting for the first time
creates the corresponding sandbox. Later connections reuse that sandbox and
its files, starting it if it is stopped.

These sandboxes have no host workspace mounted. Clone your project inside the
sandbox and select its directory in the app's remote folder picker. Changes
stay inside the sandbox until you push them to a remote repository or copy
them out.

Removing the sandbox with `sbx rm` leaves the app connection available. The
next connection creates a replacement sandbox without restoring deleted files.

If setup reports that an app is running, quit it and rerun `sbx setup ssh`.
Setup also provides sign-in guidance if Docker or agent authentication is
missing.

### Remove desktop app connections

Quit ChatGPT and Claude Desktop, then run:

```console
$ sbx setup ssh remove
```

This removes the managed SSH config and app connections. It leaves existing
sandboxes running or stopped as they were. Remove the sandboxes separately
with `sbx rm` if you no longer need them.

## Create or identify a sandbox

To connect using a sandbox name as `<name>.sbx`, create the sandbox first.
ChatGPT and Claude Desktop also support [creating a dedicated sandbox on first connection](#set-up-desktop-app-connections).
To create a named shell sandbox for the current directory:

```console
$ sbx create --name demo shell .
```

To identify an existing sandbox, list your sandboxes:

```console
$ sbx ls
```

## Connect to a sandbox over SSH

Use the sandbox name with the `.sbx` suffix. For example, to connect to a
sandbox named `demo`:

```console
$ ssh demo.sbx
```

## Select the workspace folder

Connecting an app to a sandbox selects the remote environment, but it might not
open the primary workspace automatically. The initial folder depends on the
client. A remote folder picker might open at the sandbox user's home directory,
`/home/agent`, while an interactive `ssh` shell might start in
`/home/agent/workspace`. Select the intended folder explicitly instead of
relying on the initial location.

For a sandbox with a primary workspace, each workspace path appears inside the
sandbox at the same absolute path as on the host. For example, if you pass
`/Users/bob/src/my-project`, select that path in the remote folder picker. For
a mountless sandbox that uses a Docker-provided agent template, select
`/home/agent/workspace`.

## Connect a specific tool

- [VS Code](vscode.md)
- [Cursor](cursor.md)
- [Claude Desktop](claude-desktop.md)
- [ChatGPT](chatgpt.md)
- [T3 Code](t3-code.md)

## How SSH connections work

### Managed SSH configuration

`sbx setup ssh` writes a managed block to your SSH config: `~/.ssh/config` on
macOS and Linux, or `%USERPROFILE%\.ssh\config` on Windows. The block is similar
to the following:

```text
# >>> docker sandboxes (managed) >>>
Host *.sbx
    User _default_user_
    ProxyCommand "sbx" ssh proxy %n
    IdentityAgent none
    IdentityFile /dev/null
    IdentitiesOnly yes
    ControlMaster no
    ControlPath none
    UserKnownHostsFile "~/.ssh/sbx_known_hosts"
    KnownHostsCommand "sbx" ssh known-hosts %H
    StrictHostKeyChecking yes
# <<< docker sandboxes (managed) <<<
```

You don't edit this block by hand. Its key entries work as follows:

- `Host *.sbx` maps sandbox hostnames to the sandbox daemon. Application host
  pickers don't discover individual sandbox names from this wildcard, so enter
  the hostname, such as `demo.sbx`, manually when you configure an integration.
- `User _default_user_` tells the daemon to use the sandbox image's default
  user, so your host username is never sent.

### Connection and authentication

Connections don't use a network port or an SSH key:

- A `ProxyCommand` relays the SSH stream to the daemon over its local socket
  (a Unix domain socket on macOS and Linux, a named pipe on Windows).
- The daemon accepts the connection only while you have an active Docker login.
  Authentication is tied to your login, not to a stored key.
- The host key is verified on every connection, so a rotated daemon key never
  triggers a host-key mismatch.

Because SSH terminates at the daemon, no SSH server runs inside the sandbox.
For ordinary `<name>.sbx` connections, create the sandbox first. The
[desktop app connections](#set-up-desktop-app-connections) create their dedicated
sandboxes on first use. If a sandbox is stopped, connecting starts it
automatically.

### Environment variables

SSH connections don't forward client environment variables into the sandbox.
The daemon acknowledges SSH environment requests for compatibility but ignores
their names and values.

### Port forwarding

SSH clients can use local port forwarding to make a service listening on the
sandbox's loopback interface available on the host. For example, a remote
development client can map `127.0.0.1:4321` in the sandbox to
`127.0.0.1:55565` on the host, choosing an available host port automatically.
Traffic passes through the SSH connection instead of a published Docker port.

The sandbox daemon accepts forwarded connections only to loopback addresses in
the sandbox, including `localhost`, `127.0.0.0/8`, and `::1`. The SSH client
chooses the bind address for the listener on the host. A listener bound to
`127.0.0.1` or `::1` is reachable only from the host. A client configured to
bind to a non-loopback address can make the forwarded service reachable from
other machines, subject to the host's network and firewall configuration.

---

### Manuals Ai Sandboxes Security  Index (`content/manuals/ai/sandboxes/security/_index.md`)

---
title: Security model
linkTitle: Security model
weight: 110
description: Trust boundaries, isolation layers, and security properties of Docker Sandboxes.
keywords: docker sandboxes, security model, isolation, trust boundaries, microVM
---

{{% include "sandboxes-local-scope.md" %}}

Docker Sandboxes run AI agents in microVMs so they can execute code, install
packages, and use tools without accessing host resources beyond those you
share. Multiple isolation layers protect your host system.

## Trust boundaries

The primary trust boundary is the microVM. The agent has full control inside
the VM, including sudo access. The VM boundary prevents the agent from reaching
anything on your host except what is explicitly shared.

What crosses the boundary into the VM:

- **Host workspace directory:** shared when you pass a workspace path or use
  `sbx run`, which defaults to the current directory. A direct mount is
  read-write, so the agent edits your working tree in place. With
  [`--clone`](../usage.md#clone-mode), your repository is mounted read-only and
  the agent works on a private clone. A mountless sandbox doesn't share a host
  workspace.
- **Credentials:** the host-side proxy injects authentication headers into
  outbound HTTP requests. The raw credential values never enter the VM.
- **Network access:** outbound TCP connections to destinations allowed by
  [network policy](defaults/) are proxied through the host.
- Shared agent skills: sandboxes created for supported agents mount a
  persistent host-side store read-only by default at the agent's skills
  directory. Use `--skills` or
  [`skills.defaultMode`](../configuration/settings.md#skillsdefaultmode)
  to choose another mode at
  creation. Existing sandboxes retain their mounts until recreated.
- **MCP gateway traffic:** supported agents connect to a host-side MCP gateway
  endpoint. The gateway brokers access to registered MCP servers.

What crosses the boundary back to the host:

- **Workspace file changes:** visible on your host in real time when you use a
  direct mount.
- **Outbound TCP connections:** sent to allowed destinations through the host
  proxy.
- Shared skill changes: sandboxes with `readwrite` access can write to the
  host-side store. These changes are visible to other sandboxes that share it.

Outside the workspace and shared skills store, the agent cannot access your
host filesystem. It also cannot access your host Docker daemon, your host
network directly, or any destination not allowed by network policy. Sandboxes
cannot communicate directly over the network. Outbound UDP is blocked unless
you turn on the [experimental UDP feature](../governance/access-controls/local.md#allow-outbound-udp)
and allow it through network policy. ICMP is blocked.

MCP servers are an explicit integration point. Remote MCP servers run outside
Docker Sandboxes, and local stdio MCP servers run on the host, not inside the
sandbox VM. An agent can invoke the tools those servers expose through the MCP
gateway, subject to MCP policies when organization governance is active. Treat
local MCP servers as trusted host integrations.

### MicroVM isolation

This topology shows what is private to the microVM, what is explicitly mounted,
and which host resources remain outside the agent's reach.

{{< interactive-diagram src="../diagrams/trust-boundary-topology.yaml" >}}

To follow an outbound request through network policy and credential injection,
see [Architecture](../architecture.md#follow-an-authenticated-request).

## Isolation layers

The sandbox security model has five layers. See
[Isolation layers](isolation/) for technical details on each.

- **Hypervisor isolation:** separate kernel per sandbox. No shared memory or
  processes with the host.
- **Network isolation:** outbound TCP traffic is proxied through the host and
  governed by a [deny-by-default policy](defaults/). Experimental UDP egress
  also follows network policy. ICMP is blocked.
- **Docker Engine isolation:** each sandbox has its own Docker Engine with no
  path to the host daemon.
- **Workspace isolation:** a mountless sandbox has no host workspace mount.
  Clone mode gives the agent a private in-VM clone and mounts your repository
  read-only. Direct mode shares your working tree read-write.
- **Credential isolation:** API keys are injected into HTTP headers by the
  host-side proxy. Credential values never enter the VM.

## What the agent can do inside the sandbox

Inside the VM, the agent has full privileges: sudo access, package installation,
a private Docker Engine, and read-write access to its in-sandbox filesystem and
configured workspace. Installed packages, Docker images, and other VM state
persist across restarts. See
[Default security posture](defaults/) for the full breakdown of what is
permitted and what is blocked.

## Security considerations

The sandbox isolates the agent from your host system, but the agent's actions
can still affect you through explicitly shared resources and allowed network
channels.

In direct mode, workspace changes are live on your host. The agent edits the
same files you see on your host. This includes files that execute implicitly
during normal development: Git hooks, CI configuration, IDE task configs, AI
project configuration and settings, `Makefile`, `package.json` scripts, and
similar build files. Review changes before running any modified code. Note that
Git hooks live inside `.git/` and do not appear in `git diff` output — check
them separately. See
[Workspace isolation](isolation/#workspace-isolation) for the full list and
for the alternative clone-mode boundary.

The default allowed domains include broad wildcards. Some defaults like
`*.googleapis.com` cover many services beyond AI APIs. Run `sbx policy ls` to
see the full list of active rules, and remove entries you don't need. See
[Default security posture](defaults/).

Kits run install commands with root privileges inside the sandbox. To limit
supply-chain risk, `sbx` restricts kit installs to an allowlist of sources
that defaults to Docker Hub only. See
[Restrict kit sources](/manuals/ai/sandboxes/customize/use-kits.md#restrict-kit-sources).

Shared agent skills create a narrow exception to cross-sandbox isolation. The
store can be mounted with `readwrite` access, so one sandbox can modify
instructions or scripts that an agent later uses in another sandbox, including
one with `readonly` access. This doesn't expose the rest of
the host filesystem or create a direct network path between sandboxes, but it
does put participating sandboxes in the same trust boundary. See
[Share agent skills](../workflows/agent-skills.md) for details and the
per-sandbox opt-out.

Local stdio MCP servers run outside the sandbox VM. If you register a local MCP
server that starts a host process or host Docker container, that process or
container uses host permissions and host isolation, not sandbox isolation. See
[MCP gateway](../mcp-gateway.md).

## Organization-wide control

On a single developer's machine, security and policy are configured locally —
for example, network and filesystem rules set with `sbx policy`. Admins can
move these controls to the organization level so that security, policy, and
access apply consistently across every developer's sandboxes, rather than
depending on local configuration.

See [Governance](../governance/) for the controls available to organization
admins.

## Learn more

- [Isolation layers](isolation/): how hypervisor, network, Docker,
  workspace, and credential isolation work
- [Default security posture](defaults/): what a fresh sandbox permits and
  blocks
- [Manage credentials](../configuration/credentials.md): provide and manage API
  keys while keeping their values outside the sandbox
- [Governance](../governance/): configure network, filesystem, and MCP access
  controls locally or across your organization

---

### Manuals Ai Sandboxes Workflows  Index (`content/manuals/ai/sandboxes/workflows/_index.md`)

---
title: Workflow patterns
linkTitle: Workflows
weight: 50
description: Choose a Docker Sandboxes workflow for agent skills, Git, local development, authenticated tools, or headless automation.
keywords: docker sandboxes, sbx, workflows, agent skills, shared skills, clone mode, git, local development, authentication, ci, headless
toc_max: 2
---

Choose a workflow based on how you want to develop, authenticate tools, or run
local sandboxes in automation. For command syntax and lifecycle basics, see
[Usage](../usage.md).

## Choose how code moves

Your workspace strategy determines when an agent's changes appear on the host.
Direct mode edits the host working tree in place. Clone mode keeps changes in a
private clone until you fetch or push them. Host worktrees provide branch
isolation while keeping Git operations on the host. See [Git workflows](git.md)
to choose a strategy for single or parallel tasks.

## Develop in the sandbox

Each sandbox has a private Docker daemon and runtime for building images,
installing dependencies, and running tests. You can publish services from the
sandbox or connect to services on the host. See
[Develop and test locally](development.md).

Tools inside the sandbox can use credentials configured on the host without
copying secret values into the VM. See
[Authenticate command-line tools](authentication.md) for GitHub CLI, registry,
and external secret-provider workflows.

## Reuse and automate workflows

Sandbox environment files work like Compose files for sandboxes: they capture
project configuration in a versioned YAML file. Use `sbxenv.yaml` to define
the agent, workspaces, tools, resources, credentials, and ports so contributors
can start a consistent environment without reproducing CLI flags and setup
steps. See [Sandbox environment files](../configuration/environment-files.md).

You can also add skills from Git repositories or import them from supported
host agents into a persistent store shared with new sandboxes. See
[Share agent skills](agent-skills.md).

For unattended jobs, use headless authentication and manage the sandbox
lifecycle from scripts. See [Run sandboxes in CI](automation.md).

---

### Manuals Compose How Tos Environment Variables  Index (`content/manuals/compose/how-tos/environment-variables/_index.md`)

---
title: Environment variables in Compose
linkTitle: Use environment variables
weight: 40
description: Explains how to set, use, and manage environment variables in Docker Compose.
keywords: compose, orchestration, environment, env file
aliases:
- /compose/environment-variables/
---

Environment variables and interpolation in Docker Compose help you create reusable, flexible configurations. This makes Dockerized applications easier to manage and deploy across environments.

> [!TIP]
>
> Before using environment variables, read through all of the information first to get a full picture of environment variables in Docker Compose.

This section covers:

- [How to set environment variables within your container's environment](set-environment-variables.md).
- [How environment variable precedence works within your container's environment](envvars-precedence.md).
- [Pre-defined environment variables](envvars.md).

It also covers: 
- How [interpolation](variable-interpolation.md) can be used to set variables within your Compose file and how it relates to a container's environment.
- Some [best practices](best-practices.md).

---

### Manuals Compose How Tos Multiple Compose Files  Index (`content/manuals/compose/how-tos/multiple-compose-files/_index.md`)

---
description: General overview for the different ways you can work with multiple compose
  files in Docker Compose
keywords: compose, compose file, merge, extends, include, docker compose, -f flag
linkTitle: Use multiple Compose files
title: Use multiple Compose files
weight: 80
aliases:
- /compose/multiple-compose-files/
---

This section contains information on the ways you can work with multiple Compose files. 

Using multiple Compose files lets you customize a Compose application for different environments or workflows. This is useful for large applications that may use dozens of containers, with ownership distributed across multiple teams. For example, if your organization or team uses a monorepo, each team may have their own “local” Compose file to run a subset of the application. They then need to rely on other teams to provide a reference Compose file that defines the expected way to run their own subset. Complexity moves from the code in to the infrastructure and the configuration file.

The simplest way to work with multiple Compose files is to [merge](merge.md) them using
the `-f` flag. This works well for straightforward overrides, but the
[merging rules](merge.md#merging-rules) can make it complex to manage as your
configuration grows.

Docker Compose provides two other options to manage this complexity when working with multiple Compose files. Depending on your project's needs, you can: 

- [Extend a Compose file](extends.md) by referring to another Compose file and selecting the bits you want to use in your own application, with the ability to override some attributes.
- [Include other Compose files](include.md) directly in your Compose file.

---

### Manuals Desktop Enterprise Enforce Sign In  Index (`content/manuals/desktop/enterprise/enforce-sign-in/_index.md`)

---
title: Enforce sign-in for Docker Desktop
linkTitle: Enforce sign-in
description: Require users to sign in to Docker Desktop to access organization benefits and security features
toc_max: 2
keywords: authentication, registry.json, configure, enforce sign-in, docker desktop, security, .plist, registry key, mac, windows, organization
tags: [admin]
aliases:
 - /security/for-admins/configure-sign-in/
 - /security/for-admins/enforce-sign-in/
 - /enterprise/security/enforce-sign-in/
weight: 30
---

{{< summary-bar feature_name="Enforce sign-in" >}}

By default, users can access Docker Desktop without signing in to your organization.
When users don't sign in as organization members, they miss out on subscription benefits and can bypass security features configured for your organization.

You can enforce sign-in using several methods, depending on your setup:

- [Registry key method (Windows only)](methods.md#windows-registry-key-method)
- [Configuration profiles method (Mac only)](methods.md#mac-configuration-profiles-method-recommended)
- [`.plist` method (Mac only)](methods.md#mac-plist-file-method)
- [`registry.json` method (all platforms)](methods.md#all-platforms-registryjson-method)

Deploying a `admin-settings.json` file with [Settings Management](/manuals/desktop/enterprise/hardened-desktop/settings-management/_index.md) also enforces sign-in. See [Settings Management and sign-in enforcement](methods.md#settings-management-and-sign-in-enforcement).

This page provides an overview of how sign-in enforcement works.

## How sign-in enforcement works

When Docker Desktop detects a registry key, configuration profile, `.plist` file, or
`registry.json` file:

- A **Sign in using your work email address** prompt appears, requiring users to
  sign in as organization members to use Docker Desktop. The prompt states which
  organizations are required and which method enforces it.
- If users sign in with accounts that aren't organization members, they're
  automatically signed out and can't use Docker Desktop. The prompt changes to
  **You have been signed out** and explains why. They can sign in again with a
  different account.
- When users sign in with organization member accounts, they can use Docker
  Desktop normally.
- When users sign out, the sign-in prompt reappears and they can
  no longer use Docker Desktop unless they sign back in.

### Impact on the Docker CLI

Sign-in enforcement also blocks the Docker CLI. While the sign-in prompt is
showing, Docker Desktop's API proxy rejects almost every request with an
explanation at the terminal, for example:

```text
Sign in to continue using Docker Desktop. Membership in the [myorg] organization
is required. Sign in enforced by your administrators (via registry.json).
```

- `docker run`, `docker pull`, `docker build`, `docker ps`, and other commands
  that reach the engine fail until the user signs in.
- `docker version`, `docker info`, and `docker login` continue to work, so users
  can sign in from the CLI.

> [!IMPORTANT]
>
> Make sure you plan for blocking the Docker CLI before you roll out enforcement. Any scripted or CI use of the
> Docker CLI on an enforced machine stops working until that machine's user signs
> in as an organization member.

Sign-in enforcement is separate from [SSO enforcement](#enforcing-sign-in-versus-enforcing-single-sign-on-sso), which governs how users authenticate as opposed to whether they must authenticate.

### Impact on already-signed-in users

When enforcement is first deployed, users who are already running Docker Desktop are not immediately affected. Docker Desktop re-evaluates enforcement when it starts, and when a user signs in or out. It doesn't poll for new configuration while running, so a newly deployed registry key, configuration profile, `.plist`, or `registry.json` file takes effect on the next restart.

On the next Docker Desktop restart:

- Users signed in with an organization member account are automatically re-authenticated and continue working uninterrupted.
- Users signed in with a non-member account are immediately signed out on startup and see the **Sign in required!** prompt. 

## Enforcing sign-in versus enforcing single sign-on (SSO)

Enforcing Docker Desktop sign-in and [enforcing SSO](/manuals/security/authentication/single-sign-on/connect.md#enforce-sso) are different features that serve different purposes:

| Enforcement                       | Description                                                     | Benefits                                                                                                                                                                                                                                                   |
|:----------------------------------|:----------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Enforce sign-in only              | Users must sign in before using Docker Desktop                 | Ensures users receive the benefits of your subscription and ensures security features are applied. In addition, you gain insights into users’ activity.                                                                                                    |
| Enforce single sign-on (SSO) only | If users sign in, they must sign in using SSO                  | Centralizes authentication and enforces unified policies set by the identity provider.                                                                                                                                                                     |
| Enforce both                      | Users must sign in using SSO before using Docker Desktop       | Ensures users receive the benefits of your subscription and ensures security features are applied. In addition, you gain insights into users’ activity. It also centralizes authentication and enforces unified policies set by the identity provider. |
| Enforce neither                   | If users sign in, they can use SSO or their Docker credentials | Lets users access Docker Desktop without barriers, at the cost of reduced security and insights.                                                                                                                                                  |

## Next steps

- To set up sign-in enforcement, see [Configure sign-in enforcement](methods.md).
- To configure SSO enforcement, see [Enforce SSO](/manuals/security/authentication/single-sign-on/connect.md).

---

### Manuals Desktop Enterprise Enterprise Deployment  Index (`content/manuals/desktop/enterprise/enterprise-deployment/_index.md`)

---
title: Deploy Docker Desktop 
weight: 10
description: If you're an IT admin, learn how to deploy Docker Desktop at scale
keywords: msi, docker desktop, windows, installation, mac, pkg, enterprise 
grid:
- title: MSI installer
  description: Learn how to install Docker Desktop with the MSI installer.
  link: /desktop/enterprise/enterprise-deployment/msi-install-and-configure/
- title: PKG installer
  description: Learn how to install Docker Desktop with the PKG installer.
  link: /desktop/enterprise/enterprise-deployment/pkg-install-and-configure/
- title: MS Store
  description: Learn how to install Docker Desktop through the Microsoft Store.
  link: /desktop/enterprise/enterprise-deployment/ms-store/
- title: Deploy with Intune
  description: Learn how to deploy Docker Desktop on Windows and macOS devices using Microsoft Intune.
  link: /desktop/enterprise/enterprise-deployment/use-intune/
- title: Deploy with Jamf Pro
  description: Learn how to deploy Docker Desktop for Mac using Jamf Pro
  link: /desktop/enterprise/enterprise-deployment/use-jamf-pro/
- title: Docker Desktop for Microsoft Dev Box
  description: Install Docker Desktop for Microsoft Dev Box via the Microsoft Azure Marketlplace
  link: /desktop/enterprise/enterprise-deployment/dev-box/
- title: FAQs
  description: Common questions when deploying Docker Desktop 
  link: /desktop/enterprise/enterprise-deployment/faq/
aliases:
 - /desktop/enterprise/admin/install/mac/
 - /desktop/enterprise/admin/configure/mac-admin/
 - /desktop/enterprise/admin/configure/windows-admin/
 - /desktop/enterprise/
 - /enterprise/enterprise-deployment/
---

Docker Desktop supports scalable deployment options tailored for enterprise IT environments. Whether you're rolling out Docker across hundreds of developer workstations or enforcing consistent configuration through MDM solutions, this section provides everything you need to install, configure, and manage Docker Desktop in a secure, repeatable way. 

Learn how to use MSI and PKG installers, configure default settings, control updates, and ensure compliance with your organization's policies—across Windows, Mac, and Linux systems.

{{< grid >}}

---

### Manuals Desktop Enterprise Hardened Desktop  Index (`content/manuals/desktop/enterprise/hardened-desktop/_index.md`)

---
title: Hardened Docker Desktop
linkTitle: Hardened Docker Desktop
description: Security features that help organizations secure developer environments without impacting productivity
keywords: security, hardened desktop, enhanced container isolation, registry access management, settings management, admins, docker desktop, image access management, air-gapped containers
tags: [admin]
aliases:
  - /security/for-admins/hardened-desktop/
  - /enterprise/security/
  - /enterprise/security/hardened-desktop/
grid:
  - title: "Settings Management"
    description: Learn how Settings Management can secure your developers' workflows.
    icon: shield-check
    link: /desktop/enterprise/hardened-desktop/settings-management/
  - title: "Enhanced Container Isolation"
    description: Understand how Enhanced Container Isolation can prevent container attacks.
    icon: shield-check
    link: /desktop/enterprise/hardened-desktop/enhanced-container-isolation/
  - title: "Registry Access Management"
    description: Control the registries developers can access while using Docker Desktop.
    icon: server
    link: /desktop/enterprise/hardened-desktop/registry-access-management/
  - title: "Image Access Management"
    description: Control the images developers can pull from Docker Hub.
    icon: photo
    link: /desktop/enterprise/hardened-desktop/image-access-management/
  - title: "Air-Gapped Containers"
    description: Restrict containers from accessing unwanted network resources.
    icon: lock-closed
    link: /desktop/enterprise/hardened-desktop/air-gapped-containers/
  - title: "Namespace access"
    description: Control whether organization members can push content to their personal namespaces.
    icon: folder-open
    link: /desktop/enterprise/hardened-desktop/namespace-access/
weight: 40
---

{{< summary-bar feature_name="Hardened Docker Desktop" >}}

Hardened Docker Desktop provides a collection of security features designed to strengthen developer environments without compromising productivity or developer experience.

With Hardened Docker Desktop, you can enforce strict security policies that prevent developers and containers from bypassing organizational controls. You can also enhance container isolation to protect against security threats like malicious payloads that might breach the Docker Desktop Linux VM or underlying host system.

## Who should use Hardened Docker Desktop?

Hardened Docker Desktop is ideal for security-focused organizations that:

- Don't provide root or administrator access to developers' machines
- Want centralized control over Docker Desktop configurations
- Must meet specific compliance requirements

## How Hardened Docker Desktop works

Hardened Docker Desktop features work independently and together to create a defense-in-depth security strategy. They protect developer workstations against attacks across multiple layers, including Docker Desktop configuration, container image management, and container runtime security:

- Registry Access Management and Image Access Management prevent access to unauthorized container registries and image types, reducing exposure to malicious payloads
- Enhanced Container Isolation runs containers without root privileges inside a Linux user namespace, limiting the impact of malicious containers
- Air-gapped containers let you configure network restrictions for containers, preventing malicious containers from accessing your organization's internal network resources
- Namespace access controls whether organization members can push content to their personal Docker Hub namespaces, preventing accidental publication of images outside approved locations
- Settings Management locks down Docker Desktop configurations to enforce company policies and prevent developers from introducing insecure settings, whether intentionally or accidentally

## Next steps

Explore Hardened Docker Desktop features to understand how they can strengthen your organization's security posture:

{{< grid >}}

---

### Manuals Desktop Enterprise Unassociated Machines  Index (`content/manuals/desktop/enterprise/unassociated-machines/_index.md`)

---
title: Manage unassociated machines
description: Learn how to manage unassociated machines in Docker Home
keywords: unassociated machines, insights, manage users, enforce sign-in
weight: 50
aliases:
 - /unassociated-machines/
---

{{< summary-bar feature_name="Unassociated machines" >}}

Organization owners can identify, view, and manage Docker Desktop machines
that are likely associated with their organization, based on usage, but aren't currently linked
to user accounts. This self-service capability helps you understand Docker
Desktop usage across your organization and streamline user onboarding without
IT involvement.

## How Docker identifies unassociated machines

Docker uses telemetry data to identify which machines likely belong to your
organization:

- Domain matching: Users signed in with email domains associated with your
  organization
- Registry patterns: Analysis of container registry access patterns that
  indicate organizational usage

## View unassociated machines

To see detailed information about unassociated machines:

1. Sign in to [Docker Home](https://app.docker.com) and select your organization.
1. Select **Docker Desktop**, then **Unassociated**.

The machine list displays:

- Machine ID (Docker-generated identifier)
- The registry address used to predict whether a user is part of your
  organization
- User email (only displays if the user is signed into Docker Desktop while
  using it)
- Docker Desktop version
- Operating system (OS)
- Last activity date
- Sign-in enforced status

You can:

- Export the list as CSV
- Take actions on individual or multiple machines

## Enable sign-in enforcement for unassociated machines

> [!IMPORTANT]
>
> Sign-in enforcement for unassociated machines is different from
> the [organization-level sign-in enforcement](/manuals/desktop/enterprise/enforce-sign-in/_index.md)
> available through `registry.json` and configuration profiles. This sign-in
> enforcement only requires users to sign in so admins can identify who is
> using the machine, meaning users can sign in with any email address. For more
> stringent security controls that limit sign-ins to users who are already part
> of your organization, see [Enforce sign-in](/manuals/desktop/enterprise/enforce-sign-in/_index.md).

Sign-in enforcement helps you identify who is using unassociated machines in
your organization. When you enable enforcement, users on these machines will
be required to sign in to Docker Desktop. Once they sign in, their email
addresses will appear in the Unassociated list, allowing you to then add them
to your organization.

You can enable sign-in enforcement using two methods:

- For all unassociated machines in your organization
- For individual unassociated machines

### Enable for all unassociated machines

To enable sign-in enforcement for all unassociated machines:

1. Sign in to [Docker Home](https://app.docker.com) and select your organization.
1. Select **Docker Desktop**, then **Unassociated**.
1. Turn on the **Enforce sign-in** toggle.
1. In the pop-up modal, select **Require sign-in** to confirm.

The **Sign-in required** status updates all unassociated machines to
**Yes**.

Sign-in enforcement only takes effect after Docker Desktop is restarted.
Users can continue using Docker Desktop until their next restart.

> [!NOTE]
>
> When you enable sign-in enforcement for all unassociated machines, any new
> machines detected in the future automatically have sign-in enforcement
> enabled.

### Enable for individual unassociated machines

To enable sign-in enforcement for individual unassociated machines:

1. Sign in to [Docker Home](https://app.docker.com) and select your organization.
1. Select **Docker Desktop**, then **Unassociated**.
1. Locate the machine you want to enable sign-in enforcement for.
1. Select the **Actions** menu and choose **Turn on sign-in enforcement**.
1. In the pop-up modal, select **Require sign-in** to confirm.

The **Sign-in required** status updates for the individual machine to
**Yes**.

### What happens when sign-in is enforced

After you enable sign-in enforcement:

- When users open Docker Desktop, they see a sign-in prompt. They must sign
   in to continue using Docker Desktop.
- User email addresses appear in the **Unassociated** list.
- You can add users to your organization.

Users can continue using Docker Desktop immediately after signing in, even
before being added to your organization.

## Add unassociated machines to your organization

When users in your organization use Docker without signing in, their machines
appear in the **Unassociated** list. You can add these users to your
organization in two ways:

- Automatic addition:
  - Auto-provisioning: If you have verified domains with auto-provisioning
    enabled, users who sign in with a matching email domain will automatically
    be added to your organization. For more information on verifying domains and
    auto-provisioning, see [Domain management](/manuals/security/provisioning/domain-management.md).
  - SSO user provisioning: If you have SSO configured with
    [Just-in-Time provisioning](/manuals/security/provisioning/just-in-time.md),
    users who sign in through your SSO connection will automatically be added
    to your organization.
- Manual addition: If you don't have auto-provisioning or SSO set up, or if a
  user's email domain doesn't match your configured domains, their email will
  appear in the **Unassociated** list where you can choose to add them directly.

> [!NOTE]
>
> If you add users and do not have enough seats in your organization, a
> pop-up appears prompting you to **Get more seats**.

### Add individual users

1. Sign in to [Docker Home](https://app.docker.com) and select your organization.
1. Select **Docker Desktop**, then **Unassociated**.
1. Locate the machine you want to add to your organization.
1. Select the **Actions** menu and choose **Add to organization**.
1. In the pop-up modal, select **Add user**.

### Bulk add users

1. Sign in to [Docker Home](https://app.docker.com) and select your organization.
1. Select **Docker Desktop**, then **Unassociated**.
1. Use the **checkboxes** to select the machines you want to add to your
   organizations.
1. Select the **Add to organization** button.
1. In the pop-up modal, select **Add users** to confirm.

## Disable sign-in enforcement

### Disable for all unassociated machines

1. Sign in to [Docker Home](https://app.docker.com) and select your organization.
1. Select **Docker Desktop**, then **Unassociated**.
1. Turn off the **Enforce sign-in** toggle.
1. In the pop-up modal, select **Turn off sign-in requirement** to confirm.

The **Sign-in required** status updates for all unassociated machines to
**No**.

### Disable for specific unassociated machines

1. Sign in to [Docker Home](https://app.docker.com) and select your organization.
1. Select **Docker Desktop**, then **Unassociated**.
1. Locate the machine you want to disable sign-in enforcement for.
1. Select the **Actions** menu and choose **Turn off sign-in enforcement**.
1. In the pop-up modal, select **Turn off sign-in requirement** to confirm.

The **Sign-in required** status updates for the individual machine to
**No**.

---

### Manuals Desktop Features Mcp Catalog And Toolkit  Index (`content/manuals/desktop/features/mcp-catalog-and-toolkit/_index.md`)

---
url: /ai/mcp-catalog-and-toolkit/
title: Docker MCP Catalog and Toolkit
linkTitle: MCP Catalog and Toolkit
params:
  sidebar:
    badge:
      color: blue
      text: Beta
weight: 20
description: Learn about Docker's MCP catalog on Docker Hub
keywords: Docker, ai, mcp servers, ai agents, extension, docker desktop, llm, docker hub
grid:
  - title: Get started with MCP Toolkit
    description: Learn how to quickly install and use the MCP Toolkit to set up servers and clients.
    icon: magnifying-glass-plus
    link: /ai/mcp-catalog-and-toolkit/get-started/
  - title: MCP Catalog
    description: Browse Docker's curated collection of verified MCP servers
    icon: globe-alt
    link: /ai/mcp-catalog-and-toolkit/catalog/
  - title: MCP Profiles
    description: Organize servers into profiles for different projects and share configurations
    icon: folder
    link: /ai/mcp-catalog-and-toolkit/profiles/
  - title: MCP Toolkit
    description: Use Docker Desktop's UI to discover, configure, and manage MCP servers
    icon: /icons/toolkit.svg
    link: /ai/mcp-catalog-and-toolkit/toolkit/
  - title: MCP Gateway
    description: Use the CLI and Gateway to run MCP servers with custom configurations
    icon: cpu-chip
    link: /ai/mcp-catalog-and-toolkit/mcp-gateway/
  - title: Dynamic MCP
    description: Discover and add MCP servers on-demand using natural language. This feature is experimental.
    icon: magnifying-glass
    link: /ai/mcp-catalog-and-toolkit/dynamic-mcp/
  - title: Security FAQs
    description: Common questions about MCP security, credentials, and server verification
    icon: shield-check
    link: /ai/mcp-catalog-and-toolkit/faqs/
---

{{< summary-bar feature_name="Docker MCP Catalog and Toolkit" >}}

[Model Context Protocol](https://modelcontextprotocol.io/introduction) (MCP) is
an open protocol that standardizes how AI applications access external tools
and data sources. By connecting LLMs to local development tools, databases,
APIs, and other resources, MCP extends their capabilities beyond their base
training.

The challenge is that running MCP servers locally creates operational friction.
Each server requires separate installation and configuration for every
application you use. You run untrusted code directly on your machine, manage
updates manually, and troubleshoot dependency conflicts yourself. Configure a
GitHub server for Claude, then configure it again for Cursor, and so on. Each
time you manage credentials, permissions, and environment setup.

## Docker MCP features

The [MCP Toolkit](/ai/mcp-catalog-and-toolkit/toolkit/) and [MCP
Gateway](/ai/mcp-catalog-and-toolkit/mcp-gateway/) solve these challenges
through centralized management. Instead of configuring each server for every AI
application separately, you set things up once and connect all your clients to
it. The workflow centers on three concepts: catalogs, profiles, and clients.



[Catalogs](/ai/mcp-catalog-and-toolkit/catalog/) are curated collections of
MCP servers. The Docker MCP Catalog provides 300+ verified servers packaged as
container images with versioning, provenance, and security updates. Organizations
can create [custom
catalogs](/ai/mcp-catalog-and-toolkit/catalog/#custom-catalogs) with approved
servers for their teams.

[Profiles](/ai/mcp-catalog-and-toolkit/profiles/) organize servers into named
collections for different projects. Your "web-dev" profile might use GitHub and
Playwright; your "backend" profile, database tools. Profiles support both
containerized servers from catalogs and remote MCP servers. Configure a profile
once, then share it across clients or with your team.

Clients are the AI applications that connect to your profiles. Claude Code,
Cursor, Zed, and others connect through the MCP Gateway, which routes requests
to the right server and handles authentication and lifecycle management.

> [!NOTE]
> MCP Gateway as part of Docker AI Governance is an invite-only feature. [Contact Docker Sales](https://www.docker.com/pricing/contact-sales/) to learn more.

## Learn more

{{< grid >}}

---

### Manuals Desktop Features Networking  Index (`content/manuals/desktop/features/networking/_index.md`)

---
description: Understand how Docker Desktop handles networking, firewalls, file access, proxies, and endpoint visibility.
keywords: docker desktop, networking, architecture, firewall, proxies, crowdstrike, vpn
title: Networking on Docker Desktop
linkTitle: Networking
weight: 30
---

This page explains how Docker Desktop routes network traffic and file I/O between containers, the VM, and the host, and how this behavior is visible to firewalls and endpoint protection tools.

## Overview

Docker Desktop runs the Docker Engine inside a lightweight Linux virtual machine (VM). Depending on your system configuration and operating system, Docker Desktop routes network and file operations between the Docker VM and the host using different backend components.

### Backend components and responsibilities

The backend acts as:

- Network proxy: Translates traffic between the host and Linux VM.
  - On Windows and Mac, this is handled by the `com.docker.backend` process.
  - On Linux, the `qemu` process performs this function.
- File server: Handles file access from containers to the host filesystem.
  - When using gRPC FUSE, the backend performs the file sharing.
  - When using `virtiofs`, or `krun`, file access is handled by those respective daemons rather than the backend process.
- Control plane: Manages Docker API calls, port forwarding, and proxy configuration.

The following table summarizes typical setups in more detail:

| Platform        | Setup                                 | Networking handled by    | File sharing handled by                | Notes                                                      |
| --------------- | ------------------------------------- | ------------------------ | -------------------------------------- | ---------------------------------------------------------- |
| Windows         | Hyper-V                               | `com.docker.backend.exe` | `com.docker.backend.exe`               | Simplest setup with full visibility to EDR/firewall tools  |
| Windows (WSL 2) | WSL 2                                 | `com.docker.backend.exe` | WSL 2 kernel (no visibility from host) | Recommended only when WSL 2 integration is needed          |
| Mac             | Virtualization framework + gRPC FUSE  | `com.docker.backend`     | `com.docker.backend`                   | Recommended for performance and visibility                 |
| Mac             | Virtualization framework + `virtiofs` | `com.docker.backend`     | Apple's Virtualization framework       | Higher performance but no file access visibility from host |
| Mac             | DockerVMM + `virtiofs`                | `com.docker.backend`     | `krun`                                 | Currently in Beta                                          |
| Linux           | Native Linux VM                       | `qemu`                   | `virtiofsd`                            | No `com.docker.backend` process on Linux                   |

## How containers connect to the internet

Each Linux container in Docker Desktop runs inside a small virtual network managed by Docker and every container is attached to a Docker-managed network and receives its own internal IP address. You can view and manage these networks with `docker network ls`, `docker network create`, and `docker network inspect`. They are managed by the [`daemon.json`](/manuals/engine/daemon/_index.md).

When a container initiates a network request, for example with `apt-get update` or `docker pull`:

- The container’s `eth0` interface connects to a virtual bridge (`docker0`) inside the VM.
- Outbound traffic from the container is sent through Network Address Translation (NAT) using a virtual adapter (typically with an internal IP such as `192.168.65.3`). You can view or change this with the [Docker Desktop settings](/manuals/desktop/settings-and-maintenance/settings.md#network).
- The traffic is transferred to the host system over a shared-memory channel rather than through a traditional virtual network interface. This approach ensures reliable communication and avoids conflicts with host-level network adapters or firewall configurations.
- On the host, Docker Desktop’s backend process receives the traffic and creates standard TCP/IP connections using the same networking APIs as other applications.

All outbound container network traffic originates from the `com.docker.backend` process. Firewalls, VPNs, and security tools, like CrowdStrike, see traffic coming from this process — not from a VM or unknown source so firewall and endpoint security software can apply rules directly to `com.docker.backend`.

## How exposed ports work

When you publish a container port using the `-p` or `--publish` flag, Docker Desktop makes that container port accessible from your host system or local network.

For example, with `docker run -p 80:80 nginx`:

- Docker Desktop's backend process listens on the specified host port, in this case, port `80`.
- When an application such as a web browser connects to that port, Docker Desktop forwards the connection into the Linux VM where the container is running over a shared-memory channel.
- Inside the VM, the connection is routed to the container’s internal IP address and port, for example `172.17.0.2:80`.
- The container responds through the same path, so you can access it from your host just like any other local service.

By default, `docker run -p` listens on all network interfaces (`0.0.0.0`), but you can restrict it to a specific address, such as `127.0.0.1` (`localhost`) or a particular network adapter. This behavior can be modified to bind to `localhost` by default in [Docker Desktop's network settings](/manuals/desktop/settings-and-maintenance/settings.md#network)

Host firewalls can permit or deny inbound connections by filtering on `com.docker.backend`.

## Using Docker Desktop with a proxy

Docker Desktop can use your system’s default proxy settings or custom settings that you configure with [Docker Desktop’s proxy setting](/manuals/desktop/settings-and-maintenance/settings.md#proxies).

Docker Desktop routes traffic through two separate proxies. The Containers proxy governs all `docker image pull` operations, as well as running container traffic when air-gapped container enforcement is enabled. The Docker Desktop proxy governs host-level traffic - the Desktop application, Docker CLI, and extensions — and is a fallback for image pulls only when the Containers proxy is not explicitly configured.

Note that:

- The proxy honors system or manual proxy configuration.
- On Windows, Basic, NTLM, and Kerberos authentication is supported.
- For Mac, NTLM/Kerberos is not supported natively. Run a local proxy on `localhost` as a workaround.
- CLI plugins and other tools that use the Docker API directly must be configured separately with the `HTTP_PROXY`, `HTTPS_PROXY`, and `NO_PROXY` environment variables.

## Firewalls and endpoint visibility

To restrict VM or container networking apply rules to `com.docker.backend.exe` (Windows) `com.docker.backend` (Mac) or `qemu` (Linux) as all VM networking is funneled through these processes.

Use Windows Defender Firewall or enterprise endpoint firewalls for control. This enables traffic inspection and restriction at the host level without modifying the Docker Engine.

CrowdStrike and similar tools can observe all traffic and file access that passes through the backend process.

| Action                                       | Visible to host EDR? | Reason                                 |
| -------------------------------------------- | -------------------- | -------------------------------------- |
| Container reads host files                   | Yes                  | Access handled by `com.docker.backend` |
| Container writes host files                  | Yes                  | Same process performs the write        |
| Container accesses its own filesystem layers | No                   | Exists only inside the VM              |

---

### Manuals Desktop Features Wsl  Index (`content/manuals/desktop/features/wsl/_index.md`)

---
description: Turn on the Docker WSL 2 backend and get to work using best practices,
  GPU support, and more in this thorough guide.
keywords: wsl, wsl2, installing wsl2, wsl installation, docker wsl2, wsl docker, wsl2
  tech preview, wsl install docker, install docker wsl, how to install docker in wsl
title: Docker Desktop WSL 2 backend on Windows
linkTitle: WSL
weight: 120
aliases:
- /docker-for-windows/wsl/
- /desktop/windows/wsl/
- /desktop/wsl/
- /docker-for-windows/wsl-tech-preview/
---

Windows Subsystem for Linux (WSL) 2 is a full Linux kernel built by Microsoft that lets Linux distributions run without managing virtual machines. With Docker Desktop running on WSL 2, users can leverage Linux workspaces and avoid maintaining both Linux and Windows build scripts. In addition, WSL 2 provides improvements to file system sharing, faster cold-start times, and dynamic resource allocation.

Because WSL 2 uses dynamic memory allocation, Docker Desktop requests only the CPU and memory it actually needs — freeing resources for the rest of your system, while still letting memory-intensive tasks such as multi-stage image builds run at full speed.

## Prerequisites

Before you turn on the Docker Desktop WSL 2 feature, ensure you have:

- At a minimum WSL version 2.1.5, but ideally the latest version of WSL to [avoid Docker Desktop not working as expected](best-practices.md).
- Met the Docker Desktop for Windows' [system requirements](/manuals/desktop/setup/install/windows-install.md#system-requirements).
- Installed the WSL 2 feature on Windows. For detailed instructions, refer to the [Microsoft documentation](https://docs.microsoft.com/en-us/windows/wsl/install-win10).

> [!TIP]
>
> Consider enabling the WSL [autoMemoryReclaim](https://learn.microsoft.com/en-us/windows/wsl/wsl-config#experimental-settings) setting, available since WSL 1.3.10 (experimental).
>This setting allows Windows to reclaim unused memory from the WSL virtual machine, preventing the Linux kernel's page cache from holding onto large amounts of RAM after container image builds complete. The result is better memory availability for other applications on the host. 

## Turn on Docker Desktop WSL 2

Before installing Docker Desktop, uninstall any version of Docker Engine or the Docker CLI
that was installed directly inside a WSL Linux distribution. Running both can cause conflicts.

1. [Install Docker Desktop for Windows](/manuals/desktop/setup/install/windows-install.md).
2. During installation, Docker Desktop may prompt you to turn on WSL 2. Read the information displayed on the screen and turn on the WSL 2 feature to continue.
3. Start Docker Desktop from the **Windows Start** menu.
4. Navigate to **Settings**.
5. From the **General** tab, select **Use WSL 2 based engine**.

    If you have installed Docker Desktop on a system that supports WSL 2, this option is turned on by default and the setting is not visible. 
6. Select **Apply**.

`docker` commands are now available from any Windows terminal using the WSL 2 engine.

> [!TIP]
>
> By default, Docker Desktop stores the data for the WSL 2 engine at `C:\Users\[USERNAME]\AppData\Local\Docker\wsl`.
> If you want to change the location, go to `Settings -> Resources -> Advanced` page from the Docker Dashboard.
> Read more about this and other Windows settings at [Changing settings](/manuals/desktop/settings-and-maintenance/settings.md)

## Enable Docker in a WSL 2 distribution

WSL 2 lets multiple Linux distributions run side-by-side on a single shared kernel. Docker Desktop doesn't require a particular distribution to be installed, and `docker` commands work from Windows without one. However, enabling WSL integration for a distribution gives you direct access to `docker` commands from that distribution's terminal — which is useful for Linux-native development workflows.

1. Ensure the distribution runs in WSL 2 mode. WSL can run distributions in both v1 or v2 mode.

    To check the WSL mode, run:

     ```console
     $ wsl.exe -l -v
     ```

    To upgrade the Linux distribution to v2, run:

    ```console
    $ wsl.exe --set-version (distribution name) 2
    ```

    To set v2 as the default version for future installations, run:

    ```console
    $ wsl.exe --set-default-version 2
    ```

2. When Docker Desktop starts, go to **Settings** > **Resources** > **WSL Integration**.

    The Docker-WSL integration is enabled on the default WSL distribution, which is [Ubuntu](https://learn.microsoft.com/en-us/windows/wsl/install). To change your default WSL distribution, run:
     ```console
    $ wsl.exe --set-default <distribution name>
    ```
   If **WSL integrations** isn't available under **Resources**, Docker may be in Windows container mode. In your taskbar, select the Docker menu and then **Switch to Linux containers**.

3. Select **Apply**.

## WSL 2 security in Docker Desktop

Docker Desktop's WSL 2 integration works within WSL's existing security model and does not introduce security risks beyond standard WSL behavior.

Docker Desktop runs inside its own `docker-desktop` WSL distribution, isolated from other distributions in the same way any two WSL distributions are isolated from each other. Interaction between Docker Desktop and other distributions only occurs when you explicitly enable WSL integration for those distributions. This feature allows easy access to the Docker CLI from integrated distributions. 

WSL is designed to aid interoperability between Windows and Linux environments. Its file system is accessible from the Windows host `\\wsl$`, meaning Windows processes can read and modify files within WSL. This behavior is not specific to Docker Desktop, but rather a core aspect of WSL itself.

For environments that require stricter isolation:

- Run Docker Desktop in Hyper-V mode instead of WSL 2 to avoid the shared-kernel model entirely.
- Enable [Enhanced Container Isolation](/manuals/desktop/enterprise/hardened-desktop/enhanced-container-isolation/_index.md) to add an additional layer of protection around container workloads regardless of backend.

## Additional resources

- [Explore best practices](best-practices.md)
- [Understand how to develop with Docker and WSL 2](use-wsl.md)
- [Learn about GPU support with WSL 2](/manuals/desktop/features/gpu.md)
- [Custom kernels on WSL](custom-kernels.md)

---

### Manuals Desktop Setup Install  Index (`content/manuals/desktop/setup/install/_index.md`)

---
build:
  render: never
title: Install
weight: 10
---

---

### Manuals Desktop Troubleshoot And Support Faqs  Index (`content/manuals/desktop/troubleshoot-and-support/faqs/_index.md`)

---
build:
  render: never
title: FAQs
weight: 30
---

---

### Manuals Desktop Troubleshoot And Support Troubleshoot  Index (`content/manuals/desktop/troubleshoot-and-support/troubleshoot/_index.md`)

---
description:
  Understand how to diagnose and troubleshoot Docker Desktop, and how to
  check the logs.
keywords: Linux, Mac, Windows, troubleshooting, logs, issues, Docker Desktop
toc_max: 2
title: Troubleshoot Docker Desktop
linkTitle: Troubleshoot and diagnose
aliases:
  - /docker-for-windows/troubleshoot/
  - /desktop/troubleshoot/overview/
  - /desktop/troubleshoot/
tags: [Troubleshooting]
weight: 10
---

This page contains information on how to diagnose and troubleshoot Docker Desktop, and how to check the logs.

## Troubleshoot menu

To navigate to **Troubleshoot** either:

- Select the Docker menu Docker menu {{< inline-image src="../../images/whale-x.svg" alt="whale menu" >}} and then **Troubleshoot**.
- Select the **question mark** icon near the top-right corner of the Docker Desktop Dashboard.

The **Troubleshoot** menu contains the following options:

- **Restart Docker Desktop**

- **Support**

- **Reset Kubernetes cluster**. Select to delete all stacks and Kubernetes resources. For more information, see [Kubernetes](/manuals/desktop/settings-and-maintenance/settings.md#kubernetes).

- **Clean up data**. A disk image reset destroys all Docker containers and images local to the machine, preserving all settings.

- **Reset to factory defaults**: Choose this option to reset all options on
  Docker Desktop to their initial state, the same as when Docker Desktop was first installed.

If you are a Mac user, you also have the option to **Uninstall** Docker Desktop from your system.

## Diagnose

> [!NOTE]
>
> Gathering diagnostics may take several minutes. Don't close Docker Desktop while the diagnostics are being collected.

### Diagnose from the app

1. From **Troubleshoot**, select **Get support**. This opens the in-app Support page and starts collecting the diagnostics.
2. When the diagnostics collection process is complete, select **Upload to get a Diagnostic ID**.
3. When the diagnostics are uploaded, Docker Desktop prints a diagnostic ID. Copy this ID.
4. Use your diagnostics ID to get help:
   - If you have a Docker subscription and are signed in, select **Contact support**. This opens the Docker Desktop support form. Fill in the information required and add the ID you copied in step three to the **Diagnostics ID field**. Then, select **Submit ticket** to request Docker Desktop support.
   - If you don't have a Docker subscription, select **Report a Bug** to open a new Docker Desktop issue on GitHub. Complete the information required and ensure you add the diagnostic ID you copied in step three.

### Diagnose from an error message

1. When an error message appears, select **Gather diagnostics**. Gathering diagnostics may take several minutes. Don't close Docker Desktop while the diagnostics are being collected.
2. When the diagnostics are uploaded, Docker Desktop prints a diagnostic ID. Copy this ID.
3. Use your diagnostics ID to get help:
   - If you have a Docker subscription and are signed in, select **Contact support**. This opens the Docker Desktop support form. Fill in the information required and add the ID you copied in step three to the **Diagnostics ID field**. Then, select **Submit ticket** to request Docker Desktop support.
   - If you don't have a Docker subscription, you can open a new [Docker Desktop issue on GitHub](https://github.com/docker/desktop-feedback). Complete the information required and ensure you add the diagnostic ID printed in step two.

### Diagnose from the terminal

In some cases, it's useful to run the diagnostics yourself, for instance, if the Docker Desktop Dashboard cannot start.

Run the [`docker desktop diagnose`](/manuals/desktop/features/desktop-cli.md) command:

```console
$ docker desktop diagnose
```

Gathering diagnostics may take several minutes. Wait for the process to complete before closing the terminal.

After the diagnostics have finished, the terminal displays your diagnostics ID and the path to the diagnostics file. The diagnostics ID is composed of your user ID and a timestamp. For example `BE9AFAAF-F68B-41D0-9D12-84760E6B8740/20190905152051`.

Alternatively, you can use the `com.docker.diagnose` tool:

{{< tabs group="os" >}}
{{< tab name="Windows" >}}

1. Locate the `com.docker.diagnose` tool:

   ```console
   # For all-user installations
   $ C:\Program Files\Docker\Docker\resources\com.docker.diagnose.exe

   # For per-user installations
   $ %LOCALAPPDATA%\Programs\DockerDesktop\resources\com.docker.diagnose.exe
   ```

2. Create and upload the diagnostics ID. In PowerShell, run:

   ```console
   # For all-user installations
   $ & "C:\Program Files\Docker\Docker\resources\com.docker.diagnose.exe" gather -upload

   # For per-user installations
   $ & %LOCALAPPDATA%\Programs\DockerDesktop\resources\com.docker.diagnose.exe" gather -upload
   ```

After the diagnostics have finished, the terminal displays your diagnostics ID and the path to the diagnostics file. The diagnostics ID is composed of your user ID and a timestamp. For example `BE9AFAAF-F68B-41D0-9D12-84760E6B8740/20190905152051`.

{{< /tab >}}
{{< tab name="Mac" >}}

1. Locate the `com.docker.diagnose` tool:

   ```console
   $ /Applications/Docker.app/Contents/MacOS/com.docker.diagnose
   ```

2. Create and upload the diagnostics ID. Run:

   ```console
   $ /Applications/Docker.app/Contents/MacOS/com.docker.diagnose gather -upload
   ```

After the diagnostics have finished, the terminal displays your diagnostics ID and the path to the diagnostics file. The diagnostics ID is composed of your user ID and a timestamp. For example `BE9AFAAF-F68B-41D0-9D12-84760E6B8740/20190905152051`.

{{< /tab >}}
{{< tab name="Linux" >}}

1. Locate the `com.docker.diagnose` tool:

   ```console
   $ /opt/docker-desktop/bin/com.docker.diagnose
   ```

2. Create and upload the diagnostics ID. Run:

   ```console
   $ /opt/docker-desktop/bin/com.docker.diagnose gather -upload
   ```

After the diagnostics have finished, the terminal displays your diagnostics ID and the path to the diagnostics file. The diagnostics ID is composed of your user ID and a timestamp. For example `BE9AFAAF-F68B-41D0-9D12-84760E6B8740/20190905152051`.

{{< /tab >}}
{{< /tabs >}}

To view the contents of the diagnostic file:

{{< tabs group="os" >}}
{{< tab name="Windows" >}}

1. Unzip the file. In PowerShell, copy and paste the path to the diagnostics file into the following command and then run it. It should be similar to the following example:

   ```powershell
   $ Expand-Archive -LiteralPath "C:\Users\testUser\AppData\Local\Temp\5DE9978A-3848-429E-8776-950FC869186F\20230607101602.zip" -DestinationPath "C:\Users\testuser\AppData\Local\Temp\5DE9978A-3848-429E-8776-950FC869186F\20230607101602"
   ```

2. Open the file in your preferred text editor. Run:

   ```powershell
   $ code <path-to-file>
   ```

{{< /tab >}}
{{< tab name="Mac" >}}

Run:

```console
$ open /tmp/<your-diagnostics-ID>.zip
```

{{< /tab >}}
{{< tab name="Linux" >}}

Run:

```console
$ unzip –l /tmp/<your-diagnostics-ID>.zip
```

{{< /tab >}}
{{< /tabs >}}

#### Use your diagnostics ID to get help

If you have a Docker subscription, [Contact support](https://app.docker.com/support/contact). Fill in the information required and add your diagnostics ID.

If you don't have a Docker subscription, create an issue on [GitHub](https://github.com/docker/desktop-feedback).

## Check the logs

In addition to using the diagnose option to submit logs, you can browse the logs yourself.

To access Docker Desktop logs, run:

```console
$ docker desktop diagnose
```

## View the Docker daemon logs

Refer to the [Read the daemon logs](/manuals/engine/daemon/logs.md) section
to learn how to view the Docker Daemon logs.

## Further resources

- View specific [troubleshoot topics](topics.md).
- [Get support for Docker products](/manuals/support/_index.md)

---

### Manuals Dhi Explore Security Concepts  Index (`content/manuals/dhi/explore/security-concepts/_index.md`)

---
aliases:
  - /dhi/core-concepts/
title: Security concepts
linkTitle: Security concepts
description: Learn the core concepts behind Docker Hardened Images, including security metadata, vulnerability management, image structure, and verification.
weight: 60
params:
  grid_concepts_metadata:
    - title: Attestations
      description: Review the full set of signed attestations included with each Docker Hardened Image, such as SBOMs, VEX, build provenance, and scan results.
      icon: clipboard-document-list
      link: /dhi/explore/security-concepts/attestations/
    - title: Software Bill of Materials (SBOMs)
      description: Learn what SBOMs are, why they matter, and how Docker Hardened Images include signed SBOMs to support transparency and compliance.
      icon: list-bullet
      link: /dhi/explore/security-concepts/sbom/
    - title: Supply-chain Levels for Software Artifacts (SLSA)
      description: Learn how Docker Hardened Images comply with SLSA Build Level 3 and how to verify provenance for secure, tamper-resistant builds.
      icon: clipboard-document-check
      link: /dhi/explore/security-concepts/slsa/
    - title: Image provenance
      description: Learn how build provenance metadata helps trace the origin of Docker Hardened Images and support compliance with SLSA.
      icon: pencil-square
      link: /dhi/explore/security-concepts/provenance/

  grid_concepts_compliance:
    - title: FIPS
      description: Learn how Docker Hardened Images support FIPS 140 by using validated cryptographic modules and providing signed attestations for compliance audits.
      icon: check-badge
      link: /dhi/explore/security-concepts/fips/
    - title: STIG
      description: Learn how Docker Hardened Images provide STIG-ready container images with verifiable security scan attestations for government and enterprise compliance requirements.
      icon: shield-check
      link: /dhi/explore/security-concepts/stig/
    - title: CIS Benchmarks
      description: Learn how Docker Hardened Images help you meet Center for Internet Security (CIS) Docker Benchmark requirements for secure container configuration and deployment.
      icon: check-circle
      link: /dhi/explore/security-concepts/cis/

  grid_concepts_risk:
    - title: Common Vulnerabilities and Exposures (CVEs)
      description: Understand what CVEs are, how Docker Hardened Images reduce exposure, and how to scan images for vulnerabilities using popular tools.
      icon: exclamation-circle
      link: /dhi/explore/security-concepts/cves/
    - title: Vulnerability Exploitability eXchange (VEX)
      description: Learn how VEX helps you prioritize real risks by identifying which vulnerabilities in Docker Hardened Images are actually exploitable.
      icon: exclamation-triangle
      link: /dhi/explore/security-concepts/vex/
    - title: Software Supply Chain Security
      description: Learn how Docker Hardened Images help secure every stage of your software supply chain with signed metadata, provenance, and minimal attack surface.
      icon: shield-check
      link: /dhi/explore/security-concepts/sscs/
    - title: Secure Software Development Lifecycle (SSDLC)
      description: See how Docker Hardened Images support a secure SDLC by integrating with scanning, signing, and debugging tools.
      icon: wrench-screwdriver
      link: /dhi/explore/security-concepts/ssdlc/

  grid_concepts_structure:
    - title: Distroless images
      description: Learn how Docker Hardened Images use distroless variants to minimize attack surface and remove unnecessary components.
      icon: squares-2x2
      link: /dhi/explore/security-concepts/distroless/
    - title: glibc and musl support in Docker Hardened Images
      description: Compare glibc and musl variants of DHIs to choose the right base image for your application’s compatibility, size, and performance needs.
      icon: arrows-up-down
      link: /dhi/explore/security-concepts/glibc-musl/
    - title: Image immutability
      description: Understand how image digests, read-only containers, and signed metadata ensure Docker Hardened Images are tamper-resistant and immutable.
      icon: minus-circle
      link: /dhi/explore/security-concepts/immutability/
    - title: Image hardening
      description: Learn how Docker Hardened Images are designed for security, with minimal components, nonroot execution, and secure-by-default configurations.
      icon: shield-check
      link: /dhi/explore/security-concepts/hardening/

  grid_concepts_verification:
    - title: Digests
      description: Learn how to use immutable image digests to guarantee consistency and verify the exact Docker Hardened Image you're running.
      icon: finger-print
      link: /dhi/explore/security-concepts/digests/
    - title: Code signing
      description: Understand how Docker Hardened Images are cryptographically signed using Cosign to verify authenticity, integrity, and secure provenance.
      icon: key
      link: /dhi/explore/security-concepts/signatures/
---

Docker Hardened Images (DHIs) are built on a foundation of secure software
supply chain practices. This section explains the core concepts behind that
foundation, from signed attestations and immutable digests to standards like SLSA
and VEX.

Start here if you want to understand how Docker Hardened Images support compliance,
transparency, and security.


## Security metadata and attestations

{{< grid items="grid_concepts_metadata" >}}

## Compliance standards

{{< grid items="grid_concepts_compliance" >}}

## Vulnerability and risk management

{{< grid items="grid_concepts_risk" >}}

## Image structure and behavior

{{< grid items="grid_concepts_structure" >}}

## Verification and traceability

{{< grid items="grid_concepts_verification" >}}

---

### Manuals Dhi Migration Examples  Index (`content/manuals/dhi/migration/examples/_index.md`)

---
title: Migration examples
description: Real-world examples of migrating to Docker Hardened Images
weight: 40
keywords: migration examples, dhi, docker hardened images
params:
  grid_examples:
    - title: Go
      description: Learn how to migrate Go applications to Docker Hardened Images with practical examples and best practices.
      icon: code-bracket
      link: /dhi/migration/examples/go/
    - title: Python
      description: Learn how to migrate Python applications to Docker Hardened Images with practical examples and best practices.
      icon: code-bracket
      link: /dhi/migration/examples/python/
    - title: Node.js
      description: Learn how to migrate Node.js applications to Docker Hardened Images with practical examples and best practices.
      icon: code-bracket
      link: /dhi/migration/examples/node/
    - title: .NET
      description: Learn how to migrate .NET applications to Docker Hardened Images with practical examples and best practices.
      icon: code-bracket
      link: /dhi/migration/examples/dotnet/
    - title: Java
      description: Learn how to migrate Java applications to Docker Hardened Images with practical examples and best practices.
      icon: code-bracket
      link: /dhi/migration/examples/java/
---

This section provides detailed migration examples for common programming languages and frameworks.

## Available examples

{{< grid items="grid_examples" >}}

In addition to this documentation, each Docker Hardened Image repository in
the [Docker Hardened Images
catalog](https://hub.docker.com/hardened-images/catalog) includes image-specific
guidance and best practices for migrating applications built with that language
or framework.

---

### Manuals Docker Hub Repos Manage  Index (`content/manuals/docker-hub/repos/manage/_index.md`)

---
build:
  render: never
title: Manage
weight: 30
---

---

### Manuals Engine Logging Drivers  Index (`content/manuals/engine/logging/drivers/_index.md`)

---
build:
  render: never
title: Logging drivers
---

---

### Manuals Engine Network Drivers  Index (`content/manuals/engine/network/drivers/_index.md`)

---
title: Network drivers
weight: 20
description: Learn the basics of Docker network drivers
keywords: networking, drivers, bridge, routing, routing mesh, overlay, ports
---

Docker's networking subsystem is pluggable, using drivers. Several drivers
exist by default, and provide core networking functionality:

- `bridge`: The default network driver. If you don't specify a driver, this is
  the type of network you are creating. Bridge networks are commonly used when
  your application runs in a container that needs to communicate with other
  containers on the same host.
  See [Bridge network driver](bridge.md).

- `host`: Remove network isolation between the container and the Docker host,
  and use the host's networking directly.
  See [Host network driver](host.md).

- `overlay`: Overlay networks connect multiple Docker daemons together and
  enable Swarm services and containers to communicate across nodes. This
  strategy removes the need to do OS-level routing.
  See [Overlay network driver](overlay.md).

- `ipvlan`: IPvlan networks give users total control over both IPv4 and IPv6
  addressing. The VLAN driver builds on top of that in giving operators complete
  control of layer 2 VLAN tagging and even IPvlan L3 routing for users
  interested in underlay network integration.
  See [IPvlan network driver](ipvlan.md).

- `macvlan`: Macvlan networks allow you to assign a MAC address to a container,
  making it appear as a physical device on your network. The Docker daemon
  routes traffic to containers by their MAC addresses. Using the `macvlan`
  driver is sometimes the best choice when dealing with legacy applications that
  expect to be directly connected to the physical network, rather than routed
  through the Docker host's network stack.
  See [Macvlan network driver](macvlan.md).

- `none`: Completely isolate a container from the host and other containers.
  `none` is not available for Swarm services.
  See [None network driver](none.md).

- [Network plugins](/engine/extend/plugins_network/): You can install and use
  third-party network plugins with Docker.

### Network driver summary

- The default bridge network is good for running containers that don't require
  special networking capabilities.
- User-defined bridge networks enable containers on the same Docker host to
  communicate with each other. A user-defined network typically defines an
  isolated network for multiple containers belonging to a common project or
  component.
- Host network shares the host's network with the container. When you use this
  driver, the container's network isn't isolated from the host.
- Overlay networks are best when you need containers running on different
  Docker hosts to communicate, or when multiple applications work together
  using Swarm services.
- Macvlan networks are best when you are migrating from a VM setup or need your
  containers to look like physical hosts on your network, each with a unique
  MAC address.
- IPvlan is similar to Macvlan, but doesn't assign unique MAC addresses to
  containers. Consider using IPvlan when there's a restriction on the number of
  MAC addresses that can be assigned to a network interface or port.
- Third-party network plugins allow you to integrate Docker with specialized
  network stacks.

## Next steps

Each driver page includes detailed explanations, configuration options, and
hands-on usage examples to help you work with that driver effectively.

---

### Manuals Engine Security Rootless  Index (`content/manuals/engine/security/rootless/_index.md`)

---
description: Run the Docker daemon as a non-root user (Rootless mode)
keywords: security, namespaces, rootless
title: Rootless mode
weight: 10
---

Rootless mode lets you run the Docker daemon and containers as a non-root
user to mitigate potential vulnerabilities in the daemon and
the container runtime.

Rootless mode does not require root privileges even during the installation of
the Docker daemon, as long as the [prerequisites](#prerequisites) are met.

## How it works

Rootless mode executes the Docker daemon and containers inside a user namespace.
This is similar to [`userns-remap` mode](../userns-remap.md), except that
with `userns-remap` mode, the daemon itself is running with root privileges,
whereas in rootless mode, both the daemon and the container are running without
root privileges.

The two modes also differ in how they map container UIDs and GIDs to the
host: see [UID/GID mapping](uid-gid-mapping/) for details.

Rootless mode does not use binaries with `SETUID` bits or file capabilities,
except `newuidmap` and `newgidmap`, which are needed to allow multiple
UIDs/GIDs to be used in the user namespace.


## Prerequisites

-  You must install `newuidmap` and `newgidmap` on the host. These commands
  are provided by the `uidmap` package on most distributions.

- `/etc/subuid` and `/etc/subgid` should contain at least 65,536 subordinate
  UIDs/GIDs for the user. In the following example, the user `testuser` has
  65,536 subordinate UIDs/GIDs (231072-296607).

```console
$ id -u
1001
$ whoami
testuser
$ grep ^$(whoami): /etc/subuid
testuser:231072:65536
$ grep ^$(whoami): /etc/subgid
testuser:231072:65536
```

The `dockerd-rootless-setuptool.sh install` script (see following) automatically shows help
when the prerequisites are not satisfied.

## Install

> [!NOTE]
>
> If the system-wide Docker daemon is already running, consider disabling it:
>```console
>$ sudo systemctl disable --now docker.service docker.socket
>$ sudo rm /var/run/docker.sock
>```
> Should you choose not to shut down the `docker` service and socket, you will need to use the `--force`
> parameter in the next section. There are no known issues, but until you shutdown and disable you're
> still running rootful Docker. 

{{< tabs >}}
{{< tab name="With packages (RPM/DEB)" >}}

If you installed Docker 20.10 or later with [RPM/DEB packages](/engine/install), you should have `dockerd-rootless-setuptool.sh` in `/usr/bin`.

Run `dockerd-rootless-setuptool.sh install` as a non-root user to set up the daemon:

```console
$ dockerd-rootless-setuptool.sh install
[INFO] Creating /home/testuser/.config/systemd/user/docker.service
...
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger testuser`

[INFO] Creating CLI context "rootless"
Successfully created context "rootless"
[INFO] Using CLI context "rootless"
Current context is now "rootless"

[INFO] Make sure the following environment variable(s) are set (or add them to ~/.bashrc):
export PATH=/usr/bin:$PATH

[INFO] Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///run/user/1000/docker.sock
```

If `dockerd-rootless-setuptool.sh` is not present, you may need to install the `docker-ce-rootless-extras` package manually, e.g.,

```console
$ sudo apt-get install -y docker-ce-rootless-extras
```

{{< /tab >}}
{{< tab name="Without packages" >}}

If you do not have permission to run package managers like `apt-get` and `dnf`,
consider using the installation script available at [https://get.docker.com/rootless](https://get.docker.com/rootless).
Since static packages are not available for `s390x`, hence it is not supported for `s390x`.

```console
$ curl -fsSL https://get.docker.com/rootless | sh
...
[INFO] Creating /home/testuser/.config/systemd/user/docker.service
...
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger testuser`

[INFO] Creating CLI context "rootless"
Successfully created context "rootless"
[INFO] Using CLI context "rootless"
Current context is now "rootless"

[INFO] Make sure the following environment variable(s) are set (or add them to ~/.bashrc):
export PATH=/home/testuser/bin:$PATH

[INFO] Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///run/user/1000/docker.sock
```

The binaries will be installed at `~/bin`.

{{< /tab >}}
{{< /tabs >}}

Run `docker info` to confirm that the `docker` client is connecting to the Rootless daemon:
```console
$ docker info
Client: Docker Engine - Community
 Version:    28.3.3
 Context:    rootless
...
Server:
...
 Security Options:
  seccomp
   Profile: builtin
  rootless
  cgroupns
...
```

See [Troubleshooting](./troubleshoot.md) if you faced an error.

---

### Manuals Engine Security Trust  Index (`content/manuals/engine/security/trust/_index.md`)

---
description: Enabling content trust in Docker
keywords: content, trust, security, docker, documentation
title: Content trust in Docker
aliases:
- /engine/security/trust/content_trust/
- /notary/getting_started/
- /notary/advanced_usage/
- /notary/service_architecture/
- /notary/running_a_service/
- /notary/changelog/
- /notary/reference/server-config/
- /notary/reference/signer-config/
- /notary/reference/client-config/
- /notary/reference/common-configs/
---

When transferring data among networked systems, trust is a central concern. In
particular, when communicating over an untrusted medium such as the internet, it
is critical to ensure the integrity and the publisher of all the data a system
operates on. You use Docker Engine to push and pull images (data) to a
public or private registry. Content trust gives you the ability to verify both
the integrity and the publisher of all the data received from a registry over
any channel.

## About Docker Content Trust (DCT)

Docker Content Trust (DCT) provides the ability to use digital signatures for
data sent to and received from remote Docker registries. These signatures allow
client-side or runtime verification of the integrity and publisher of specific
image tags.

Through DCT, image publishers can sign their images and image consumers can
ensure that the images they pull are signed. Publishers could be individuals
or organizations manually signing their content or automated software supply
chains signing content as part of their release process.

> [!WARNING]
>
> Docker Content Trust (DCT) is being retired. The Notary v1 service at
> `notary.docker.io` will shut down on December 8, 2026. For more information, see
> [Docker Content Trust (DCT)](/manuals/retired.md#docker-content-trust-dct).

### Image tags and DCT

An individual image record has the following identifier:

```text
[REGISTRY_HOST[:REGISTRY_PORT]/]REPOSITORY[:TAG]
```

A particular image `REPOSITORY` can have multiple tags. For example, `latest` and
 `3.1.2` are both tags on the `mongo` image. An image publisher can build an image
 and tag combination many times changing the image with each build.

DCT is associated with the `TAG` portion of an image. Each image repository has
a set of keys that image publishers use to sign an image tag. Image publishers
have discretion on which tags they sign.

An image repository can contain an image with one tag that is signed and another
tag that is not. For example, consider [the Mongo image
repository](https://hub.docker.com/_/mongo/tags/). The `latest`
tag could be unsigned while the `3.1.6` tag could be signed. It is the
responsibility of the image publisher to decide if an image tag is signed or
not. In this representation, some image tags are signed, others are not:



Publishers can choose to sign a specific tag or not. As a result, the content of
an unsigned tag and that of a signed tag with the same name may not match. For
example, a publisher can push a tagged image `someimage:latest` and sign it.
Later, the same publisher can push an unsigned `someimage:latest` image. This second
push replaces the last unsigned tag `latest` but does not affect the signed `latest` version.
The ability to choose which tags they can sign, allows publishers to iterate over
the unsigned version of an image before officially signing it.

Image consumers can enable DCT to ensure that images they use were signed. If a
consumer enables DCT, they can only pull, run, or build with trusted images.
Enabling DCT is a bit like applying a "filter" to your registry. Consumers "see"
only signed image tags and the less desirable, unsigned image tags are
"invisible" to them.



To the consumer who has not enabled DCT, nothing about how they work with Docker
images changes. Every image is visible regardless of whether it is signed or
not.

### Docker Content Trust Keys

Trust for an image tag is managed through the use of signing keys. A key set is
created when an operation using DCT is first invoked. A key set consists
of the following classes of keys:

- An offline key that is the root of DCT for an image tag
- Repository or tagging keys that sign tags
- Server-managed keys such as the timestamp key, which provides freshness
	security guarantees for your repository

The following image depicts the various signing keys and their relationships:



> [!WARNING]
>
>The root key once lost is not recoverable. If you lose any other key, send an email to [Docker Hub Support](mailto:hub-support@docker.com). This loss also requires manual intervention from every
consumer that used a signed tag from this repository prior to the loss.

You should back up the root key somewhere safe. Given that it is only required
to create new repositories, it is a good idea to store it offline in hardware.
For details on securing, and backing up your keys, make sure you
read how to [manage keys for DCT](trust_key_mng.md).

## Signing images with Docker Content Trust

Within the Docker CLI we can sign and push a container image with the
`$ docker trust` command syntax. This is built on top of the Notary feature
set. For more information, see the [Notary GitHub repository](https://github.com/theupdateframework/notary).

A prerequisite for signing an image is a Docker Registry with a Notary server (such as Docker Hub) attached.
Refer to [Deploying Notary](/engine/security/trust/deploying_notary/) for instructions.

To sign a Docker Image you will need a delegation key pair. These keys
can be generated locally using `$ docker trust key generate` or generated
by a certificate authority.

First we will add the delegation private key to the local Docker trust
repository. (By default this is stored in `~/.docker/trust/`). If you are
generating delegation keys with `$ docker trust key generate`, the private key
is automatically added to the local trust store. If you are importing a separate
key, you will need to use the
`$ docker trust key load` command.

```console
$ docker trust key generate jeff
Generating key for jeff...
Enter passphrase for new jeff key with ID 9deed25:
Repeat passphrase for new jeff key with ID 9deed25:
Successfully generated and loaded private key. Corresponding public key available: /home/ubuntu/Documents/mytrustdir/jeff.pub
```

Or if you have an existing key:

```console
$ docker trust key load key.pem --name jeff
Loading key from "key.pem"...
Enter passphrase for new jeff key with ID 8ae710e:
Repeat passphrase for new jeff key with ID 8ae710e:
Successfully imported key from key.pem
```

Next we will need to add the delegation public key to the Notary server;
this is specific to a particular image repository in Notary known as a Global
Unique Name (GUN). If this is the first time you are adding a delegation to that
repository, this command will also initiate the repository, using a local Notary
canonical root key. To understand more about initiating a repository, and the
role of delegations, head to
[delegations for content trust](trust_delegation.md).

```console
$ docker trust signer add --key cert.pem jeff registry.example.com/admin/demo
Adding signer "jeff" to registry.example.com/admin/demo...
Enter passphrase for new repository key with ID 10b5e94:
```

Finally, we will use the delegation private key to sign a particular tag and
push it up to the registry.

```console
$ docker trust sign registry.example.com/admin/demo:1
Signing and pushing trust data for local image registry.example.com/admin/demo:1, may overwrite remote trust data
The push refers to repository [registry.example.com/admin/demo]
7bff100f35cb: Pushed
1: digest: sha256:3d2e482b82608d153a374df3357c0291589a61cc194ec4a9ca2381073a17f58e size: 528
Signing and pushing trust metadata
Enter passphrase for signer key with ID 8ae710e:
Successfully signed registry.example.com/admin/demo:1
```

Alternatively, once the keys have been imported an image can be pushed with the
`$ docker push` command, by exporting the DCT environmental variable.

```console
$ export DOCKER_CONTENT_TRUST=1

$ docker push registry.example.com/admin/demo:1
The push refers to repository [registry.example.com/admin/demo:1]
7bff100f35cb: Pushed
1: digest: sha256:3d2e482b82608d153a374df3357c0291589a61cc194ec4a9ca2381073a17f58e size: 528
Signing and pushing trust metadata
Enter passphrase for signer key with ID 8ae710e:
Successfully signed registry.example.com/admin/demo:1
```

Remote trust data for a tag or a repository can be viewed by the
`$ docker trust inspect` command:

```console
$ docker trust inspect --pretty registry.example.com/admin/demo:1

Signatures for registry.example.com/admin/demo:1

SIGNED TAG          DIGEST                                                             SIGNERS
1                   3d2e482b82608d153a374df3357c0291589a61cc194ec4a9ca2381073a17f58e   jeff

List of signers and their keys for registry.example.com/admin/demo:1

SIGNER              KEYS
jeff                8ae710e3ba82

Administrative keys for registry.example.com/admin/demo:1

  Repository Key:	10b5e94c916a0977471cc08fa56c1a5679819b2005ba6a257aa78ce76d3a1e27
  Root Key:	84ca6e4416416d78c4597e754f38517bea95ab427e5f95871f90d460573071fc
```

Remote Trust data for a tag can be removed by the `$ docker trust revoke` command:

```console
$ docker trust revoke registry.example.com/admin/demo:1
Enter passphrase for signer key with ID 8ae710e:
Successfully deleted signature for registry.example.com/admin/demo:1
```

## Client enforcement with Docker Content Trust

Content trust is disabled by default in the Docker Client. To enable
it, set the `DOCKER_CONTENT_TRUST` environment variable to `1`. This prevents
users from working with tagged images unless they contain a signature.

When DCT is enabled in the Docker client, `docker` CLI commands that operate on
tagged images must either have content signatures or explicit content hashes.
The commands that operate with DCT are:

* `push`
* `build`
* `create`
* `pull`
* `run`

For example, with DCT enabled a `docker pull someimage:latest` only
succeeds if `someimage:latest` is signed. However, an operation with an explicit
content hash always succeeds as long as the hash exists:

```console
$ docker pull registry.example.com/user/image:1
Error: remote trust data does not exist for registry.example.com/user/image: registry.example.com does not have trust data for registry.example.com/user/image

$ docker pull registry.example.com/user/image@sha256:d149ab53f8718e987c3a3024bb8aa0e2caadf6c0328f1d9d850b2a2a67f2819a
sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1: Pulling from user/image
ff3a5c916c92: Pull complete
a59a168caba3: Pull complete
Digest: sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1
Status: Downloaded newer image for registry.example.com/user/image@sha256:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1
```

## Related information

* [Delegations for content trust](trust_delegation.md)
* [Automation with content trust](trust_automation.md)
* [Manage keys for content trust](trust_key_mng.md)
* [Play in a content trust sandbox](trust_sandbox.md)

---

### Manuals Engine Storage Drivers  Index (`content/manuals/engine/storage/drivers/_index.md`)

---
description: Learn the technologies that support storage drivers.
keywords: container, storage, driver, btrfs, overlayfs, vfs, zfs, containerd
title: Storage drivers
weight: 40
aliases:
  - /storage/storagedriver/imagesandcontainers/
  - /storage/storagedriver/
  - /engine/userguide/storagedriver/imagesandcontainers/
---

> [!NOTE]
> This page describes the classic storage drivers, such as `overlay2`. Docker
> Engine 29.0 and later uses the [containerd image store](../containerd.md) by
> default for fresh installations, which uses snapshotters instead of classic
> storage drivers. If you're running a fresh installation of Docker Engine 29.0
> or later, or if you've migrated to the containerd image store, the concepts on
> this page still explain how image layers work, but the commands and examples
> won't reflect how your system stores images. For operational guidance, see
> [containerd image store](../containerd.md).

To use storage drivers effectively, it's important to know how Docker builds and
stores images, and how these images are used by containers. You can use this
information to make informed choices about the best way to persist data from
your applications and avoid performance problems along the way.

## Storage drivers versus Docker volumes

Docker uses storage drivers to store image layers, and to store data in the
writable layer of a container. The container's writable layer doesn't persist
after the container is deleted, but is suitable for storing ephemeral data that
is generated at runtime. Storage drivers are optimized for space efficiency, but
(depending on the storage driver) write speeds are lower than native file system
performance, especially for storage drivers that use a copy-on-write filesystem.
Write-intensive applications, such as database storage, are impacted by a
performance overhead, particularly if pre-existing data exists in the read-only
layer.

Use Docker volumes for write-intensive data, data that must persist beyond the
container's lifespan, and data that must be shared between containers. Refer to
the [volumes section](../volumes.md) to learn how to use volumes to persist data
and improve performance.

## Images and layers

A Docker image is built up from a series of layers. Each layer represents an
instruction in the image's Dockerfile. Each layer except the very last one is
read-only. Consider the following Dockerfile:

```dockerfile
# syntax=docker/dockerfile:1

FROM ubuntu:22.04
LABEL org.opencontainers.image.authors="org@example.com"
COPY . /app
RUN make /app
RUN rm -r $HOME/.cache
CMD python /app/app.py
```

This Dockerfile contains four commands. Commands that modify the filesystem create
a new layer. The `FROM` statement starts out by creating a layer from the `ubuntu:22.04`
image. The `LABEL` command only modifies the image's metadata, and doesn't produce
a new layer. The `COPY` command adds some files from your Docker client's current
directory. The first `RUN` command builds your application using the `make` command,
and writes the result to a new layer. The second `RUN` command removes a cache
directory, and writes the result to a new layer. Finally, the `CMD` instruction
specifies what command to run within the container, which only modifies the
image's metadata, which doesn't produce an image layer.

Each layer is only a set of differences from the layer before it. Note that both
_adding_, and _removing_ files will result in a new layer. In the example above,
the `$HOME/.cache` directory is removed, but will still be available in the
previous layer and add up to the image's total size. Refer to the
[Best practices for writing Dockerfiles](/manuals/build/building/best-practices.md)
and [use multi-stage builds](/manuals/build/building/multi-stage.md)
sections to learn how to optimize your Dockerfiles for efficient images.

The layers are stacked on top of each other. When you create a new container,
you add a new writable layer on top of the underlying layers. This layer is often
called the "container layer". All changes made to the running container, such as
writing new files, modifying existing files, and deleting files, are written to
this thin writable container layer. The diagram below shows a container based
on an `ubuntu:15.04` image.



A storage driver handles the details about the way these layers interact with
each other. Different storage drivers are available, which have advantages
and disadvantages in different situations.

## Container and layers

The major difference between a container and an image is the top writable layer.
All writes to the container that add new or modify existing data are stored in
this writable layer. When the container is deleted, the writable layer is also
deleted. The underlying image remains unchanged.

Because each container has its own writable container layer, and all changes are
stored in this container layer, multiple containers can share access to the same
underlying image and yet have their own data state. The diagram below shows
multiple containers sharing the same Ubuntu 15.04 image.



Docker uses storage drivers to manage the contents of the image layers and the
writable container layer. Each storage driver handles the implementation
differently, but all drivers use stackable image layers and the copy-on-write
(CoW) strategy.

> [!NOTE]
>
> Use Docker volumes if you need multiple containers to have shared access to
> the exact same data. Refer to the [volumes section](../volumes.md) to learn
> about volumes.

## Container size on disk

To view the approximate size of a running container, you can use the `docker ps -s`
command. Two different columns relate to size.

- `size`: the amount of data (on disk) that's used for the writable layer of
  each container.
- `virtual size`: the amount of data used for the read-only image data
  used by the container plus the container's writable layer `size`.
  Multiple containers may share some or all read-only
  image data. Two containers started from the same image share 100% of the
  read-only data, while two containers with different images which have layers
  in common share those common layers. Therefore, you can't just total the
  virtual sizes. This over-estimates the total disk usage by a potentially
  non-trivial amount.

The total disk space used by all of the running containers on disk is some
combination of each container's `size` and the `virtual size` values. If
multiple containers started from the same exact image, the total size on disk for
these containers would be SUM (`size` of containers) plus one image size
(`virtual size` - `size`).

This also doesn't count the following additional ways a container can take up
disk space:

- Disk space used for log files stored by the [logging-driver](/manuals/engine/logging/_index.md).
  This can be non-trivial if your container generates a large amount of logging
  data and log rotation isn't configured.
- Volumes and bind mounts used by the container.
- Disk space used for the container's configuration files, which are typically
  small.
- Memory written to disk (if swapping is enabled).
- Checkpoints, if you're using the experimental checkpoint/restore feature.

## The copy-on-write (CoW) strategy

Copy-on-write is a strategy of sharing and copying files for maximum efficiency.
If a file or directory exists in a lower layer within the image, and another
layer (including the writable layer) needs read access to it, it just uses the
existing file. The first time another layer needs to modify the file (when
building the image or running the container), the file is copied into that layer
and modified. This minimizes I/O and the size of each of the subsequent layers.
These advantages are explained in more depth below.

### Sharing promotes smaller images

When you use `docker pull` to pull down an image from a repository, or when you
create a container from an image that doesn't yet exist locally, each layer is
pulled down separately, and stored in Docker's local storage area, which is
usually `/var/lib/docker/` on Linux hosts. You can see these layers being pulled
in this example:

```console
$ docker pull ubuntu:22.04
22.04: Pulling from library/ubuntu
f476d66f5408: Pull complete
8882c27f669e: Pull complete
d9af21273955: Pull complete
f5029279ec12: Pull complete
Digest: sha256:6120be6a2b7ce665d0cbddc3ce6eae60fe94637c6a66985312d1f02f63cc0bcd
Status: Downloaded newer image for ubuntu:22.04
docker.io/library/ubuntu:22.04
```

Each of these layers is stored in its own directory inside the Docker host's
local storage area. To examine the layers on the filesystem, list the contents
of `/var/lib/docker/<storage-driver>`. This example uses the `overlay2`
storage driver:

```console
$ ls /var/lib/docker/overlay2
16802227a96c24dcbeab5b37821e2b67a9f921749cd9a2e386d5a6d5bc6fc6d3
377d73dbb466e0bc7c9ee23166771b35ebdbe02ef17753d79fd3571d4ce659d7
3f02d96212b03e3383160d31d7c6aeca750d2d8a1879965b89fe8146594c453d
ec1ec45792908e90484f7e629330666e7eee599f08729c93890a7205a6ba35f5
l
```

The directory names don't correspond to the layer IDs.

Now imagine that you have two different Dockerfiles. You use the first one to
create an image called `acme/my-base-image:1.0`.

```dockerfile
# syntax=docker/dockerfile:1
FROM alpine
RUN apk add --no-cache bash
```

The second one is based on `acme/my-base-image:1.0`, but has some additional
layers:

```dockerfile
# syntax=docker/dockerfile:1
FROM acme/my-base-image:1.0
COPY . /app
RUN chmod +x /app/hello.sh
CMD /app/hello.sh
```

The second image contains all the layers from the first image, plus new layers
created by the `COPY` and `RUN` instructions, and a read-write container layer.
Docker already has all the layers from the first image, so it doesn't need to
pull them again. The two images share any layers they have in common.

If you build images from the two Dockerfiles, you can use `docker image ls` and
`docker image history` commands to verify that the cryptographic IDs of the shared
layers are the same.

1. Make a new directory `cow-test/` and change into it.

2. Within `cow-test/`, create a new file called `hello.sh` with the following contents.

   ```bash
   #!/usr/bin/env bash
   echo "Hello world"
   ```

3. Copy the contents of the first Dockerfile above into a new file called
   `Dockerfile.base`.

4. Copy the contents of the second Dockerfile above into a new file called
   `Dockerfile`.

5. Within the `cow-test/` directory, build the first image. Don't forget to
   include the final `.` in the command. That sets the `PATH`, which tells
   Docker where to look for any files that need to be added to the image.

   ```
/* Detailed source-code truncated for AI context efficiency. */
```

6. Build the second image.

   ```
/* Detailed source-code truncated for AI context efficiency. */
```

7. Check out the sizes of the images.

   ```console
   $ docker image ls

   REPOSITORY             TAG     IMAGE ID         CREATED               SIZE
   acme/my-final-image    1.0     8bd85c42fa7f     About a minute ago    7.75MB
   acme/my-base-image     1.0     da3cf8df55ee     2 minutes ago         7.75MB
   ```

8. Check out the history of each image.

   ```console
   $ docker image history acme/my-base-image:1.0

   IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
   da3cf8df55ee   5 minutes ago   RUN /bin/sh -c apk add --no-cache bash # bui…   2.15MB    buildkit.dockerfile.v0
   <missing>      7 weeks ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
   <missing>      7 weeks ago     /bin/sh -c #(nop) ADD file:f278386b0cef68136…   5.6MB
   ```

   Some steps don't have a size (`0B`), and are metadata-only changes, which do
   not produce an image layer and don't take up any size, other than the metadata
   itself. The output above shows that this image consists of 2 image layers.

   ```console
   $ docker image history  acme/my-final-image:1.0

   IMAGE          CREATED         CREATED BY                                      SIZE      COMMENT
   8bd85c42fa7f   3 minutes ago   CMD ["/bin/sh" "-c" "/app/hello.sh"]            0B        buildkit.dockerfile.v0
   <missing>      3 minutes ago   RUN /bin/sh -c chmod +x /app/hello.sh # buil…   39B       buildkit.dockerfile.v0
   <missing>      3 minutes ago   COPY . /app # buildkit                          222B      buildkit.dockerfile.v0
   <missing>      4 minutes ago   RUN /bin/sh -c apk add --no-cache bash # bui…   2.15MB    buildkit.dockerfile.v0
   <missing>      7 weeks ago     /bin/sh -c #(nop)  CMD ["/bin/sh"]              0B
   <missing>      7 weeks ago     /bin/sh -c #(nop) ADD file:f278386b0cef68136…   5.6MB
   ```

   Notice that all steps of the first image are also included in the final
   image. The final image includes the two layers from the first image, and
   two layers that were added in the second image.

   The `<missing>` lines in the `docker history` output indicate that those
   steps were either built on another system and part of the `alpine` image
   that was pulled from Docker Hub, or were built with BuildKit as builder.
   Before BuildKit, the "classic" builder would produce a new "intermediate"
   image for each step for caching purposes, and the `IMAGE` column would show
   the ID of that image.

   BuildKit uses its own caching mechanism, and no longer requires intermediate
   images for caching. Refer to [BuildKit](/manuals/build/buildkit/_index.md)
   to learn more about other enhancements made in BuildKit.

9. Check out the layers for each image

   Use the `docker image inspect` command to view the cryptographic IDs of the
   layers in each image:

   ```console
   $ docker image inspect --format "{{json .RootFS.Layers}}" acme/my-base-image:1.0
   [
     "sha256:72e830a4dff5f0d5225cdc0a320e85ab1ce06ea5673acfe8d83a7645cbd0e9cf",
     "sha256:07b4a9068b6af337e8b8f1f1dae3dd14185b2c0003a9a1f0a6fd2587495b204a"
   ]
   ```

   ```console
   $ docker image inspect --format "{{json .RootFS.Layers}}" acme/my-final-image:1.0
   [
     "sha256:72e830a4dff5f0d5225cdc0a320e85ab1ce06ea5673acfe8d83a7645cbd0e9cf",
     "sha256:07b4a9068b6af337e8b8f1f1dae3dd14185b2c0003a9a1f0a6fd2587495b204a",
     "sha256:cc644054967e516db4689b5282ee98e4bc4b11ea2255c9630309f559ab96562e",
     "sha256:e84fb818852626e89a09f5143dbc31fe7f0e0a6a24cd8d2eb68062b904337af4"
   ]
   ```

   Notice that the first two layers are identical in both images. The second
   image adds two additional layers. Shared image layers are only stored once
   in `/var/lib/docker/` and are also shared when pushing and pulling an image
   to an image registry. Shared image layers can therefore reduce network
   bandwidth and storage.

   > [!TIP]
   >
   > Format output of Docker commands with the `--format` option.
   >
   > The examples above use the `docker image inspect` command with the `--format`
   > option to view the layer IDs, formatted as a JSON array. The `--format`
   > option on Docker commands can be a powerful feature that allows you to
   > extract and format specific information from the output, without requiring
   > additional tools such as `awk` or `sed`. To learn more about formatting
   > the output of docker commands using the `--format` flag, refer to the
   > [format command and log output section](/manuals/engine/cli/formatting.md).
   > We also pretty-printed the JSON output using the [`jq` utility](https://stedolan.github.io/jq/)
   > for readability.

### Copying makes containers efficient

When you start a container, a thin writable container layer is added on top of
the other layers. Any changes the container makes to the filesystem are stored
here. Any files the container doesn't change don't get copied to this writable
layer. This means that the writable layer is as small as possible.

When an existing file in a container is modified, the storage driver performs a
copy-on-write operation. The specific steps involved depend on the specific
storage driver. For the `overlay2` driver, the copy-on-write operation follows
this rough sequence:

- Search through the image layers for the file to update. The process starts
  at the newest layer and works down to the base layer one layer at a time.
  When results are found, they're added to a cache to speed future operations.
- Perform a `copy_up` operation on the first copy of the file that's found, to
  copy the file to the container's writable layer.
- Any modifications are made to this copy of the file, and the container can't
  see the read-only copy of the file that exists in the lower layer.

Btrfs, ZFS, and other drivers handle the copy-on-write differently. You can
read more about the methods of these drivers later in their detailed
descriptions.

Containers that write a lot of data consume more space than containers
that don't. This is because most write operations consume new space in the
container's thin writable top layer. Note that changing the metadata of files,
for example, changing file permissions or ownership of a file, can also result
in a `copy_up` operation, therefore duplicating the file to the writable layer.

> [!TIP]
>
> Use volumes for write-heavy applications.
>
> Don't store the data in the container for write-heavy applications. Such
> applications, for example write-intensive databases, are known to be
> problematic particularly when pre-existing data exists in the read-only
> layer.
>
> Instead, use Docker volumes, which are independent of the running container,
> and designed to be efficient for I/O. In addition, volumes can be shared
> among containers and don't increase the size of your container's writable
> layer. Refer to the [use volumes](../volumes.md) section to learn about
> volumes.

A `copy_up` operation can incur a noticeable performance overhead. This overhead
is different depending on which storage driver is in use. Large files,
lots of layers, and deep directory trees can make the impact more noticeable.
This is mitigated by the fact that each `copy_up` operation only occurs the first
time a given file is modified.

To verify the way that copy-on-write works, the following procedure spins up 5
containers based on the `acme/my-final-image:1.0` image we built earlier and
examines how much room they take up.

1. From a terminal on your Docker host, run the following `docker run` commands.
   The strings at the end are the IDs of each container.

   ```console
   $ docker run -dit --name my_container_1 acme/my-final-image:1.0 bash \
     && docker run -dit --name my_container_2 acme/my-final-image:1.0 bash \
     && docker run -dit --name my_container_3 acme/my-final-image:1.0 bash \
     && docker run -dit --name my_container_4 acme/my-final-image:1.0 bash \
     && docker run -dit --name my_container_5 acme/my-final-image:1.0 bash

   40ebdd7634162eb42bdb1ba76a395095527e9c0aa40348e6c325bd0aa289423c
   a5ff32e2b551168b9498870faf16c9cd0af820edf8a5c157f7b80da59d01a107
   3ed3c1a10430e09f253704116965b01ca920202d52f3bf381fbb833b8ae356bc
   939b3bf9e7ece24bcffec57d974c939da2bdcc6a5077b5459c897c1e2fa37a39
   cddae31c314fbab3f7eabeb9b26733838187abc9a2ed53f97bd5b04cd7984a5a
   ```

2. Run the `docker ps` command with the `--size` option to verify the 5 containers
   are running, and to see each container's size.

   ```console
   $ docker ps --size --format "table {{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Size}}"

   CONTAINER ID   IMAGE                     NAMES            SIZE
   cddae31c314f   acme/my-final-image:1.0   my_container_5   0B (virtual 7.75MB)
   939b3bf9e7ec   acme/my-final-image:1.0   my_container_4   0B (virtual 7.75MB)
   3ed3c1a10430   acme/my-final-image:1.0   my_container_3   0B (virtual 7.75MB)
   a5ff32e2b551   acme/my-final-image:1.0   my_container_2   0B (virtual 7.75MB)
   40ebdd763416   acme/my-final-image:1.0   my_container_1   0B (virtual 7.75MB)
   ```

   The output above shows that all containers share the image's read-only layers
   (7.75MB), but no data was written to the container's filesystem, so no additional
   storage is used for the containers.

   {{< accordion title="Advanced: metadata and logs storage used for containers" >}}

   > [!NOTE]
   >
   > This step requires a Linux machine, and doesn't work on Docker Desktop, as
   > it requires access to the Docker Daemon's file storage.

   While the output of `docker ps` provides you information about disk space
   consumed by a container's writable layer, it doesn't include information
   about metadata and log-files stored for each container.

   More details can be obtained by exploring the Docker Daemon's storage
   location (`/var/lib/docker` by default).

   ```console
   $ sudo du -sh /var/lib/docker/containers/*

   36K  /var/lib/docker/containers/3ed3c1a10430e09f253704116965b01ca920202d52f3bf381fbb833b8ae356bc
   36K  /var/lib/docker/containers/40ebdd7634162eb42bdb1ba76a395095527e9c0aa40348e6c325bd0aa289423c
   36K  /var/lib/docker/containers/939b3bf9e7ece24bcffec57d974c939da2bdcc6a5077b5459c897c1e2fa37a39
   36K  /var/lib/docker/containers/a5ff32e2b551168b9498870faf16c9cd0af820edf8a5c157f7b80da59d01a107
   36K  /var/lib/docker/containers/cddae31c314fbab3f7eabeb9b26733838187abc9a2ed53f97bd5b04cd7984a5a
   ```

   Each of these containers only takes up 36k of space on the filesystem.

   {{< /accordion >}}

3. Per-container storage

   To demonstrate this, run the following command to write the word 'hello' to
   a file on the container's writable layer in containers `my_container_1`,
   `my_container_2`, and `my_container_3`:

   ```console
   $ for i in {1..3}; do docker exec my_container_$i sh -c 'printf hello > /out.txt'; done
   ```

   Running the `docker ps` command again afterward shows that those containers
   now consume 5 bytes each. This data is unique to each container, and not
   shared. The read-only layers of the containers aren't affected, and are still
   shared by all containers.

   ```console
   $ docker ps --size --format "table {{.ID}}\t{{.Image}}\t{{.Names}}\t{{.Size}}"

   CONTAINER ID   IMAGE                     NAMES            SIZE
   cddae31c314f   acme/my-final-image:1.0   my_container_5   0B (virtual 7.75MB)
   939b3bf9e7ec   acme/my-final-image:1.0   my_container_4   0B (virtual 7.75MB)
   3ed3c1a10430   acme/my-final-image:1.0   my_container_3   5B (virtual 7.75MB)
   a5ff32e2b551   acme/my-final-image:1.0   my_container_2   5B (virtual 7.75MB)
   40ebdd763416   acme/my-final-image:1.0   my_container_1   5B (virtual 7.75MB)
   ```

The previous examples illustrate how copy-on-write filesystems help make
containers efficient. Not only does copy-on-write save space, but it also
reduces container start-up time. When you create a container (or multiple
containers from the same image), Docker only needs to create the thin writable
container layer.

If Docker had to make an entire copy of the underlying image stack each time it
created a new container, container creation times and disk space used would be
significantly increased. This would be similar to the way that virtual machines
work, with one or more virtual disks per virtual machine. The [`vfs` storage](vfs-driver.md)
doesn't provide a CoW filesystem or other optimizations. When using this storage
driver, a full copy of the image's data is created for each container.

## Related information

- [Volumes](../volumes.md)
- [Select a storage driver](select-storage-driver.md)

---

### Manuals Engine Swarm How Swarm Mode Works  Index (`content/manuals/engine/swarm/how-swarm-mode-works/_index.md`)

---
build:
  render: never
title: How swarm works
---

---

### Manuals Engine Swarm Swarm Tutorial  Index (`content/manuals/engine/swarm/swarm-tutorial/_index.md`)

---
description: Getting Started tutorial for Docker Engine Swarm mode
keywords: tutorial, cluster management, swarm mode, docker engine, get started
title: Getting started with Swarm mode
toc_max: 4
---

This tutorial introduces you to the features of Docker Engine Swarm mode. You
may want to familiarize yourself with the [key concepts](../key-concepts.md)
before you begin.

The tutorial guides you through:

* Initializing a cluster of Docker Engines in swarm mode
* Adding nodes to the swarm
* Deploying application services to the swarm
* Managing the swarm once you have everything running

This tutorial uses Docker Engine CLI commands entered on the command line of a
terminal window.

If you are brand new to Docker, see [About Docker Engine](../../_index.md).

## Set up

To run this tutorial, you need:

- [Set up](#set-up)
  - [Three networked host machines](#three-networked-host-machines)
    - [Install Docker Engine on Linux machines](#install-docker-engine-on-linux-machines)
  - [The IP address of the manager machine](#the-ip-address-of-the-manager-machine)
  - [Open protocols and ports between the hosts](#open-protocols-and-ports-between-the-hosts)
- [Next steps](#next-steps)

### Three networked host machines

This tutorial requires three Linux hosts which have Docker installed and can
communicate over a network. These can be physical machines, virtual machines,
Amazon EC2 instances, or hosted in some other way.

One of these machines is a manager (called `manager1`) and two of them are
workers (`worker1` and `worker2`).

> [!NOTE]
>
> You can follow many of the tutorial steps to test single-node swarm as well, in which case you need only one host. Multi-node commands do not work, but you can initialize a swarm, create services, and scale them.

#### Install Docker Engine on Linux machines

If you are using Linux based physical computers or cloud-provided computers as
hosts, simply follow the [Linux install instructions](../../install/_index.md)
for your platform. Spin up the three machines, and you are ready. You can test both
single-node and multi-node swarm scenarios on Linux machines.

### The IP address of the manager machine

The IP address must be assigned to a network interface available to the host
operating system. All nodes in the swarm need to connect to the manager at
the IP address.

Because other nodes contact the manager node on its IP address, you should use a
fixed IP address.

You can run `ip addr` on Linux, or `ifconfig` on macOS, to see a list of the
available network interfaces.

The tutorial uses `manager1` : `192.168.99.100`.

### Open protocols and ports between the hosts

The following ports must be available. On some systems, these ports are open by default.

* Port `2377` TCP for communication with and between manager nodes
* Port `7946` TCP/UDP for overlay network node discovery
* Port `4789` UDP (configurable) for overlay network traffic

If you plan on creating an overlay network with encryption (`--opt encrypted`),
you also need to ensure IP protocol 50 (IPSec ESP) traffic is allowed.

Port `4789` is the default value for the Swarm data path port, also known as the VXLAN port.
It is important to prevent any untrusted traffic from reaching this port, as VXLAN does not
provide authentication. This port should only be opened to a trusted network, and never at a
perimeter firewall.

If the network which Swarm traffic traverses is not fully trusted, it is strongly suggested that
encrypted overlay networks be used. If encrypted overlay networks are in exclusive use, some
additional hardening is suggested:

* [Customize the default ingress network](../networking.md) to use encryption
* Only accept encrypted packets on the Data Path Port:

```bash
# Example iptables rule (order and other tools may require customization)
iptables -I INPUT -m udp --dport 4789 -m policy --dir in --pol none -j DROP
```

## Next steps

Next, you'll create a swarm. 

{{< button text="Create a swarm" url="create-swarm.md" >}}

---

### Manuals Extensions Extensions Sdk Architecture  Index (`content/manuals/extensions/extensions-sdk/architecture/_index.md`)

---
title: Extension architecture
linkTitle: Architecture
description: Docker extension architecture
keywords: Docker, extensions, sdk, metadata
aliases: 
 - /desktop/extensions-sdk/architecture/
weight: 50
---

Extensions are applications that run inside the Docker Desktop. They're packaged as Docker images, distributed
through Docker Hub, and installed by users either through the Marketplace within the Docker Desktop Dashboard or the
Docker Extensions CLI.

Extensions can be composed of three (optional) components:
- A frontend (or User Interface): A web application displayed in a tab of the dashboard in Docker Desktop
- A backend: One or many containerized services running in the Docker Desktop VM
- Executables: Shell scripts or binaries that Docker Desktop copies on the host when installing the extension



An extension doesn't necessarily need to have all these components, but at least one of them depending on the extension features. 
To configure and run those components, Docker Desktop uses a `metadata.json` file. See the
[metadata](metadata) section for more details.

## The frontend

The frontend is basically a web application made from HTML, Javascript, and CSS. It can be built with a simple HTML
file, some vanilla Javascript or any frontend framework, such as React or Vue.js.

When Docker Desktop installs the extension, it extracts the UI folder from the extension image, as defined by the 
`ui` section in the `metadata.json`. See the [ui metadata section](metadata.md#ui-section) for more details.

Every time users click on the **Extensions** tab, Docker Desktop initializes the extension's UI as if it was the first time. When they navigate away from the tab, both the UI itself and all the sub-processes started by it (if any) are terminated.

The frontend can invoke `docker` commands, communicate with the extension backend, or invoke extension executables
deployed on the host, through the [Extensions SDK](https://www.npmjs.com/package/@docker/extension-api-client).

> [!TIP]
>
> The `docker extension init` generates a React based extension. But you can still use it as a starting point for
> your own extension and use any other frontend framework, like Vue, Angular, Svelte, etc. or event stay with
> vanilla Javascript.

Learn more about [building a frontend](/manuals/extensions/extensions-sdk/build/frontend-extension-tutorial.md) for your extension.

## The backend

Alongside a frontend application, extensions can also contain one or many backend services. In most cases, the Extension does not need a backend, and features can be implemented just by invoking docker commands through the SDK. However, there are some cases when an extension requires a backend
	service, for example:
- To run long-running processes that must outlive the frontend
- To store data in a local database and serve them back with a REST API
- To store the extension state, like when a button starts a long-running process, so that if you navigate away
  from the extension and come back, the frontend can pick up where it left off
- To access specific resources in the Docker Desktop VM, for example by mounting folders in the compose
file

> [!TIP]
>
> The `docker extension init` generates a Go backend. But you can still use it as a starting point for
> your own extension and use any other language like Node.js, Python, Java, .Net, or any other language and framework.

Usually, the backend is made of one container that runs within the Docker Desktop VM. Internally, Docker Desktop creates
a Docker Compose project, creates the container from the `image` option of the `vm` section of the `metadata.json`, and
attaches it to the Compose project. See the [`vm` metadata section](metadata.md#vm-section) for more details.

In some cases, a `compose.yaml` file can be used instead of an `image`. This is useful when the backend container
needs more specific options, such as mounting volumes or requesting [capabilities](https://docs.docker.com/engine/reference/run/#runtime-privilege-and-linux-capabilities)
that can't be expressed just with a Docker image. The `compose.yaml` file can also be used to add multiple containers
needed by the extension, like a database or a message broker. 
Note that, if the Compose file defines many services, the SDK can only contact the first of them.

> [!NOTE]
>
> In some cases, it is useful to also interact with Docker Engine from the backend.
> See [How to use the Docker socket](../guides/use-docker-socket-from-backend.md) from the backend.

To communicate with the backend, the Extension SDK provides [functions](../dev/api/backend.md#get) to make `GET`,
`POST`, `PUT`, `HEAD`, and `DELETE` requests from the frontend. Under the hood, the communication is done through a socket
or named pipe, depending on the operating system. If the backend was listening to a port, it would be difficult to
prevent collision with other applications running on the host or in a container already. Also, some users are
running Docker Desktop in constrained environments where they can't open ports on their machines.



Finally, the backend can be built with any technology, as long as it can run in a container and listen on a socket.

Learn more about [adding a backend](/manuals/extensions/extensions-sdk/build/backend-extension-tutorial.md) to your extension.

## Executables

In addition to the frontend and the backend, extensions can also contain executables. Executables are binaries or shell scripts
that are installed on the host when the extension is installed. The frontend can invoke them with [the extension SDK](../dev/api/backend.md#invoke-an-extension-binary-on-the-host).

These executables are useful when the extension needs to interact with a third-party CLI tool, like AWS, `kubectl`, etc.
Shipping those executables with the extension ensure that the CLI tool is always available, at the right version, on
the users' machine.

When Docker Desktop installs the extension, it copies the executables on the host as defined by the `host` section in
the `metadata.json`. See the [`host` metadata section](metadata.md#host-section) for more details.



However, since they're executed on the users' machine, they have to be available to the platform they're running on.
For example, if you want to ship the `kubectl` executable, you need to provide a different version for Windows, Mac,
and Linux. Multi arch images will also need to include binaries built for the right arch (AMD / ARM)


See the [host metadata section](metadata.md#host-section) for more details.

Learn how to [invoke host binaries](../guides/invoke-host-binaries.md).

---

### Manuals Extensions Extensions Sdk Design  Index (`content/manuals/extensions/extensions-sdk/design/_index.md`)

---
title: UI styling overview for Docker extensions
linkTitle: Design and UI styling
description: Docker extension design
keywords: Docker, extensions, design
aliases:
 - /desktop/extensions-sdk/design/design-overview/
 - /desktop/extensions-sdk/design/overview/
 - /desktop/extensions-sdk/design/
weight: 60
---

Our Design System is a constantly evolving set of specifications that aim to ensure visual consistency across Docker products, and meet [level AA accessibility standards](https://www.w3.org/WAI/WCAG2AA-Conformance). We've opened parts of it to extension authors, documenting basic styles (color, typography) and components. See: [Docker Extensions Styleguide](https://www.figma.com/file/U7pLWfEf6IQKUHLhdateBI/Docker-Design-Guidelines?node-id=1%3A28771).

We require extensions to match the wider Docker Desktop UI to a certain degree, and reserve the right to make this stricter in the future.

To get started on your UI, follow the steps below.

## Step one: Choose your framework

### Recommended: React+MUI, using our theme

Docker Desktop's UI is written in React and [MUI](https://mui.com/) (using Material UI specifically). This is the only officially supported framework for building extensions, and the one that the `init` command automatically configures for you. Using it brings significant benefits to authors:

- You can use our [Material UI theme](https://www.npmjs.com/package/@docker/docker-mui-theme) to automatically replicate Docker Desktop's look and feel.
- In future, we'll release utilities and components specifically targeting this combination (e.g. custom MUI components, or React hooks for interacting with Docker).

Read our [MUI best practices](mui-best-practices.md) guide to learn future-proof ways to use MUI with Docker Desktop.

### Not recommended: Some other framework

You may prefer to use another framework, perhaps because you or your team are more familiar with it or because you have existing assets you want to reuse. This is possible, but highly discouraged. It means that:

- You'll need to manually replicate the look and feel of Docker Desktop. This takes a lot of effort, and if you don't match our theme closely enough, users will find your extension jarring and we may ask you to make changes during a review process.
- You'll have a higher maintenance burden. Whenever Docker Desktop's theme changes (which could happen in any release), you'll need to manually change your extension to match it.
- If your extension is open-source, deliberately avoiding common conventions will make it harder for the community to contribute to it.

## Step two: Follow the below recommendations

### Follow our MUI best practices (if applicable)

See our [MUI best practices](mui-best-practices.md) article.

### Only use colors from our palette

With minor exceptions, displaying your logo for example, you should only use colors from our palette. These can be found in our [style guide document](https://www.figma.com/file/U7pLWfEf6IQKUHLhdateBI/Docker-Design-Guidelines?node-id=1%3A28771), and will also soon be available in our MUI theme and via CSS variables.

### Use counterpart colors in light/dark mode

Our colors have been chosen so that the counterpart colors in each variant of the palette should have the same essential characteristics. Anywhere you use `red-300` in light mode, you should use `red-300` in dark mode too.

## What's next?

- Take a look at our [MUI best practices](mui-best-practices.md).
- Learn how to [publish your extension](../extensions/_index.md).

---

### Manuals Extensions Extensions Sdk Dev  Index (`content/manuals/extensions/extensions-sdk/dev/_index.md`)

---
build:
  render: never
title: Developer SDK tools
---

---

### Manuals Extensions Extensions Sdk Extensions  Index (`content/manuals/extensions/extensions-sdk/extensions/_index.md`)

---
title: "Part two: Publish"
description: General steps in how to publish an extension
keywords: Docker, Extensions, sdk, publish
aliases: 
 - /desktop/extensions-sdk/extensions/
weight: 40
---

This section describes how to make your extension available and more visible, so users can discover it and install it with a single click.

## Release your extension

After you have developed your extension and tested it locally, you are ready to release the extension and make it available for others to install and use (either internally with your team, or more publicly).

Releasing your extension consists of:

- Providing information about your extension: description, screenshots, etc. so users can decide to install your extension
- [Validating](validate.md) that the extension is built in the right format and includes the required information
- Making the extension image available on [Docker Hub](https://hub.docker.com/)

See [Package and release your extension](DISTRIBUTION.md) for more details about the release process.

## Promote your extension

Once your extension is available on Docker Hub, users who have access to the extension image can install it using the Docker CLI.

### Use a share extension link

You can also [generate a share URL](share.md) in order to share your extension within your team, or promote your extension on the internet. The share link lets users view the extension description and screenshots.

### Publish your extension in the Marketplace

You can publish your extension in the Extensions Marketplace to make it more discoverable. You must [submit your extension](publish.md) if you want to have it published in the Marketplace.

## What happens next

### New releases

Once you have released your extension, you can push a new release just by pushing a new version of the extension image, with an incremented tag (still using `semver` conventions).
Extensions published in the Marketplace benefit from update notifications to all Desktop users that have installed the extension. For more details, see [new releases and updates](DISTRIBUTION.md#new-releases-and-updates).

### Extension support and user feedback

In addition to providing a description of your extension's features and screenshots, you should also specify additional URLs using [extension labels](labels.md). This direct users to your website for reporting bugs and feedback, and accessing documentation and support.

{{% include "extensions-form.md" %}}

---

### Manuals Extensions Extensions Sdk Guides  Index (`content/manuals/extensions/extensions-sdk/guides/_index.md`)

---
build:
  render: never
title: Developer Guides
---

---

### Manuals Scout Integrations Ci  Index (`content/manuals/scout/integrations/ci/_index.md`)

---
description: How to set up Docker Scout in continuous integration pipelines
keywords: scanning, vulnerabilities, Hub, supply chain, security, ci, continuous integration,
  github actions, gitlab
title: Using Docker Scout in continuous integration
linkTitle: Continuous Integration
aliases:
- /scout/ci/
---

You can analyze Docker images in continuous integration pipelines as you build
them using a GitHub action or the Docker Scout CLI plugin.

Available integrations:

- [GitHub Actions](gha.md)
- [GitLab](gitlab.md)
- [Microsoft Azure DevOps Pipelines](azure.md)
- [Circle CI](circle-ci.md)
- [Jenkins](jenkins.md)

You can also add runtime integration as part of your CI/CD pipeline, which lets
you assign an image to an environment, such as `production` or `staging`, when
you deploy it. For more information, see [Environment monitoring](../environment/_index.md).

---

### Manuals Scout Integrations Environment  Index (`content/manuals/scout/integrations/environment/_index.md`)

---
description:
  Docker Scout can integrate with runtime environments to give you real-time
  insights about your software supply chain.
keywords: supply chain, security, streams, environments, workloads, deployments
title: Integrating Docker Scout with environments
---

You can integrate Docker Scout with your runtime environments, and get insights
for your running workloads. This gives you a real-time view of your security
status for your deployed artifacts.

Docker Scout lets you define multiple environments, and assign images to
different environments. This gives you a complete overview of your software
supply chain, and lets you view and compare deltas between environments, for
example staging and production.

How you define and name your environments is up to you. You can use patterns
that are meaningful to you and that matches how you ship your applications.

## Assign to environments

Each environment contains references to a number of images. These references
represent containers currently running in that particular environment.

For example, say you're running `myorg/webapp:3.1` in production, you can
assign that tag to your `production` environment. You might be running a
different version of the same image in staging, in which case you can assign
that version of the image to the `staging` environment.

To add environments to Docker Scout, you can:

- Use the `docker scout env <environment> <image>` CLI command to record images to environments manually
- Enable a runtime integration to automatically detect images in your environments.

Docker Scout supports the following runtime integrations:

- [Docker Scout GitHub Action](https://github.com/marketplace/actions/docker-scout#record-an-image-deployed-to-an-environment)
- [CLI client](./cli.md)

> [!NOTE]
>
> Only organization owners can create new environments and set up integrations.
> Additionally, Docker Scout only assigns an image to an environment if the
> image [has been analyzed](/manuals/scout/explore/analysis.md), either manually or
> through a [registry integration](/manuals/scout/integrations/_index.md#container-registries).

## List environments

To see all of the available environments for an organization, you can use the
`docker scout env` command.

```console
$ docker scout env
```

By default, this prints all environments for your personal Docker organization.
To list environments for another organization that you're a part of, use the
`--org` flag.

```console
$ docker scout env --org <org>
```

You can use the `docker scout config` command to change the default
organization. This changes the default organization for all `docker scout`
commands, not just `env`.

```console
$ docker scout config organization <org>
```

## Comparing between environments

Assigning images to environments lets you make comparisons with and between
environments. This is useful for things like GitHub pull requests, for
comparing the image built from the code in the PR to the corresponding image in
staging or production.

You can also compare with streams using the `--to-env` flag on the
[`docker scout compare`](/reference/cli/docker/scout/compare/)
CLI command:

```console
$ docker scout compare --to-env production myorg/webapp:latest
```

## View images for an environment

To view the images for an environment:

1. Go to the [Images page](https://scout.docker.com/) in the Docker Scout Dashboard.
2. Open the **Environments** drop-down menu.
3. Select the environment that you want to view.

The list displays all images that have been assigned to the selected
environment. If you've deployed multiple versions of the same image in an
environment, all versions of the image appear in the list.

Alternatively, you can use the `docker scout env` command to view the images from the terminal.

```console
$ docker scout env production
docker/scout-demo-service:main@sha256:ef08dca54c4f371e7ea090914f503982e890ec81d22fd29aa3b012351a44e1bc
```

### Mismatching image tags

When you've selected an environment on the **Images** tab, tags in the list
represent the tag that was used to deploy the image. Tags are mutable, meaning
that you can change the image digest that a tag refers to. If Docker Scout
detects that a tag refers to an outdated digest, a warning icon displays next
to the image name.

---

--- METRICS ---
- Files Extracted: 149
- Estimated Token Budget: ~125133 tokens
- Canonical Reference: https://codewiki.google/github.com/docker/docs
