如何将 Docker Compose 设置作为独立容器运行

Docker compose 很棒!但有时解开 docker-compose.yml 文件并单独运行每个容器会很有用。

让我带你了解解构 Docker compose 文件的过程,以便你可以单独运行每个容器。

简而言之:

Docker compose 设置作为独立应用程序运行需要你首先确定已定义的所有服务以及每个单独服务使用的所有资源,例如存储、网络和环境设置。从单独重新创建这些资源开始,一旦一切设置完毕,为每个服务派生 docker build ...docker run ... 命令。

让我们仔细看看这个过程。

基本 Docker 概念

在开始之前,你需要了解最重要的 Docker 概念。如果你刚刚开始使用 Docker,我建议你查看下面 Docker 入门指南中的官方文档,尤其是尝试了解:

Docker 远不止这些,但如果你理解这些基本概念,阅读和理解 Docker 撰写文件将变得容易得多,并且你将能够运行大多数设置!

如何从 docker-compose.yml 文件单独运行服务
让我们看一个示例 docker 撰写文件,尝试解构它并将设置作为单独的容器运行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
version: "3.9"                                # Specify the version of Docker Compose being used

services: # Define the services (containers) that make up your app
app: # Service name: app
image: my-app:latest # The image to use for the app service (latest version)
container_name: my_app_container # Custom name for the container
build:
context: ./app # The build context (directory for the Dockerfile)
dockerfile: Dockerfile # The Dockerfile to build the image from
args:
- APP_ENV=production # Build argument for setting environment variable
environment:
- APP_ENV=production # Set the environment variable in the container
- APP_SECRET=mysecret # Another environment variable for the app
ports:
- "8080:80" # Map port 8080 on the host to port 80 on the container
volumes:
- app-data:/data # Volume mount for persistent app data
networks:
- shared-network # Connect the app to a shared network
depends_on:
- db # Ensure the db service starts before the app service
restart_policy:
condition: on-failure # Restart the app if it fails
labels:
com.example.description: "My web app" # Custom label to describe the app

db: # Service name: db
image: postgres:16 # Use the official PostgreSQL 16 image
container_name: my_db_container # Custom name for the database container
environment:
POSTGRES_PASSWORD: password # Set the PostgreSQL password
volumes:
- db-data:/var/lib/postgresql/data # Volume mount for database data persistence
networks:
- shared-network # Connect the db to the shared network
ports:
- "5432:5432" # Map PostgreSQL default port 5432 from container to host

volumes:
app-data: # Named volume for app data persistence
db-data: # Named volume for database data persistence

networks:
shared-network: # Define a shared network for both services to communicate

Docker compose 文件的结构在官方 compose 文件参考中进行了描述。在此示例中,有 4 个顶级选项:

  • version
  • services
  • volumes
  • networks

version 仅描述所使用的 Docker compose 版本,在本教程中我们不需要它。

第二个顶级选项 services 是这里最重要的。它描述了每个容器的配置。上面的 compose 文件中有 2 个服务:appdb,每个服务都表示为 services 块中的键。

但在我们可以单独运行每个服务之前,我们需要做一些准备工作。

你可以看到两个服务块都包含一个存储和网络部分。例如,app 服务使用将安装到 /data 的存储 app-data 和一个名为 shared-network的网络。db 服务使用将安装到 /var/lib/postgresql/data 的存储 db-data

服务可以引用的所有存储和网络都在 compose 文件的块 3 和 4 中进行了描述。在我们运行容器之前,我们需要设置两个存储 app-datadb-data和我们的网络共享网络。

1
2
3
4
5
6
# create the shared network that is used to connect containers
docker network create shared-network

# create volumes for the containers to persist data
docker volume create app-data
docker volume create db-data

现在一切就绪,我们为第一个容器编写一个运行命令。在 Compose 文件中,你可以看到,该应用程序依赖于 db,这意味着我们需要先运行 db 容器:

1
2
3
4
5
6
7
docker run \
-e POSTGRES_PASSWORD=password \ # Environment translates to -e flags or --env-file
-v db-data:/var/lib/postgresql/data \ # Mount the db-data volume
--network shared-network \ # Attach the container to the shared network
-p 5432:5432 \ # Map host port 5432 to container port 5432
-d \ # Run in detached mode
postgres

请注意,我有意没有使用上面 docker-compose.yml 文件中描述的所有设置。在这种情况下,我只是跳过了 container_name 选项。可以使用 --name my_db_container 标志来标记容器。但是,我想展示的是,docker compose 设置通常可以运行,而无需复制每个选项。区分必需设置和可选设置很重要,并且根据你的用例,你可能还可以运行更简单版本的 compose 设置,该版本足以满足你的用例。

同时,我在 run 命令中引入了一个新的标志 -d,该标志未在 compose 文件中明确描述。单独运行容器为你提供了一些灵活性。例如,你还可以在 .env 文件中定义环境变量,并在 run 命令中使用 --env-file 标志来访问它们。

接下来让我们看看应用服务。该服务在 compose 文件中包含一个构建块。这意味着,我们可能需要先构建我们的图像,然后才能从中运行容器。

1
2
3
4
docker build \
--build-arg APP_ENV=production \ # Build time configuration
-t app \ # Tag the image
./app \ # Define the build context (location that acts as the root for subsequent Docker commands)

如果构建成功,则可以使用以下命令运行应用程序映像:

1
2
3
4
5
6
7
8
9
10
docker run -d \
--name my_app_container \ # Custom container name
-p 8080:80 \ # Port mapping
-e APP_ENV=production \ # Environment variable
-e APP_SECRET=mysecret \ # Another environment variable
-v app-data:/data \ # Volume mount for persistent data
--network shared-network \ # Connect to shared network
--restart on-failure \ # Restart policy
--label com.example.description="My web app" \ # Custom label
my-app:latest

同样,你可以使用不同的重启策略或不使用标签来运行此应用程序。

尝试运行组合设置时要考虑的最重要的设置是:

  • 端口映射
  • 存储挂载
  • 网络
  • 环境变量

其他设置也是可能的,但通常不一定是必需的。

摘要

解构 Docker 组合文件并单独运行容器涉及识别组合文件中定义的服务、网络、存储和环境设置。

设置这些 Docker 对象后,你可以为每个服务派生必要的 docker 构建和运行命令。

虽然可以省略某些选项,但关键元素(如端口映射、存储挂载和环境变量)对于复制组合设置至关重要。