Technical Documentation: docker/docs
ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference
Overview (`README.md`)
Docs @ Docker
Welcome to the Docker Documentation repository. This is the source for the Docker Docs Website.
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 on the docs repository, or
- Click Request changes in the right column of every page on
docs.docker.com, or - Click Give feedback on every page in the docs.
To get community support, use the Docker Community Slack. Personalized support is available
through the Docker Pro, Team, and Business subscriptions. See Docker
Pricing 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 - Contribution workflow and setup
- STYLE.md - Writing style and content guidelines
- COMPONENTS.md - Component and shortcode usage
Copyright and license
Copyright 2013-2026 Docker, Inc., released under the Apache 2.0 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:
$ npm ci
$ hugo serverFor 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 and make
the vacuum executable available on PATH. The script runs Vacuum and the Go
generator without installing tools.
$ ./hack/api-docs/run.sh test
$ ./hack/api-docs/run.sh generateCommit data/api-reference.json with the source changes. Withdocker 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 undertmp/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
- Parse the authoritative YAML with
libopenapiand preserve source values and
reference identities. Verify locked OpenAPI dialect resources. - Run Vacuum policy checks and JSON Schema validation of schemas and supplied
examples, followed by documentation profile checks. - Generate presentation model version 1: operations, effective security and
servers, parameters, media variants, examples, schema links, and provenance. - Render HTML and Markdown through the content adapter and
api-docstemplates. - 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:
$ ./hack/api-docs/run.sh checkGeneration runs the same strict validation. Any diagnostic fails generation;
there is no exception baseline. Reports are written totmp/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:
$ docker buildx bake validate-api-referenceThis 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 todocs.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 fromrequest-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 ofdocker/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 fordocker/sbx-api:
$ python3 hack/sync-sandboxes-docs.pyThe 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 indocker/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 commitdata/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 certlots of things to see and manually answer, as openssl wants to be interactive
[!NOTE]: make sure you enter the hostname (
boot2dockerin my case) when prompted forComputer Name)
root@boot2docker:/# sudo make runStart another terminal:
$ boot2docker ssh
root@boot2docker:/# cd docker/docs/articles/https
root@boot2docker:/# make clientThe 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.
The latest version of the API specification can be found at the root directory
of this module which may contain unreleased changes.
For API version v1.24, documentation is only available in markdown
format, for later versions Swagger (OpenAPI) v2.0
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
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: Run an application, sandbox an AI agent, or
roll out Docker. - Guides: Follow task-focused walkthroughs for common workflows.
- Manuals: Install, configure, and use Docker products.
- Reference: Browse CLI, API, and file format documentation.
{{< whats-new >}}
Common questions
- How do I get started with Docker?
- How do I containerize an application?
- Can I run my AI agent in a sandbox?
- What are Docker Hardened Images?
- Why should I use Docker Compose?
Get Started Index (`content/get-started/_index.md`)
title: Get started
keywords: Docker, get started, containers, AI agents, sandboxes, administration
layout: get-started
params:
notoc: true
installs:
- eyebrow: Docker
title: Install Docker
link: /get-started/get-docker/
- eyebrow: Docker Sandboxes
title: Install Docker Sandboxes
link: /ai/sandboxes/install/
tutorials:
- audience: New to Docker
title: Build and share a containerized application
link: /get-started/tutorials/run-an-app/
- audience: AI developers
title: Run your coding agent in a sandbox
link: /get-started/tutorials/run-an-agent/
- audience: Administrators
title: Roll out Docker to a pilot group
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`)
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.
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.
$ docker run -i -t ubuntu /bin/bashWhen you run this command, the following happens (assuming you are using
the default registry configuration):
If you don't have the
ubuntuimage locally, Docker pulls it from your
configured registry, as though you had rundocker pull ubuntumanually.Docker creates a new container, as though you had run a
docker container create
command manually.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.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.Docker starts the container and executes
/bin/bash. Because the container
is running interactively and attached to your terminal (due to the-iand-t
flags), you can provide input using your keyboard while Docker logs the output to
your terminal.When you run
exitto terminate the/bin/bashcommand, 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 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
Guides Index (`content/guides/_index.md`)
title: Docker guides
linkTitle: Guides
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 repository.
Guides Lab Compose Quickstart (`content/guides/lab-compose-quickstart.md`)
title: "Lab: Docker Compose Quickstart" linkTitle: "Lab: Docker Compose Quickstart" 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.yamlfile and manage it with Compose commands - Control service startup order using health checks and
depends_onconditions - 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
includedirective - Use
config,logs, andexecto 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" 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
Dockerfileto package an application, using layer caching for fast rebuilds - Build a custom image with
docker buildand 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
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
CustomerServicethat 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 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:
$ 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.csprojAdd the Npgsql dependency to the source project:
$ dotnet add ./CustomerService/CustomerService.csproj package NpgsqlImplement the business logic
Create a Customer record type:
namespace Customers;
public readonly record struct Customer(long Id, string Name);Create a DbConnectionProvider class to manage database connections:
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 thecustomerstable and returns them asCustomerobjects.Create()inserts a customer record into the database.
Write tests with Testcontainers
Add Testcontainers dependencies
Add the Testcontainers PostgreSQL module to the test project:
$ dotnet add ./CustomerService.Tests/CustomerService.Tests.csproj package Testcontainers.PostgreSqlWrite the test
Create CustomerServiceTest.cs in the test project:
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
PostgreSqlContainerusing thePostgreSqlBuilderwith thepostgres:16-alpineDocker image. - Implements
IAsyncLifetimefor container lifecycle management:InitializeAsync()starts the container before the test runs.DisposeAsync()stops and removes the container after the test finishes.
ShouldReturnTwoCustomers()creates aCustomerServicewith 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:
$ dotnet testYou 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 for many SQL
databases, NoSQL databases, messaging queues, and more.
To learn more about Testcontainers, visit the
Testcontainers overview.
Further reading
Guides Testcontainers Go Getting Started (`content/guides/testcontainers-go-getting-started.md`)
title: Getting started with Testcontainers for Go
linkTitle: Testcontainers for Go
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.
[!NOTE]
If you're new to Testcontainers, visit the
Testcontainers overview to learn more about
Testcontainers and the benefits of using it.
Create the Go project
Initialize the project
Start by creating a Go project.
$ mkdir testcontainers-go-demo
$ cd testcontainers-go-demo
$ go mod init github.com/testcontainers/testcontainers-go-demoThis guide uses the jackc/pgx PostgreSQL
driver to interact with the Postgres database and the testcontainers-go
Postgres module to
spin up a Postgres Docker instance for testing. It also uses
testify for running multiple tests
as a suite and for writing assertions.
Install these dependencies:
$ 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/testifyCreate Customer struct
Create a types.go file in the customer package and define the Customer
struct to model the customer details:
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:
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:
Repositoryholds a*pgx.Connfor performing database operations.NewRepository(connStr)takes a database connection string and initializes aRepository.CreateCustomer()andGetCustomerByEmail()are methods on theRepositoryreceiver 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:
CREATE TABLE IF NOT EXISTS customers (id serial, name varchar(255), email varchar(255));
INSERT INTO customers(name, email) VALUES ('John', '[email protected]');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:
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: "[email protected]",
})
assert.NoError(t, err)
assert.NotNil(t, c)
customer, err := customerRepo.GetCustomerByEmail(ctx, "[email protected]")
assert.NoError(t, err)
assert.NotNil(t, customer)
assert.Equal(t, "Henry", customer.Name)
assert.Equal(t, "[email protected]", customer.Email)
}Here's what the test does:
- Calls
postgres.Run()with thepostgres:16-alpineDocker 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 theCUSTOMERStable 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 afterpostgres.Run().
This registers automatic cleanup with the test framework, replacing the manualt.CleanupandTerminatepattern. - Obtains the database
ConnectionStringfrom the container and initializes aRepository. - Creates a customer with the email
[email protected]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
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:
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-goPostgresContainer to provide easy access to ConnectionString. TheCreatePostgresContainer() 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:
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: "[email protected]",
})
require.NoError(t, err)
assert.NotNil(t, customer.Id)
}
func (suite *CustomerRepoTestSuite) TestGetCustomerByEmail() {
t := suite.T()
customer, err := suite.repository.GetCustomerByEmail(suite.ctx, "[email protected]")
require.NoError(t, err)
assert.Equal(t, "John", customer.Name)
assert.Equal(t, "[email protected]", customer.Email)
}
func TestCustomerRepoTestSuite(t *testing.T) {
suite.Run(t, new(CustomerRepoTestSuite))
}Here's what the code does:
CustomerRepoTestSuiteextendssuite.Suiteand includes fields shared
across multiple tests.SetupSuite()runs once before all tests. It callsCreatePostgresContainer(suite.T(), ...)which handles cleanup registration
automatically viaCleanupContainer, so noTearDownSuite()is needed.TestCreateCustomer()usesrequire.NoError()for the create operation
(fail immediately if it errors) andassert.NotNil()for the ID check.TestGetCustomerByEmail()usesrequire.NoError()then asserts on the
returned values.TestCustomerRepoTestSuite(t *testing.T)runs the test suite when you
executego 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:
$ 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.
Further reading
- Testcontainers for Go documentation
- Testcontainers for Go quickstart
- Testcontainers Postgres module for Go
Guides Testcontainers Java Getting Started (`content/guides/testcontainers-java-getting-started.md`)
title: Getting started with Testcontainers for Java
linkTitle: Testcontainers for Java
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
CustomerServicethat 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 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:
<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:
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:
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 thecustomerstable and returns a list ofCustomerobjects.
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:
<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:
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
PostgreSQLContainerwith thepostgres:16-alpineDocker image. - The
@BeforeAllcallback starts the Postgres container before any test
methods run. - The
@BeforeEachcallback creates aDBConnectionProviderusing the JDBC
connection parameters from the container, then creates aCustomerService.
TheCustomerServiceconstructor creates thecustomerstable if it
doesn't exist. shouldGetCustomers()inserts 2 customer records, fetches all customers,
and asserts the count.- The
@AfterAllcallback stops the container after all test methods finish.
Run tests and next steps
Run the tests
Run the tests using Maven:
$ mvn testYou 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.
Further reading
- Testcontainers container lifecycle management using JUnit 5
- Replace H2 with a real database for testing
- Getting started with Testcontainers in a Java Spring Boot project
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
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 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:
$ npm init -yAdd pg, jest, and @testcontainers/postgresql as dependencies:
$ npm install pg --save
$ npm install jest @testcontainers/postgresql --save-devImplement the customer repository
Create src/customer-repository.js with functions to manage customers in
PostgreSQL:
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 thecustomerstable 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:
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
beforeAllblock starts a real PostgreSQL container usingPostgreSqlContainer. It then creates apgclient connected to the
container and sets up thecustomerstable. - The
afterAllblock 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:
{
"scripts": {
"test": "jest"
}
}Then run the tests:
$ npm testYou should see output like:
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 totalTo see what Testcontainers is doing under the hood — which containers it
starts, what versions it uses — set the DEBUG environment variable:
$ DEBUG=testcontainers* npm testSummary
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
for many SQL databases, NoSQL databases, messaging queues, and more.
To learn more about Testcontainers, visit the
Testcontainers overview.
Further reading
Guides Testcontainers Python Getting Started (`content/guides/testcontainers-python-getting-started.md`)
title: Getting started with Testcontainers for Python
linkTitle: Testcontainers for Python
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
psycopgto interact with the database - Write integration tests using
testcontainers-pythonandpytest - 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 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:
$ mkdir tc-python-demo
$ cd tc-python-demo
$ python3 -m venv venv
$ source venv/bin/activateThis guide uses psycopg3 to interact
with the Postgres database, pytest for testing, and
testcontainers-python for
running a PostgreSQL database in a container.
Install the dependencies:
$ pip install "psycopg[binary]" pytest testcontainers[postgres]
$ pip freeze > requirements.txtThe 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:
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:
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:
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:
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
for setup and teardown logic. A recommended approach is to use
finalizers
to guarantee cleanup runs even if setup fails:
@pytest.fixture
def setup(request):
# setup code
def cleanup():
# teardown code
request.addfinalizer(cleanup)
return some_valueCreate the test file
Create a tests/__init__.py file with empty content to enable pytest
auto-discovery.
Then create tests/test_customers.py with the fixtures:
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
setupfixture hasscope="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 thecustomerstable. A cleanup
function removes the container after all tests complete. - The
setup_datafixture hasscope="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:
def test_get_all_customers():
customers.create_customer("Siva", "[email protected]")
customers.create_customer("James", "[email protected]")
customers_list = customers.get_all_customers()
assert len(customers_list) == 2
def test_get_customer_by_email():
customers.create_customer("John", "[email protected]")
customer = customers.get_customer_by_email("[email protected]")
assert customer.name == "John"
assert customer.email == "[email protected]"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:
$ pytest -vYou should see output similar to:
============================= 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.
Further reading
- testcontainers-python documentation
- Getting started with Testcontainers for Go
- Getting started with Testcontainers for Java
- Getting started with Testcontainers for Node.js
Includes Index (`content/includes/_index.md`)
cascade:
- build:
list: never
publishResources: false
render: never
Manuals Index (`content/manuals/_index.md`)
title: Manuals
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
icon: cloud
link: /agentic-platform/ - title: Docker Sandboxes
icon: command-line
link: /ai/sandboxes/ - title: Sandboxes API and SDK
icon: code-bracket
link: /ai/sandboxes-api/ - title: MCP Catalog and Toolkit
icon: /icons/toolkit.svg
link: /ai/mcp-catalog-and-toolkit/ - title: Gordon
icon: document-plus
link: /ai/gordon/ - title: Docker Model Runner
icon: /icons/models.svg
link: /ai/model-runner/ - title: Docker Agent
icon: /icons/cagent.svg
link: /ai/docker-agent - title: Docker Skills
icon: document-text
link: /ai/skills/
application-development: - title: Docker Desktop
icon: /icons/Whale.svg
link: /desktop/ - title: Docker Offload
icon: cloud
link: /offload/ - title: Docker Build Cloud
icon: /icons/logo-build-cloud.svg
link: /build-cloud/ - title: Testcontainers
icon: /icons/Testcontainers.svg
link: /testcontainers/ - title: Docker Build
icon: wrench-screwdriver
link: /build/ - title: Docker Engine
icon: cpu-chip
link: /engine/ - title: Docker Compose
icon: /icons/Compose.svg
link: /compose/
supply-chain-security: - title: Docker Hub
icon: globe-alt
link: /docker-hub/ - title: Docker Hardened Images
icon: /icons/dhi.svg
link: /dhi/ - title: Docker Scout
icon: /icons/Scout.svg
link: /scout/
platform: - title: Accounts
icon: user-circle
link: /accounts/ - title: Subscription and billing
icon: credit-card
link: /subscription-billing/ - title: Security
icon: lock-closed
link: /security/ - title: FAQs
icon: question-mark-circle
link: /faqs/ - title: Support
icon: chat-bubble-left
link: /support/ - title: Release notes
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
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 | sbx |
| Run agents in cloud sandboxes through a web Console | Docker Agentic Platform (experimental) | Web Console |
| Get AI help with Docker tasks (containers, images, Dockerfiles) | Gordon | docker ai |
| Run AI models locally with an OpenAI-compatible API | Model Runner | docker model |
| Connect AI tools to external services via MCP | MCP Catalog and Toolkit | docker mcp |
| Build and orchestrate custom multi-agent teams | Docker Agent | docker agent |
| Give my coding agent Docker best-practice guidance | Docker 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 for current guidance.
Docker Sandboxes provides isolated environments for running coding agents
locally or
in the cloud. 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 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
keywords: Docker reference, API, CLI, file formats
params:
icon: command-line
notoc: true
grid_files:
- title: Dockerfile
icon: pencil-square
link: /reference/dockerfile/ - title: Compose file
icon: rectangle-stack
link: /reference/compose-file/
grid_clis: - title: Docker CLI
icon: command-line
link: /reference/cli/docker/ - title: Compose CLI
applications.
icon: server-stack
link: /reference/cli/docker/compose/ - title: Daemon CLI (dockerd)
icon: cpu-chip
link: /reference/cli/dockerd/
grid_apis: - title: Sandboxes API
icon: code-bracket
link: /reference/api/sandboxes/latest/ - title: Engine API
icon: code-bracket
link: /reference/api/engine/ - title: Docker Hub API
icon: cloud
link: /reference/api/hub/latest/ - title: DVP Data API
icon: chart-bar
link: /reference/api/dvp/latest/ - title: Registry API
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 keywords: Docker, get started, tutorials, containers, AI agents, administration weight: 1 build: render: never
Manuals Accounts Index (`content/manuals/accounts/_index.md`)
title: Accounts
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
icon: user-circle
link: /accounts/individual/ - title: Organization accounts
icon: building-storefront
link: /accounts/organization/ - title: Company accounts
icon: building-office-2
link: /accounts/company/ - title: Security
icon: lock-closed
link: /security/ - title: Subscription and billing
icon: credit-card
link: /subscription-billing/ - title: FAQs
icon: question-mark-circle
link: /faqs/
A Docker account identifies you and lets you access Docker products. You
manage it in Docker Home. 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
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
icon: credit-card
link: /agentic-platform/signup/ - title: Get started
icon: rocket-launch
link: /agentic-platform/get-started/ - title: Kits
icon: cube
link: /agentic-platform/kits/ - title: Sandboxes
icon: command-line
link: /agentic-platform/sandboxes/ - title: MCP
icon: cpu-chip
link: /agentic-platform/mcp/ - title: Secrets
icon: key
link: /agentic-platform/secrets/ - title: Policies
icon: shield-check
link: /agentic-platform/policies/ - title: FAQ
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 and
cloud sandboxes. These pages describe
the web Console experience. The Console and CLI use different secret names;
see Cloud credentials.
In the Console, choose a kit 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 connects external tools.
- Secrets provide credentials
without placing their values inside a sandbox. - Network policies control
which hosts and services a sandbox can reach.
To begin, activate your subscription, then
start a sandbox. You pay for compute by the second while your
sandbox runs. See Signup and billing for account and payment
information.
{{< grid >}}
Manuals Build Cloud Index (`content/manuals/build-cloud/_index.md`)
title: Docker Build Cloud
weight: 20
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. 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 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 for more information.
Once you've signed up and created a builder, continue by
setting up the builder in your local environment.
For information about roles and permissions related to Docker Build Cloud, see
Roles and Permissions.
Manuals Compose Index (`content/manuals/compose/_index.md`)
title: Docker Compose
weight: 30
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?
icon: magnifying-glass
link: /compose/intro/features-uses/ - title: How Compose works
icon: squares-2x2
link: /compose/intro/compose-application-model/ - title: Install Compose
icon: arrow-down-tray
link: /compose/install - title: Quickstart
web application.
icon: magnifying-glass-plus
link: /compose/gettingstarted - title: View the release notes
icon: document-plus
link: "https://github.com/docker/compose/releases" - title: Explore the Compose file reference
Docker application.
icon: arrows-right-left
link: /reference/compose-file - title: Use Compose Bridge
icon: arrow-down
link: /compose/bridge - title: Browse common FAQs
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
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
Install Docker Desktop on
Mac,
Windows, or
Linux.
icon: arrow-down-tray - title: Learn about Docker Desktop
icon: magnifying-glass
link: /desktop/use-desktop/ - title: Explore its key features
Find information about Networking, Docker VMM, WSL, and more.
icon: squares-2x2 - title: View the release notes
icon: document-plus
link: /desktop/release-notes/ - title: Browse common FAQs
icon: question-mark-circle
link: /desktop/troubleshoot-and-support/faqs/general/ - title: Give feedback
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
- Docker Model Runner
- Gordon
- Docker Offload
- Docker Engine
- Docker CLI client
- Docker Build
- Docker Compose
- Docker Scout
- Kubernetes
Next steps
{{< grid >}}
Manuals Dhi Index (`content/manuals/dhi/_index.md`)
title: Docker Hardened 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
icon: rocket-launch
link: /dhi/get-started/ - title: Explore
icon: information-circle
link: /dhi/explore/ - title: How-tos
icon: play
link: /dhi/how-to/ - title: Security concepts
icon: clipboard-document-check
link: /dhi/explore/security-concepts/ - title: Tools
icon: wrench-screwdriver
link: /dhi/tools/ - title: Resources and feedback
icon: link
link: /dhi/resources/ - title: Release notes
icon: newspaper
link: /dhi/release-notes/platform/
- title: Quickstart
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.
Community features
DHI's core features are free to use, share, and build on under Apache 2.0.
- Near-zero CVEs: continuously scanned and patched
to maintain minimal known vulnerabilities - Distroless variants: remove unnecessary
components, reducing attack surface by up to 95% - Non-root execution: containers run as non-root by default
- Hardened system packages: system packages
built from source, cryptographically signed, and verified by Docker - SLSA Build Level 3 provenance, signed
SBOMs, VEX statements,
and cryptographic signatures on every image - Built on Alpine and Debian with glibc and musl
variants; dev and runtime image variants
available - Works with existing Docker workflows, CI/CD pipelines, and tools with no
retooling required - Helm charts: 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 for critical and high
severity CVE remediation - FIPS-enabled and
STIG-ready compliance variants - Customization: add packages, tools, certificates,
and configurations (up to 5 with Select, unlimited with Enterprise) - Enterprise package repository 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`)
keywords: docker hub, hub, repositories
title: Docker Hub
weight: 30
params:
sidebar:
group: Supply chain security
grid:
- title: Quickstart
icon: magnifying-glass-plus
link: /docker-hub/quickstart - title: Library
icon: book-open
link: /docker-hub/image-library/ - title: Repositories
or the Docker community.
icon: inbox
link: /docker-hub/repos - title: Settings
icon: cog-6-tooth
link: /docker-hub/settings - title: Organizations
icon: building-storefront
link: /accounts/organization/ - title: Usage and limits
icon: chart-bar
link: /docker-hub/usage/ - title: MCP server
icon: server-stack
link: /docker-hub/mcp-server/ - title: Release notes
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, the experimental Docker
Hub CLI tool, or the Docker Hub
MCP server for AI agent integrations.
{{< grid >}}
Manuals Docker Hub Quickstart (`content/manuals/docker-hub/quickstart.md`)
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
- A verified Docker 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" >}}
Navigate to the Docker Hub Explore page.
On the Explore page, you can browse by catalog or category, or use the search
to quickly find content.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.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.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 thedocker pullcommand to
pull the image.
{{< /tab >}}
{{< tab name="Docker Desktop" >}}
Open the Docker Desktop Dashboard.
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.Leave the search box empty and then select Search.
The search results are shown with additional filters now next to the search box.
Select the search filter icon, and then select Docker Official Image and Web Servers.
In the results, select the nginx image.
{{< /tab >}}
{{< tab name="CLI" >}}
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.In the terminal, run the following command.
console$ docker search --filter is-official=true nginxUnlike the Docker Hub and Docker Desktop interfaces, you can't browse by
category using thedocker searchcommand. For more details about the
command, see 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" >}}
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.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.In the Host port option, specify
8080.Select Run.
The container logs appear after the container starts.
Select the 8080:80 link to open the server, or visit
http://localhost:8080 in your web browser.In the Docker Desktop Dashboard, select the Stop button to stop the
container.
{{< /tab >}}
{{< tab name="CLI" >}}
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.In your terminal, run the following command to pull and run the Nginx image.
console$ docker run -p 8080:80 --rm nginxThe
docker runcommand automatically pulls and runs the image without the
need to rundocker pullfirst. To learn more about the command and its
options, see thedocker runCLI
reference. After running the
command, you should see output similar to the following.text
/* 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.
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 thedocker buildCLI
reference. 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.0sRun the following command to test your image. Replace
<YOUR-USERNAME>with
your Docker ID.console$ docker run -p 8080:80 --rm <YOUR-USERNAME>/nginx-customVisit http://localhost:8080 to view the page. You
should seeHello world from Docker!.In the terminal, press CTRL+C to stop the container.
Sign in to Docker Desktop. You must be signed in before pushing an image to
Docker Hub.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 thedocker pushCLI
reference. 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" >}}
Go to Docker Hub and sign in.
After signing in, you should be on the Repositories page. If not, then go
to the Repositories page.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" >}}
Sign in to Docker Desktop.
Select the Images view.
Select the Hub repositories tab.
A list of your Docker Hub repositories appears.
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 to help users find and use
your image.
Manuals Engine Index (`content/manuals/engine/_index.md`)
title: Docker Engine
weight: 10
keywords: Engine
params:
sidebar:
group: Application development
grid:
- title: Install Docker Engine
icon: arrow-down-tray
link: /engine/install - title: Storage
icon: circle-stack
link: /storage - title: Networking
icon: server-stack
link: /network - title: Container logs
icon: document-text
link: /config/containers/logging/ - title: Prune
icon: scissors
link: /config/pruning - title: Configure the daemon
icon: adjustments-horizontal
link: /config/daemon - title: Rootless mode
icon: shield-check
link: /engine/security/rootless - title: Deprecated features
icon: folder-minus
link: /engine/deprecated/ - title: Release notes
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. - APIs which specify interfaces that programs can use to talk to and instruct
the Docker daemon. - A command line interface (CLI) client
docker.
The CLI uses Docker APIs 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.
{{< 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.
Apache License, Version 2.0. See LICENSE for the full license.
Manuals Extensions Index (`content/manuals/extensions/_index.md`)
title: Docker Extensions
weight: 60
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.
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 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 to control which extensions your team can install.
Manuals Faqs Index (`content/manuals/faqs/_index.md`)
title: FAQs
linkTitle: FAQs
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
icon: question-mark-circle
link: /faqs/accounts/ - title: Security FAQs
icon: lock-closed
link: /faqs/security/ - title: Subscription and billing FAQs
icon: credit-card
link: /faqs/subscription-billing/ - title: Platform FAQs
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
keywords: build, cloud, cloud build, remote builder
params:
sidebar:
group: Application development
grid:
title: Quickstart
icon: rocket-launch
link: /offload/quickstart/title: About
icon: information-circle
link: /offload/about/title: Configure
icon: adjustments-horizontal
link: /offload/configuration/title: Usage
icon: heart
link: /offload/usage/title: Optimize
icon: bolt
link: /offload/optimize/title: Troubleshoot
icon: bug-ant
link: /offload/troubleshoot/title: Feedback
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 keywords: cloud, quickstart, Docker Desktop, offload
{{< summary-bar feature_name="Docker Offload" >}}
Docker Offload 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 contact sales and subscribe your
organization to use Docker Offload. After subscribing, see Manage Docker
products to learn how to manage
access for the developers in your organization.
Prerequisites
- You must have Docker 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.
- Start Docker Desktop and sign in.
- 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, 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.
Start Docker Desktop and sign in.
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.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 rundocker 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:
$ docker run --rm hello-worldIf 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 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:
$ docker offload stopWhen 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
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/
icon: magnifying-glass-plus - title: Image analysis
link: /scout/image-analysis/
icon: signal - title: Advisory database
link: /scout/advisory-db-sources/
icon: circle-stack - title: Integrations
Connect Docker Scout with your CI, registries, and other third-party services.
link: /scout/integrations/
icon: arrows-right-left - title: Dashboard
link: /scout/dashboard/
The web interface for Docker Scout.
icon: squares-2x2 - title: Policy
link: /scout/policy/
Ensure that your artifacts align with supply chain best practices.
icon: shield-check - title: Upgrade
link: /subscription-billing/manage/plans/
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
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 contains
a vulnerable Node.js application that you can use to follow along.
Clone its repository:
console$ git clone https://github.com/docker/scout-demo-service.gitMove into the directory:
console$ cd scout-demo-serviceMake sure you're signed in to your Docker account,
either by running thedocker logincommand or by signing in with Docker Desktop.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.
Sign in to your Docker account with the
docker logincommand or use the
Sign in button in Docker Desktop.Next, enroll your organization with Docker Scout, using the
docker scout enrollcommand.console$ docker scout enroll <ORG_NAME>Enable Docker Scout for your image repository with the
docker scout repo enablecommand.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:
$ docker scout cves --only-package expressDocker 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 theCLI reference documentation.
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:
"dependencies": {
- "express": "4.17.1"
+ "express": "4.17.3"
}Rebuild the image with a new tag and push it to your Docker Hub repository:
$ 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:
$ 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 detectedStep 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.
$ 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:
$ 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 dataExclamation 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:
CMD ["node","/app/app.js"]
EXPOSE 3000
+ USER appuserAdditionally, 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
(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.
$ 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.
- Open the Docker Scout Dashboard.
- Sign in with your Docker account.
- 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:
Manuals Security Index (`content/manuals/security/_index.md`)
title: Secure Docker accounts and organizations
linkTitle: Security
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
Two-factor authentication, single sign-on, and OIDC connections.
icon: key
link: /security/authentication/ - title: Access tokens
Personal and organization access tokens for the Docker CLI and
automation.
icon: lock-closed
link: /security/access-tokens/ - title: Provisioning
Add users with SCIM, JIT, auto-provisioning, and domain management.
icon: arrow-path
link: /security/provisioning/ - title: Roles and permissions
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.
Individual accounts
You sign in with your individual account.
- Two-factor authentication
(2FA) adds a time-based one-time password (TOTP) from an authenticator
app to your password. - A personal access token
(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
(SSO) federates sign-in through your identity provider, which can cover
one organization or every organization in a company. - Provisioning adds users with
System for Cross-domain Identity Management (SCIM), Just-in-Time (JIT)
provisioning, auto-provisioning, or domain matching. - An organization access token
(OAT) stays with the organization when membership changes. - OIDC connections
use OpenID Connect to authenticate GitHub Actions with short-lived
tokens, as an alternative to a long-lived OAT. - Roles and permissions
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
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
link: /subscription-billing/plans/
icon: chart-bar - title: Manage billing
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 | Flat-rate plans for personal and organization accounts | Docker Personal, Docker Pro, Docker Team, Docker Business |
| Docker Hardened Images (DHI) | Graduated security features for hardened container images | DHI Community, DHI Select, DHI Enterprise |
| Gordon | Prepaid usage for the Gordon AI agent | Gordon Plus, Gordon Max, Gordon Ultra |
| AI Governance | Purchase set amount of licenses | AI Governance |
| Docker Verified Publisher (DVP) | 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.
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. See
Docker plans to learn about
Docker Team, Business, and Pro. You can also
contact sales.
To update payment methods, review usage and credits, or download invoices, see
Manage billing.
Next steps
{{< grid >}}
Manuals Support Index (`content/manuals/support/_index.md`)
title: Get support for Docker products
linkTitle: Support
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.
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.
Community support
All Docker users can seek support through community resources, where Docker
or the community respond on a best-effort basis:
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
(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
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
Docker Desktop community resources
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.
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`)
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
icon: document-text
link: /reference/compose-file/version-and-name/ - title: Services top-level element
icon: wrench-screwdriver
link: /reference/compose-file/services/ - title: Networks top-level element
icon: server-stack
link: /reference/compose-file/networks/ - title: Volumes top-level element
icon: circle-stack
link: /reference/compose-file/volumes/ - title: Configs top-level element
icon: cog-6-tooth
link: /reference/compose-file/configs/ - title: Secrets top-level element
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 or try the quickstart guide.
The Compose Specification is the latest and recommended version of the Compose file format. It helps you define a Compose file 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.
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 extension for linting, code navigation, and vulnerability scanning.
{{< grid >}}
Reference Samples Index (`content/reference/samples/_index.md`)
linkTitle: Samples
title: Samples overview
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 | MongoDB | MS-SQL | MySQL | PostgreSQL | Redis
Frameworks
.NET | Angular | Django | Express |FastAPI | Flask | Node.js | React | Rails | Spark | Spring Boot | Vue.js
Languages
Go | Java | JavaScript | PHP | Python | Ruby | Rust | TypeScript
Platforms
Gitea | Nextcloud | Portainer | Prometheus | WordPress
Other samples
Agentic AI | AI/ML | Cloudflared | Elasticsearch / Logstash / Kibana | Minecraft | NGINX | Pi-hole | Plex | Traefik | WireGuard
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 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
owners administer.
keywords: company, multiple organizations, Docker Home, Docker Business,
company owners, SSO, SCIM
grid:
- title: Create a company
icon: building-office-2
link: /accounts/company/new-company/ - title: Manage your company
icon: building-storefront
link: /accounts/company/manage/ - title: Configure SSO and SCIM
icon: key
link: /security/authentication/single-sign-on/ - title: Domain management
icon: check-badge
link: /security/provisioning/domain-management/ - title: FAQs
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 in
Docker Home.
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:
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:#3b82f6What 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
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
icon: finger-print
link: /accounts/individual/create-account/ - title: Manage account
icon: cog
link: /accounts/individual/manage-account/ - title: Personal access tokens
icon: lock-closed
link: /security/access-tokens/ - title: Set up two-factor authentication
link: /security/authentication/2fa/manage/
icon: device-phone-mobile - title: Organization accounts
icon: building-storefront
link: /accounts/organization/ - title: Account FAQs
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. For organization accounts, including
companies, see
Organization accounts.
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),
Google, or GitHub.
Next steps
{{< grid >}}
Manuals Accounts Organization Index (`content/manuals/accounts/organization/_index.md`)
title: Organization accounts
linkTitle: Organization
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
icon: magnifying-glass-plus
link: /accounts/organization/setup/ - title: Manage your organization
icon: user-plus
link: /accounts/organization/manage/ - title: Activity logs
repositories.
icon: clipboard-document-list
link: /accounts/organization/activity-logs/ - title: Insights
icon: chart-bar
link: /accounts/organization/insights/ - title: Security
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:
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 5Owners
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.
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
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 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 (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:
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: shellThe 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 - From source: See the Docker Agent
repository
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:
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 modelsSave the example configuration as
debugger.yaml.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
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:
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
for complete details.
Share agent teams
Agent configurations are packaged as OCI artifacts. Push and pull them like
container images:
$ docker agent share push ./debugger.yaml myusername/debugger
$ docker agent share pull myusername/debuggerUse Docker Hub or any OCI-compatible registry. Pushing creates the repository if
it doesn't exist yet.
What's next
- Follow the quickstart to build your first agent
- Learn best practices for building effective agents
- Integrate Docker Agent with your editor or use agents as
tools in MCP clients - Browse example agent configurations in the Docker Agent
repository - Connect agents to external tools via the Docker MCP
Gateway - Read the full configuration reference
Manuals Ai Gordon Index (`content/manuals/ai/gordon/_index.md`)
title: Gordon
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. - Run
docker aiin the terminal to use the full assistant from the command
line. See Using Gordon via CLI. - Select the Gordon icon on any repository page at
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 to ask Docker questions.
Docker Desktop and the CLI count against your Gordon plan's usage
limits. 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:
- Contact Docker Support to activate Gordon for your organization. Docker
will confirm when activation is complete.- Once confirmed, an organization administrator must turn on Gordon via
Settings Management.
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" >}}
Open Docker Desktop.
Select Gordon in the sidebar.
Select your project directory.
Type a question: "What containers are running?"
Review Gordon's proposed actions and approve.
{{< /tab >}}
{{< tab name="CLI" >}}
Open your terminal and run:
console$ docker aiThis opens the Terminal User Interface (TUI) for Gordon.
Type a question: "what containers are running?" and press Enter.
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.
Try these examples
Container inspection:
$ docker ai "show me logs from my nginx container"Dockerfile review:
$ docker ai "review my Dockerfile for best practices"Image management:
$ 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
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.
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
- Pull models from Hugging Face
- Serve models on OpenAI and Ollama-compatible APIs for easy integration with existing apps
- Support for llama.cpp, vLLM, and Diffusers inference engines (vLLM and Diffusers on Linux with NVIDIA GPUs)
- Generate images from text prompts 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 like Cline, Continue, Cursor, and Aider
- Configure context size and model parameters to tune performance
- Set up Open WebUI 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 >}}
{{}}
How Docker Model Runner works
Models are pulled from Docker Hub, an OCI-compliant registry, or
Hugging Face 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.
Inference engines
Docker Model Runner supports three inference engines:
| Engine | Best for | Model format |
|---|---|---|
| llama.cpp | Local development, resource efficiency | GGUF (quantized) |
| vLLM | Production, high throughput | Safetensors |
| 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 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:
$ docker model configure --context-size 8192 ai/qwen2.5-coderSee Configuration options for details on context size and other parameters.
[!TIP]
Using Testcontainers or Docker Compose?
Testcontainers for Java
and Go, and
Docker Compose 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:
docker: 'model' is not a docker commandIt 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:
$ ln -s /Applications/Docker.app/Contents/Resources/cli-plugins/docker-model ~/.docker/cli-plugins/docker-modelOnce 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 (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. You can also give feedback through the Give feedback link next to the Enable Docker Model Runner setting.
Next steps
- Get started with DMR - Enable DMR and run your first model
- API reference - OpenAI and Ollama-compatible API documentation
- Configuration options - Context size and runtime parameters
- Inference engines - llama.cpp, vLLM, and Diffusers details
- IDE integrations - Connect Cline, Continue, Cursor, and more
- Open WebUI integration - 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
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 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.
Use the same Docker account to authenticate your application.
Cloud compute is billed separately from your Docker subscription. See
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 for installation instructions.
You can also call the REST API directly from any language or HTTP tool.
See the API reference for operations,
request fields, responses, and the downloadable OpenAPI specification.
To run agents from your terminal, see Docker Sandboxes.
Develop your application
- SDK cookbook: follow examples for processes, files,
storage, networking, and other sandbox operations. - API concepts: choose a kit or image, identify resources, and
wait for actions to finish. - Authentication and authorization: authenticate requests
and understand which permissions your application needs. - Errors and retries: handle failures and retry requests without
duplicating work. - Compute sizes and limits: choose resources and handle account
quotas and request rate limits.
Manuals Ai Sandboxes Index (`content/manuals/ai/sandboxes/_index.md`)
title: Docker Sandboxes
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.
Model-provider charges are separate.
Organization admins can
centrally manage sandbox network, filesystem, and MCP policies,
for local sandboxes across developer machines.
Available on a separate paid subscription.
Get started
Install the sbx CLI 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 |
| Cloud sandboxes | Run on Docker-managed compute without local virtualization | Get started in the cloud |
The two environments have separate credentials, network policies, and lifecycle
controls. See Compare local and cloud sandboxes
before adapting a workflow.
To create and manage cloud sandboxes from your application, see
Sandboxes API and SDK.
Learn more
The following guides describe local sandbox workflows. For cloud workflows,
see Cloud sandboxes.
- Agents — supported agents and per-agent configuration
- Workflows — patterns for Git, local development,
authentication, agent skills, and automation - Configuration — manage credentials, declare project
environments, turn on GPU passthrough, and configure an upstream proxy - Integrations — connect editors and apps like VS Code and
Cursor to a sandbox over SSH - MCP gateway — register MCP servers and connect them to
sandboxed agents - Kits — package tools and configuration into reusable
sandbox environments - Architecture — microVM isolation, workspace mounting,
networking - Security — isolation model, credential handling, and
network policies - CLI reference — full list of
sbxcommands and options - Troubleshooting — common issues and fixes
- FAQ — 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.
Manuals Ai Skills Index (`content/manuals/ai/skills/_index.md`)
title: Docker Skills
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
for available skills and their descriptions.
Get started
- Install Docker Skills with a method supported by your agent,
and start a new agent session. - Ask for an outcome in plain language, for example, “Make this Dockerfile
smaller and run as a non-root user.” - 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`)
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.
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 or create a custom transformation 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.
Compose Bridge also supports applications that use LLMs via Docker Model Runner.
For more details, see Use Model Runner.
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.
What's next?
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`)
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:
[!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:
Standalone (Legacy)
[!WARNING]
This install scenario is not recommended and is only supported for backward compatibility purposes.
You can install the Docker Compose standalone 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`)
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, images, volumes, builds, Kubernetes resources, and logs.
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.
- Enhance your organization's security posture for containerized development with Hardened Desktop.
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.
[!TIP]
Explore Docker's core subscriptions to see what else Docker can offer you.
Use AI features
- Gordon: 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: Manage, run, and deploy AI models using Docker.
- Docker MCP Toolkit: 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: Run builds and containers in the cloud when local resources aren't enough.
- Docker Hub: Search, browse, pull, run, or view details for images.
- Docker Extensions: 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
weight: 10
params:
grid_about:
- title: What are hardened images and why use them?
icon: information-circle
link: /dhi/explore/what/
- title: Build process
icon: wrench-screwdriver
link: /dhi/explore/build-process/
- title: Image types
icon: squares-2x2
link: /dhi/explore/available/
- title: Scanner integrations
icon: shield-check
link: /dhi/explore/scanner-integrations/
- title: Image testing
icon: beaker
link: /dhi/explore/test/
- title: Malware scanning
icon: bug-ant
link: /dhi/explore/malware-scanning/
- title: Responsibility overview
icon: user-group
link: /dhi/explore/responsibility/
- title: EU data residency
icon: globe-alt
link: /dhi/explore/eu-region/
- title: Security concepts
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
weight: 20
aliases:
- /dhi/how-to/manage/
params:
grid_discover:- title: Search and evaluate Docker Hardened Images
icon: globe-alt
link: /dhi/how-to/search-evaluate/
grid_adopt: - title: Get started with DHI Select and Enterprise
icon: rocket-launch
link: /dhi/how-to/select-enterprise/ - title: Mirror a Docker Hardened Image repository
icon: arrows-right-left
link: /dhi/how-to/mirror/ - title: Customize a Docker Hardened Image or chart
icon: cog-6-tooth
link: /dhi/how-to/customize/ - title: Use hardened system packages
icon: archive-box
link: /dhi/how-to/hardened-packages/ - title: Use a Docker Hardened Image
icon: play
link: /dhi/how-to/use/ - title: Use a Docker Hardened Image chart
icon: chart-bar
link: /dhi/how-to/helm/
grid_verify: - title: Verify a Docker Hardened Image or chart
icon: check-circle
link: /dhi/how-to/verify/ - title: Scan Docker Hardened Images
icon: bug-ant
link: /dhi/how-to/scan/ - title: Query VEX for a Docker Hardened Image
icon: bug-ant
link: /dhi/how-to/vex-api/
grid_govern: - title: Apply Docker Hardened Image policies to your images
icon: shield-check
link: /dhi/how-to/policies/
grid_troubleshoot: - title: Troubleshoot
icon: question-mark-circle
link: /dhi/how-to/troubleshoot/
- title: Search and evaluate Docker Hardened Images
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
weight: 18
keywords: migrate, docker hardened images, dhi, migration guide
aliases:
- /dhi/how-to/migrate/
params:
grid_migration_paths:- title: Migrate with Gordon
icon: sparkles
link: /dhi/migration/migrate-with-ai/ - title: Migrate from Alpine or Debian images
icon: code-bracket
link: /dhi/migration/migrate-from-doi/ - title: Migrate from Ubuntu
icon: arrow-up-circle
link: /dhi/migration/migrate-from-ubuntu/ - title: Migrate from Wolfi
icon: arrow-path
link: /dhi/migration/migrate-from-wolfi/
- title: Migrate with Gordon
grid_migration_resources:
- title: Migration checklist
icon: clipboard-document-check
link: /dhi/migration/checklist/
- title: Examples
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
weight: 25
params:
grid_tools:
- title: Use Docker Hub
icon: squares-2x2
link: /dhi/tools/hub/
- title: CLI
icon: command-line
link: /dhi/tools/cli/
- title: MCP server
icon: cpu-chip
link: /dhi/tools/mcp/
- title: Use the DHI Terraform provider
icon: wrench-screwdriver
link: /dhi/tools/terraform/
- title: Use the DHI 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`)
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: Discover how to browse and search Docker Hub's extensive resources.
- Trusted content: 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: Explore Docker Hub's generative AI catalogs
and sandbox kits. - Mirroring: 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`)
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 a repository.
Manage a repository, including how to manage:
Repository information: Add descriptions,
overviews, and categories to help users understand the purpose and usage of
your repository. Clear repository information aids discoverability and
usability.Access: 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: 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: Utilize
continuous Docker Scout analysis and static vulnerability scanning to
detect, understand, and address security issues within container images.Webhooks: 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: Integrate with GitHub or
Bitbucket for automated builds. Every code change triggers an image
rebuild, supporting continuous integration and delivery.Trusted content: 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 an outdated or unsupported repository.
Delete a repository.
Manuals Docker Hub Usage Index (`content/manuals/docker-hub/usage/_index.md`)
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.
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`)
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.
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
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:
$ dockerd --debug \
--tls=true \
--tlscert=/var/docker/server.pem \
--tlskey=/var/docker/serverkey.pem \
--host tcp://192.168.59.3:2376Listen 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:
PS C:\> dockerd -H unix://C:/Users/<USER>/docker.sock --group docker-usersReplace `` 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:
PS C:\> docker -H unix://C:/Users/<USER>/docker.sock infoLearn about the available configuration options in the
dockerd reference docs, or by
running:
$ dockerd --helpDaemon 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/dockeron LinuxC:\ProgramData\dockeron Windows
When using the containerd image store
(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
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.
{
"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:
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
- Run containerd in the Docker daemon
- Limit a container's resources
- Configure storage drivers
- Container security
- Configure the Docker daemon to use a proxy
Manuals Engine Install Index (`content/manuals/engine/install/_index.md`)
title: Install Docker Engine
linkTitle: Install
weight: 10
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.
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 | ✅ | ✅ | ✅ | ||
| Debian | ✅ | ✅ | ✅ | ✅ | |
| Fedora | ✅ | ✅ | ✅ | ||
| Raspberry Pi OS (32-bit) | ⚠️ | ||||
| RHEL | ✅ | ✅ | ✅ | ||
| Ubuntu | ✅ | ✅ | ✅ | ✅ | ✅ |
| Binaries | ✅ | ✅ | ✅ |
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, 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,
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 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.
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.
Apache License, Version 2.0. See 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 [email protected].
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.
Manuals Engine Logging Index (`content/manuals/engine/logging/_index.md`)
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. Thedocker 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, calledSTDIN, 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 andSTDERR. To read more about I/O and Linux, see the
Linux Documentation Project article on I/O redirection.
In some cases, docker logs may not show useful information unless you take
additional steps.
- If you use a logging driver which sends logs to a file, an
external host, a database, or another logging back-end, and have "dual logging"
disabled,docker logsmay 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 ofSTDOUT
andSTDERR.
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.
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.
Next steps
- Configure logging drivers.
- Write a Dockerfile.
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
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:
$ 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 msUser-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:
$ docker network create -d bridge my-net
$ docker run --network=my-net -it busyboxDrivers
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 | The default network driver. |
| host | Remove network isolation between the container and the Docker host. |
| none | Completely isolate a container from the host and other containers. |
| overlay | Swarm Overlay networks connect multiple Docker daemons together. |
| ipvlan | Connect containers to external VLANs. |
| macvlan | 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.
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 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.
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 anddocker 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.
$ docker run --network name=gwnet,gw-priority=1 --network anet1 --name myctr myimage
$ docker network connect anet2 myctrPublished 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.
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.
$ docker network create --ipv6 --ipv4=false v6netBy 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:
$ docker network create --ipv6 --subnet 192.0.2.0/24 --subnet 2001:db8::/64 mynetAutomatic 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:
{
"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 yourdefault-address-pools. See Dynamic IPv6 subnet allocation
for more information.
Docker attempts to avoid address prefixes already in use on the host. However, you may need to customizedefault-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:
{
"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:
$ 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
--subnetwas 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
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
bridgenetwork, 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 isNXDOMAIN.
On a custom network, Docker's embedded DNS server queries upstream servers in
order and stops after a successful response or anNXDOMAINresponse.
You can configure DNS resolution on a per-container basis, using flags for thedocker 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 in thedocker 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.
$ 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.1Manuals 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`)
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 withdocker 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
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.
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 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, 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.
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.
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 withdocker 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
runudevdor 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 performifconfig,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,
an allowlist instead of a denylist approach. You can see a full list of
available capabilities in Linux
manpages.
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.
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
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.
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
- Seccomp security profiles for Docker
- AppArmor security profiles for Docker
- On the Security of Containers (2014)
- Docker swarm mode overlay network security model
Manuals Engine Storage Index (`content/manuals/engine/storage/_index.md`)
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 and
storage 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 or Storage 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:
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.
Named pipes
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:
Learn more about daemon storage backends:
Manuals Engine Swarm Index (`content/manuals/engine/swarm/_index.md`)
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
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.
- Get started with the Swarm mode tutorial.
- Explore Swarm mode CLI commands
Manuals Extensions Extensions Sdk Index (`content/manuals/extensions/extensions-sdk/_index.md`)
title: Overview of the Extensions SDK
linkTitle: Extensions SDK
keywords: Docker, Extensions, sdk
aliases:
- /desktop/extensions-sdk/dev/overview/
- /desktop/extensions-sdk/
grid: - title: "The build and publish process"
icon: clipboard-document-check
link: "/extensions/extensions-sdk/process/" - title: "Quickstart guide"
icon: magnifying-glass-plus
link: "/extensions/extensions-sdk/quickstart/" - title: "View the design guidelines"
icon: paint-brush
link: "/extensions/extensions-sdk/design/design-guidelines/" - title: "Publish your extension"
icon: arrow-up-tray
link: "/extensions/extensions-sdk/extensions/" - title: "Interacting with Kubernetes"
icon: arrows-right-left
link: "/extensions/extensions-sdk/guides/kubernetes/" - title: "Multi-arch extensions"
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 [email protected] 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.
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 for further details.
{{% include "extensions-form.md" %}}
{{< grid >}}
Manuals Extensions Extensions Sdk Quickstart (`content/manuals/extensions/extensions-sdk/quickstart.md`)
title: Quickstart
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
[!NOTE]
NodeJS and Go are only required when you follow the quickstart guide to create an extension. It uses the
docker extension initcommand 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.
$ 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
backendfolder that listens on a socket. It has one endpoint/hellothat returns a JSON payload. - A React frontend in the
frontendfolder 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.
Step two: Build the extension
To build the extension, move into the newly created directory and run:
$ 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:
? 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:
$ 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 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 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 [email protected] 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.
Clean up
To remove the extension, run:
$ docker extension rm <name-of-your-extension>What's next
- Build a more advanced frontend for your extension.
- Learn how to test and debug your extension.
- Learn how to setup CI for your extension.
- Learn more about extensions architecture.
- Learn more about designing the UI.
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`)
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 usingdocker scout watch, 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:
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
- Generic CLI integration
For more information about environment integrations, see
Environments.
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 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.
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
- No copyleft licenses
- No outdated base images
- High-Profile Vulnerabilities
- Supply Chain Attestations
- Default Non-Root User
- Approved Base Images
For configuration options for each policy type, see
Evaluate 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.
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, 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 and
provenance
attestations. Images are non-compliant if they lack either attestation type.
To ensure compliance, build with attestations:
$ 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 theUSER 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
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:
$ 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
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
icon: lock-closed
link: /security/access-tokens/personal-access-tokens/ - title: Organization access tokens
icon: building-office-2
link: /security/access-tokens/organization-access-tokens/ - title: Reference
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,
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
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.
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.
OIDC connections
If your automation runs in GitHub Actions, you don't need to store a token.
An OIDC connection
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
keywords: authentication, SSO, OIDC, two-factor authentication, 2FA, Docker security
weight: 20
grid:
- title: Single sign-on
icon: key
link: /security/authentication/single-sign-on/ - title: Two-factor authentication
icon: device-phone-mobile
link: /security/authentication/2fa/ - title: OIDC connections
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.
Enforce sign-in is configured in Enterprise, not in this section.
Next steps
{{< grid >}}
Manuals Security Provisioning Index (`content/manuals/security/provisioning/_index.md`)
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
icon: globe-alt
link: "domain-management/" - title: SCIM provisioning
icon: arrow-path
link: "scim/" - title: Just-in-Time (JIT) provisioning
icon: clock
link: "just-in-time/" - title: Auto-provisioning
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) | 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) | 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 | 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 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.
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 Roles And Permissions Index (`content/manuals/security/roles-and-permissions/_index.md`)
title: Docker organization roles and permissions
linkTitle: Roles and permissions
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
Compare permissions for the built-in Member, Editor, and Owner roles.
icon: shield-check
link: /security/roles-and-permissions/core-roles/ - title: Custom roles
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
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
keywords: manage plans, billing, payment methods, invoices, taxes, docker subscription
weight: 20
grid:
- title: Manage plans
icon: shopping-cart
link: /subscription-billing/manage/plans/ - title: Add or update a payment method
icon: credit-card
link: /subscription-billing/manage/payment-method/ - title: Update billing information
icon: pencil-square
link: /subscription-billing/manage/details/ - title: View billing history
icon: credit-card
link: /subscription-billing/manage/history/ - title: 3D Secure authentication
icon: wallet
link: /subscription-billing/manage/3d-secure/ - title: Taxes
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:
- Sign in to Docker Home, then choose your
personal account or organization. - Select Billing.
- Select the page you want in the sidebar, or stay on Overview.
To add or upgrade a plan, see
Manage plans. To compare
plan types, see Plans.
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
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
link: /subscription-billing/plans/docker/
icon: credit-card - title: Gordon plans
link: /subscription-billing/plans/gordon/
icon: /icons/gordon.svg - title: Docker Hardened Images (DHI)
link: /subscription-billing/plans/dhi/
icon: /icons/dhi.svg - title: AI Governance
link: /subscription-billing/plans/ai-governance/
icon: shield-check - title: Docker Verified Publisher (DVP)
link: /subscription-billing/plans/docker-verified-publisher/
icon: check-badge
[!TIP]
Interested in pricing details? Check out the
pricing page 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.
Each plan page covers usage entitlements, billing cycle, and management
options. To add or upgrade a plan, see
Manage plans.
Product catalog
{{< grid >}}
Reference Api Ai Governance Index (`content/reference/api/ai-governance/_index.md`)
title: Docker AI Governance API 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
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.
The Docker Engine API is a RESTful API accessed by an HTTP client such as wget orcurl, 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.
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:
$ 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
curldirectly, 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 bydocker version, set the
environment variableDOCKER_API_VERSIONto 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 theclientobject. See the
Go constructor
or the
Python SDK documentation forclient.
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 | 1.40 | changes |
| 29.7 | 1.55 | 1.40 | changes |
| 29.6 | 1.55 | 1.40 | changes |
| 29.5 | 1.54 | 1.40 | changes |
| 29.4 | 1.54 | 1.40 | changes |
| 29.3 | 1.54 | 1.40 | changes |
| 29.2 | 1.53 | 1.44 | changes |
| 29.1 | 1.52 | 1.44 | changes |
| 29.0 | 1.52 | 1.44 | changes |
| 28.5 | 1.51 | 1.24 | changes |
| 28.4 | 1.51 | 1.24 | changes |
| 28.3 | 1.51 | 1.24 | changes |
| 28.2 | 1.50 | 1.24 | changes |
| 28.1 | 1.49 | 1.24 | changes |
| 28.0 | 1.48 | 1.24 | changes |
| 27.5 | 1.47 | 1.24 | changes |
| 27.4 | 1.47 | 1.24 | changes |
| 27.3 | 1.47 | 1.24 | changes |
| 27.2 | 1.47 | 1.24 | changes |
| 27.1 | 1.46 | 1.24 | changes |
| 27.0 | 1.46 | 1.24 | changes |
| 26.1 | 1.45 | 1.24 | changes |
| 26.0 | 1.45 | 1.24 | changes |
| 25.0 | 1.44 | 1.24 | changes |
| 24.0 | 1.43 | 1.12 | changes |
| 23.0 | 1.42 | 1.12 | changes |
| 20.10 | 1.41 | 1.12 | changes |
| 19.03 | 1.40 | 1.12 | 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 |
| 18.06 | 1.38 | 1.12 | changes |
| 18.05 | 1.37 | 1.12 | changes |
| 18.04 | 1.37 | 1.12 | changes |
| 18.03 | 1.37 | 1.12 | changes |
| 18.02 | 1.36 | 1.12 | changes |
| 17.12 | 1.35 | 1.12 | changes |
| 17.11 | 1.34 | 1.12 | changes |
| 17.10 | 1.33 | 1.12 | changes |
| 17.09 | 1.32 | 1.12 | changes |
| 17.07 | 1.31 | 1.12 | changes |
| 17.06 | 1.30 | 1.12 | changes |
| 17.05 | 1.29 | 1.12 | changes |
| 17.04 | 1.28 | 1.12 | changes |
| 17.03.1 | 1.27 | 1.12 | changes |
| 17.03 | 1.26 | 1.12 | changes |
| 1.13.1 | 1.26 | 1.12 | changes |
| 1.13 | 1.25 | 1.12 | changes |
| 1.12 | 1.24 | 1.12 | changes |
| 1.11 | 1.23 | 1.12 | changes |
| 1.10 | 1.22 | 1.12 | changes |
| 1.9 | 1.21 | 1.12 | changes |
| 1.8 | 1.20 | 1.12 | changes |
| 1.7 | 1.19 | 1.0 | changes |
| 1.6 | 1.18 | 1.0 | changes |
| 1.5 | 1.17 | 1.0 | changes |
| 1.4 | 1.16 | 1.0 | changes |
| 1.3 | 1.15 | 1.0 | changes |
| 1.2 | 1.14 | 1.0 | changes |
| 1.1 | 1.13 | 1.0 | changes |
| 1.0 | 1.12 | 1.0 | changes |
| 0.12 | 1.12 | 1.0 | changes |
| 0.11 | 1.11 | 1.0 | changes |
| 0.10 | 1.10 | 1.0 | changes |
| 0.9 | 1.10 | 1.0 | changes |
| 0.8 | 1.9 | 1.0 | changes |
| 0.7.1 | 1.8 | 1.0 | changes |
| 0.7 | 1.7 | 1.0 | changes |
| 0.6.4 | 1.6 | 1.0 | changes |
| 0.6.2 | 1.5 | 1.0 | changes |
| 0.6 | 1.4 | 1.0 | changes |
| 0.5 | 1.3 | 1.0 | changes |
| 0.4.1 | 1.2 | 1.0 | changes |
| 0.3.4 | 1.1 | 1.0 | changes |
| 0.3.3 | 1.0 | 1.0 | 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
keywords: Docker, extensions, sdk, API, reference
aliases:
- /desktop/extensions-sdk/dev/api/reference/README/
- /extensions/extensions-sdk/dev/api/reference/README/
Dashboard interfaces
Other interfaces
- ExecResultV0
- RequestConfigV0
- BackendV0
- OpenDialogResult
- Dialog
- Docker
- DockerCommand
- ExecOptions
- SpawnOptions
- Exec
- ExecProcess
- ExecStreamOptions
- ExecResult
- RawExecResult
- Extension
- DesktopUI
- ExtensionVM
- ExtensionHost
- ExtensionCli
- HttpService
- RequestConfig
- ServiceError
- DockerDesktopClient
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 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
keywords: manage organization, members, teams, licenses, seats, product access, organization management, docker home, organization settings, deactivate organization
grid:
- title: Members
icon: user-plus
link: /accounts/organization/manage/members/ - title: Teams
icon: user-group
link: /accounts/organization/manage/manage-a-team/ - title: Products
icon: squares-2x2
link: /accounts/organization/manage/manage-products/ - title: Licenses
icon: key
link: /accounts/organization/manage/manage-licenses/ - title: Seats
icon: user-circle
link: /accounts/organization/manage/manage-seats/ - title: Information
icon: pencil-square
link: /accounts/organization/manage/general-settings/ - title: Deactivation
icon: minus-circle
link: /accounts/organization/manage/deactivate-account/ - title: Security
icon: shield-check
link: /security/ - title: Billing
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 and
must be assigned the
organization owner role.
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
and Manage licenses.
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
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
icon: building-storefront
link: /accounts/organization/setup/orgs/ - title: Convert your account
icon: arrows-right-left
link: /accounts/organization/setup/convert-account/ - title: Onboard your organization
icon: magnifying-glass-plus
link: /accounts/organization/setup/onboard/ - title: Manage your organization
icon: user-group
link: /accounts/organization/manage/ - title: Security
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 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
innamespace/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 useacmeas 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.
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
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 to run your first sandbox, or
install the SDK to use these examples in an existing project.
For HTTP operations and request fields, see the
API reference.
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 keywords: docker sandboxes, ai agents, claude code, codex, cursor, devin, gemini
Docker Sandboxes runs the following agents in local sandboxes:
- Claude Code
- Codex
- Copilot
- Cursor
- Devin
- Docker Agent
- Droid
- Gemini
- Kiro
- OpenCode
- Shell — agent-less sandbox for manual setup or testing
Want to pre-install tools or customize an agent's environment?
See Customize.
Manuals Ai Sandboxes Cloud Index (`content/manuals/ai/sandboxes/cloud/_index.md`)
title: Cloud sandboxes 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:
$ sbx --cloud lsCloud 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 before adapting a local
workflow.
Prerequisites
To use cloud sandboxes, you need:
- The
sbxCLI, version 0.45.0 or later - An active Docker Agentic Platform subscription
Follow Signup and billing 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:
$ sbx loginFor CI and other environments without a browser, sign in with a Docker
Personal Access Token (PAT) for the subscribed account:
$ echo "$DOCKER_PAT" | sbx login --username <your-docker-id> --password-stdinFor PAT setup instructions, see CI and headless use.
Check cloud connectivity and account access:
$ sbx --cloud diagnoseIf the check reports that your account doesn't have access, follow
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:
$ sbx --cloud secret set anthropicSee Authenticate cloud agents 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.
Create a sandbox without attaching, allowing access to GitHub for this example:
$ sbx --cloud create --name cloud-project --allow-network github.com:443 claudeCloud sandboxes don't accept a local workspace path. Clone the public
Welcome to Docker repository
inside the sandbox:
$ sbx --cloud exec cloud-project git clone \
https://github.com/docker/welcome-to-docker.git /home/agent/workspace/projectAttach to the agent:
$ sbx --cloud attach cloud-projectAsk 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:
$ sbx --cloud cp cloud-project:/home/agent/workspace/review.md ./review.mdRead the result, then remove the sandbox when you're finished:
$ sbx --cloud rm cloud-projectRemoval deletes files stored only in the sandbox. For your own projects, see
Transfer files and
Authenticate cloud agents before cloning private repositories.
Learn more
- Signup and billing covers activation
and compute charges - Local and cloud differences compares the two execution
environments - Use cloud sandboxes covers creation, files, ports, and lifecycle
- Authenticate cloud agents covers cloud-specific secrets,
API keys, and OAuth - Manage cloud network policy covers account-level and
sandbox-level network access - Move a sandbox explains filesystem transfers between local and
cloud environments sbxCLI reference lists commands and options
Manuals Ai Sandboxes Configuration Index (`content/manuals/ai/sandboxes/configuration/_index.md`)
title: Configure Docker Sandboxes linkTitle: Configuration weight: 60 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.
- Settings lists host-level settings, environment variable
equivalents, and commands to inspect and change values. - Credentials configures API keys, authentication
credentials, and registry access for sandboxed agents. - Models selects local models, hosted providers, or custom
inference endpoints for sandboxed agents. - Environment files declare reusable project
configuration insbxenv.yamlfor local or cloud sandboxes. - GPU passthrough configures a Linux host and sandbox for
NVIDIA GPU workloads. - Registry mirror routes Docker Hub template, kit, and
in-sandbox Docker image pulls through an organization's registry mirror. - Upstream proxy 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
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.
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 asdocker.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:
$ sbx run docker.io/docker/sbx-kit-claude:2.1.267 --kit docker.io/sbx/playwright:1.61.1The 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.
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 for how to run kits
and add mixins. To customize and publish your own combination, see
Compose a kit set.
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, sosbx run claude --kit ./some-v3-mixin fails. To use that mixin, choose a
v3 workload
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
for details. V2 remains supported and is not deprecated.
Choose your next step
- Use kits to run a published environment or combine
a workload with mixins. - Author kits 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
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 Governance Index (`content/manuals/ai/sandboxes/governance/_index.md`)
title: Governance weight: 120 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 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. 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.
Organization policy is configured centrally in Docker Home. Network and
filesystem policies can also be managed via the
Governance API. 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.
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 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
to request access.
Learn more
Start with Policy concepts for the resource model, rule syntax,
MCP policy basics, evaluation, and precedence.
Access controls
- Local policy: configure network rules on your
machine with thesbx policyCLI. - Organization policies: centrally manage
sandbox policies across your organization. - Network access policies: control outbound network
access from sandboxes, by host or by HTTP method and path. - Filesystem access policies: control which
host paths sandboxes can mount as workspaces. - MCP access policies: control MCP server registration,
tool calls, resources, prompts, and approval gates.
Monitor and enforce
- Monitoring policies: inspect active
rules and monitor sandbox network traffic withsbx policy lsandsbx policy log. - Audit logs: view, configure, export, and collect governance audit
records. - Sign-in enforcement: require
developers to sign in as organization members, enforced through endpoint
management.
Reference
- AI Governance API: manage network and
filesystem org policies programmatically. - MCP policy reference: 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 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.
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
sbxCLI installed and signed in. See Get started. - 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:
$ sbx setup sshThe 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 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:
$ sbx setup ssh --auto-createSetup 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:
$ sbx setup ssh removeThis 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.
To create a named shell sandbox for the current directory:
$ sbx create --name demo shell .To identify an existing sandbox, list your sandboxes:
$ sbx lsConnect to a sandbox over SSH
Use the sandbox name with the .sbx suffix. For example, to connect to a
sandbox named demo:
$ ssh demo.sbxSelect 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
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:
# >>> 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 *.sbxmaps sandbox hostnames to the sandbox daemon. Application host
pickers don't discover individual sandbox names from this wildcard, so enter
the hostname, such asdemo.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
ProxyCommandrelays 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 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 to127.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 to127.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 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, 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 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--skillsorskills.defaultMode
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
readwriteaccess 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
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.
Isolation layers
The sandbox security model has five layers. See
Isolation layers 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. 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 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 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.
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.
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 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.
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 for the controls available to organization
admins.
Learn more
- Isolation layers: how hypervisor, network, Docker,
workspace, and credential isolation work - Default security posture: what a fresh sandbox permits and
blocks - Manage credentials: provide and manage API
keys while keeping their values outside the sandbox - 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 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.
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
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.
Tools inside the sandbox can use credentials configured on the host without
copying secret values into the VM. See
Authenticate command-line tools 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.
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.
For unattended jobs, use headless authentication and manage the sandbox
lifecycle from scripts. See Run sandboxes in CI.
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
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.
- How environment variable precedence works within your container's environment.
- Pre-defined environment variables.
It also covers:
- How interpolation can be used to set variables within your Compose file and how it relates to a container's environment.
- Some best practices.
Manuals Compose How Tos Multiple Compose Files Index (`content/manuals/compose/how-tos/multiple-compose-files/_index.md`)
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 them using
the -f flag. This works well for straightforward overrides, but the
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 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 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
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)
- Configuration profiles method (Mac only)
.plistmethod (Mac only)registry.jsonmethod (all platforms)
Deploying a admin-settings.json file with Settings Management also enforces sign-in. See 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, orregistry.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:
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, anddocker logincontinue 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, 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 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.
- To configure SSO enforcement, see Enforce SSO.
Manuals Desktop Enterprise Enterprise Deployment Index (`content/manuals/desktop/enterprise/enterprise-deployment/_index.md`)
title: Deploy Docker Desktop
weight: 10
keywords: msi, docker desktop, windows, installation, mac, pkg, enterprise
grid:
- title: MSI installer
link: /desktop/enterprise/enterprise-deployment/msi-install-and-configure/ - title: PKG installer
link: /desktop/enterprise/enterprise-deployment/pkg-install-and-configure/ - title: MS Store
link: /desktop/enterprise/enterprise-deployment/ms-store/ - title: Deploy with Intune
link: /desktop/enterprise/enterprise-deployment/use-intune/ - title: Deploy with Jamf Pro
link: /desktop/enterprise/enterprise-deployment/use-jamf-pro/ - title: Docker Desktop for Microsoft Dev Box
link: /desktop/enterprise/enterprise-deployment/dev-box/ - title: FAQs
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
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"
icon: shield-check
link: /desktop/enterprise/hardened-desktop/settings-management/ - title: "Enhanced Container Isolation"
icon: shield-check
link: /desktop/enterprise/hardened-desktop/enhanced-container-isolation/ - title: "Registry Access Management"
icon: server
link: /desktop/enterprise/hardened-desktop/registry-access-management/ - title: "Image Access Management"
icon: photo
link: /desktop/enterprise/hardened-desktop/image-access-management/ - title: "Air-Gapped Containers"
icon: lock-closed
link: /desktop/enterprise/hardened-desktop/air-gapped-containers/ - title: "Namespace access"
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
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:
- Sign in to Docker Home and select your organization.
- 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
available throughregistry.jsonand 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.
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:
- Sign in to Docker Home and select your organization.
- Select Docker Desktop, then Unassociated.
- Turn on the Enforce sign-in toggle.
- 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:
- Sign in to Docker Home and select your organization.
- Select Docker Desktop, then Unassociated.
- Locate the machine you want to enable sign-in enforcement for.
- Select the Actions menu and choose Turn on sign-in enforcement.
- 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. - SSO user provisioning: If you have SSO configured with
Just-in-Time provisioning,
users who sign in through your SSO connection will automatically be added
to your organization.
- Auto-provisioning: If you have verified domains with auto-provisioning
- 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
- Sign in to Docker Home and select your organization.
- Select Docker Desktop, then Unassociated.
- Locate the machine you want to add to your organization.
- Select the Actions menu and choose Add to organization.
- In the pop-up modal, select Add user.
Bulk add users
- Sign in to Docker Home and select your organization.
- Select Docker Desktop, then Unassociated.
- Use the checkboxes to select the machines you want to add to your
organizations. - Select the Add to organization button.
- In the pop-up modal, select Add users to confirm.
Disable sign-in enforcement
Disable for all unassociated machines
- Sign in to Docker Home and select your organization.
- Select Docker Desktop, then Unassociated.
- Turn off the Enforce sign-in toggle.
- 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
- Sign in to Docker Home and select your organization.
- Select Docker Desktop, then Unassociated.
- Locate the machine you want to disable sign-in enforcement for.
- Select the Actions menu and choose Turn off sign-in enforcement.
- 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
keywords: Docker, ai, mcp servers, ai agents, extension, docker desktop, llm, docker hub
grid:
- title: Get started with MCP Toolkit
icon: magnifying-glass-plus
link: /ai/mcp-catalog-and-toolkit/get-started/ - title: MCP Catalog
icon: globe-alt
link: /ai/mcp-catalog-and-toolkit/catalog/ - title: MCP Profiles
icon: folder
link: /ai/mcp-catalog-and-toolkit/profiles/ - title: MCP Toolkit
icon: /icons/toolkit.svg
link: /ai/mcp-catalog-and-toolkit/toolkit/ - title: MCP Gateway
icon: cpu-chip
link: /ai/mcp-catalog-and-toolkit/mcp-gateway/ - title: Dynamic MCP
icon: magnifying-glass
link: /ai/mcp-catalog-and-toolkit/dynamic-mcp/ - title: Security FAQs
icon: shield-check
link: /ai/mcp-catalog-and-toolkit/faqs/
{{< summary-bar feature_name="Docker MCP Catalog and Toolkit" >}}
Model Context Protocol (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 and 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 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 with approved
servers for their teams.
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 to learn more.
Learn more
{{< grid >}}
Manuals Desktop Features Networking Index (`content/manuals/desktop/features/networking/_index.md`)
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.backendprocess. - On Linux, the
qemuprocess performs this function.
- On Windows and Mac, this is handled by the
- File server: Handles file access from containers to the host filesystem.
- When using gRPC FUSE, the backend performs the file sharing.
- When using
virtiofs, orkrun, 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.
When a container initiates a network request, for example with apt-get update or docker pull:
- The container’s
eth0interface 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. - 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
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.
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
localhostas a workaround. - CLI plugins and other tools that use the Docker API directly must be configured separately with the
HTTP_PROXY,HTTPS_PROXY, andNO_PROXYenvironment 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`)
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.
- Met the Docker Desktop for Windows' system requirements.
- Installed the WSL 2 feature on Windows. For detailed instructions, refer to the Microsoft documentation.
[!TIP]
Consider enabling the WSL autoMemoryReclaim 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.
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.
Start Docker Desktop from the Windows Start menu.
Navigate to Settings.
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.
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 toSettings -> Resources -> Advancedpage from the Docker Dashboard.
Read more about this and other Windows settings at Changing settings
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.
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 -vTo upgrade the Linux distribution to v2, run:
console$ wsl.exe --set-version (distribution name) 2To set v2 as the default version for future installations, run:
console$ wsl.exe --set-default-version 2When Docker Desktop starts, go to Settings > Resources > WSL Integration.
The Docker-WSL integration is enabled on the default WSL distribution, which is Ubuntu. 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.
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 to add an additional layer of protection around container workloads regardless of backend.
Additional resources
- Explore best practices
- Understand how to develop with Docker and WSL 2
- Learn about GPU support with WSL 2
- Custom kernels on WSL
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`)
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.
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
- From Troubleshoot, select Get support. This opens the in-app Support page and starts collecting the diagnostics.
- When the diagnostics collection process is complete, select Upload to get a Diagnostic ID.
- When the diagnostics are uploaded, Docker Desktop prints a diagnostic ID. Copy this ID.
- 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
- 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.
- When the diagnostics are uploaded, Docker Desktop prints a diagnostic ID. Copy this ID.
- 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. 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 command:
$ docker desktop diagnoseGathering 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" >}}
Locate the
com.docker.diagnosetool: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.exeCreate 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" >}}
Locate the
com.docker.diagnosetool:console$ /Applications/Docker.app/Contents/MacOS/com.docker.diagnoseCreate 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" >}}
Locate the
com.docker.diagnosetool:console$ /opt/docker-desktop/bin/com.docker.diagnoseCreate 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" >}}
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"Open the file in your preferred text editor. Run:
powershell$ code <path-to-file>
{{< /tab >}}
{{< tab name="Mac" >}}
Run:
$ open /tmp/<your-diagnostics-ID>.zip{{< /tab >}}
{{< tab name="Linux" >}}
Run:
$ unzip –l /tmp/<your-diagnostics-ID>.zip{{< /tab >}}
{{< /tabs >}}
Use your diagnostics ID to get help
If you have a Docker subscription, Contact support. Fill in the information required and add your diagnostics ID.
If you don't have a Docker subscription, create an issue on GitHub.
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:
$ docker desktop diagnoseView the Docker daemon logs
Refer to the Read the daemon logs section
to learn how to view the Docker Daemon logs.
Further resources
- View specific troubleshoot topics.
- Get support for Docker products
Manuals Dhi Explore Security Concepts Index (`content/manuals/dhi/explore/security-concepts/_index.md`)
aliases:
- /dhi/core-concepts/
title: Security concepts
linkTitle: Security concepts
weight: 60
params:
grid_concepts_metadata:- title: Attestations
icon: clipboard-document-list
link: /dhi/explore/security-concepts/attestations/ - title: Software Bill of Materials (SBOMs)
icon: list-bullet
link: /dhi/explore/security-concepts/sbom/ - title: Supply-chain Levels for Software Artifacts (SLSA)
icon: clipboard-document-check
link: /dhi/explore/security-concepts/slsa/ - title: Image provenance
icon: pencil-square
link: /dhi/explore/security-concepts/provenance/
- title: Attestations
grid_concepts_compliance:
- title: FIPS
icon: check-badge
link: /dhi/explore/security-concepts/fips/
- title: STIG
icon: shield-check
link: /dhi/explore/security-concepts/stig/
- title: CIS Benchmarks
icon: check-circle
link: /dhi/explore/security-concepts/cis/
grid_concepts_risk:
- title: Common Vulnerabilities and Exposures (CVEs)
icon: exclamation-circle
link: /dhi/explore/security-concepts/cves/
- title: Vulnerability Exploitability eXchange (VEX)
icon: exclamation-triangle
link: /dhi/explore/security-concepts/vex/
- title: Software Supply Chain Security
icon: shield-check
link: /dhi/explore/security-concepts/sscs/
- title: Secure Software Development Lifecycle (SSDLC)
icon: wrench-screwdriver
link: /dhi/explore/security-concepts/ssdlc/
grid_concepts_structure:
- title: Distroless images
icon: squares-2x2
link: /dhi/explore/security-concepts/distroless/
- title: glibc and musl support in Docker Hardened Images
icon: arrows-up-down
link: /dhi/explore/security-concepts/glibc-musl/
- title: Image immutability
icon: minus-circle
link: /dhi/explore/security-concepts/immutability/
- title: Image hardening
icon: shield-check
link: /dhi/explore/security-concepts/hardening/
grid_concepts_verification:
- title: Digests
icon: finger-print
link: /dhi/explore/security-concepts/digests/
- title: Code signing
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
weight: 40
keywords: migration examples, dhi, docker hardened images
params:
grid_examples:
- title: Go
icon: code-bracket
link: /dhi/migration/examples/go/
- title: Python
icon: code-bracket
link: /dhi/migration/examples/python/
- title: Node.js
icon: code-bracket
link: /dhi/migration/examples/node/
- title: .NET
icon: code-bracket
link: /dhi/migration/examples/dotnet/
- title: Java
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 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 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.host: Remove network isolation between the container and the Docker host,
and use the host's networking directly.
See Host network driver.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.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.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 themacvlan
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.none: Completely isolate a container from the host and other containers.noneis not available for Swarm services.
See None network driver.Network plugins: 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`)
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 are met.
How it works
Rootless mode executes the Docker daemon and containers inside a user namespace.
This is similar to userns-remap mode, 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 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
newuidmapandnewgidmapon the host. These commands
are provided by theuidmappackage on most distributions./etc/subuidand/etc/subgidshould contain at least 65,536 subordinate
UIDs/GIDs for the user. In the following example, the usertestuserhas
65,536 subordinate UIDs/GIDs (231072-296607).
$ id -u
1001
$ whoami
testuser
$ grep ^$(whoami): /etc/subuid
testuser:231072:65536
$ grep ^$(whoami): /etc/subgid
testuser:231072:65536The 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.sockShould you choose not to shut down the
dockerservice 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, 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:
$ 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.sockIf dockerd-rootless-setuptool.sh is not present, you may need to install the docker-ce-rootless-extras package manually, e.g.,
$ 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.
Since static packages are not available for s390x, hence it is not supported for s390x.
$ 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.sockThe binaries will be installed at ~/bin.
{{< /tab >}}
{{< /tabs >}}
Run docker info to confirm that the docker client is connecting to the Rootless daemon:
$ docker info
Client: Docker Engine - Community
Version: 28.3.3
Context: rootless
...
Server:
...
Security Options:
seccomp
Profile: builtin
rootless
cgroupns
...See Troubleshooting if you faced an error.
Manuals Engine Security Trust Index (`content/manuals/engine/security/trust/_index.md`)
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.iowill shut down on December 8, 2026. For more information, see
Docker Content Trust (DCT).
Image tags and DCT
An individual image record has the following identifier:
[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. 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. 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.
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.
A prerequisite for signing an image is a Docker Registry with a Notary server (such as Docker Hub) attached.
Refer to 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.
$ 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.pubOr if you have an existing key:
$ 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.pemNext 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.
$ 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.
$ 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:1Alternatively, once the keys have been imported an image can be pushed with the$ docker push command, by exporting the DCT environmental variable.
$ 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:1Remote trust data for a tag or a repository can be viewed by the$ docker trust inspect command:
$ 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: 84ca6e4416416d78c4597e754f38517bea95ab427e5f95871f90d460573071fcRemote Trust data for a tag can be removed by the $ docker trust revoke command:
$ 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:1Client 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:
pushbuildcreatepullrun
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:
$ 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:ee7491c9c31db1ffb7673d91e9fac5d6354a89d0e97408567e09df069a1687c1Related information
- Delegations for content trust
- Automation with content trust
- Manage keys for content trust
- Play in a content trust sandbox
Manuals Engine Storage Drivers Index (`content/manuals/engine/storage/drivers/_index.md`)
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 asoverlay2. Docker
Engine 29.0 and later uses the containerd image store 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.
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 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:
# syntax=docker/dockerfile:1
FROM ubuntu:22.04
LABEL org.opencontainers.image.authors="[email protected]"
COPY . /app
RUN make /app
RUN rm -r $HOME/.cache
CMD python /app/app.pyThis 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
and use multi-stage builds
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 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 layersize.
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.
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:
$ 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.04Each 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:
$ ls /var/lib/docker/overlay2
16802227a96c24dcbeab5b37821e2b67a9f921749cd9a2e386d5a6d5bc6fc6d3
377d73dbb466e0bc7c9ee23166771b35ebdbe02ef17753d79fd3571d4ce659d7
3f02d96212b03e3383160d31d7c6aeca750d2d8a1879965b89fe8146594c453d
ec1ec45792908e90484f7e629330666e7eee599f08729c93890a7205a6ba35f5
lThe 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.
# syntax=docker/dockerfile:1
FROM alpine
RUN apk add --no-cache bashThe second one is based on acme/my-base-image:1.0, but has some additional
layers:
# syntax=docker/dockerfile:1
FROM acme/my-base-image:1.0
COPY . /app
RUN chmod +x /app/hello.sh
CMD /app/hello.shThe 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 anddocker image history commands to verify that the cryptographic IDs of the shared
layers are the same.
Make a new directory
cow-test/and change into it.Within
cow-test/, create a new file calledhello.shwith the following contents.bash#!/usr/bin/env bash echo "Hello world"Copy the contents of the first Dockerfile above into a new file called
Dockerfile.base.Copy the contents of the second Dockerfile above into a new file called
Dockerfile.Within the
cow-test/directory, build the first image. Don't forget to
include the final.in the command. That sets thePATH, which tells
Docker where to look for any files that need to be added to the image.text
/* 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.75MBCheck 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.6MBSome 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.6MBNotice 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 thedocker historyoutput indicate that those
steps were either built on another system and part of thealpineimage
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 theIMAGEcolumn would show
the ID of that image.BuildKit uses its own caching mechanism, and no longer requires intermediate
images for caching. Refer to BuildKit
to learn more about other enhancements made in BuildKit.Check out the layers for each image
Use the
docker image inspectcommand 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
--formatoption.The examples above use the
docker image inspectcommand 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 asawkorsed. To learn more about formatting
the output of docker commands using the--formatflag, refer to the
format command and log output section.
We also pretty-printed the JSON output using thejqutility
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_upoperation 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 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.
From a terminal on your Docker host, run the following
docker runcommands.
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 cddae31c314fbab3f7eabeb9b26733838187abc9a2ed53f97bd5b04cd7984a5aRun the
docker pscommand with the--sizeoption 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 psprovides 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/dockerby 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/cddae31c314fbab3f7eabeb9b26733838187abc9a2ed53f97bd5b04cd7984a5aEach of these containers only takes up 36k of space on the filesystem.
{{< /accordion >}}
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 containersmy_container_1,my_container_2, andmy_container_3:console$ for i in {1..3}; do docker exec my_container_$i sh -c 'printf hello > /out.txt'; doneRunning the
docker pscommand 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
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
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`)
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
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.
Set up
To run this tutorial, you need:
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
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
2377TCP for communication with and between manager nodes - Port
7946TCP/UDP for overlay network node discovery - Port
4789UDP (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 to use encryption
- Only accept encrypted packets on the Data Path Port:
# Example iptables rule (order and other tools may require customization)
iptables -I INPUT -m udp --dport 4789 -m policy --dir in --pol none -j DROPNext 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
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 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 theui section in the metadata.json. See the ui metadata 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.
[!TIP]
The
docker extension initgenerates 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 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 initgenerates 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 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
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 from the backend.
To communicate with the backend, the Extension SDK provides functions 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 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.
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 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 for more details.
Learn how to invoke host binaries.
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
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. We've opened parts of it to extension authors, documenting basic styles (color, typography) and components. See: Docker Extensions Styleguide.
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 (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 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 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 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, 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.
- Learn how to publish your extension.
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"
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 that the extension is built in the right format and includes the required information
- Making the extension image available on Docker Hub
See Package and release your extension 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 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 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.
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. 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`)
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:
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.
Manuals Scout Integrations Environment Index (`content/manuals/scout/integrations/environment/_index.md`)
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>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:
[!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, either manually or
through a registry integration.
List environments
To see all of the available environments for an organization, you can use thedocker scout env command.
$ docker scout envBy 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.
$ 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.
$ 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 thedocker scout compare
CLI command:
$ docker scout compare --to-env production myorg/webapp:latestView images for an environment
To view the images for an environment:
- Go to the Images page in the Docker Scout Dashboard.
- Open the Environments drop-down menu.
- 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 th