目录
Docker Compose 常用命令教程:掌握日常操作
所有 docker compose 命令都要在 compose.yaml 所在的文件夹(或子文件夹)中运行,或者使用 -f 指定文件。命令后面可以接服务名称,只对该服务进行操作;不接则操作整个项目。本节的示例都使用 Compose 入门 中的 compose-demo 项目。
启动与停止
| 命令 | 作用 |
|---|---|
docker compose up | 创建并启动,日志输出在前台,按 Ctrl+C 停止 |
docker compose up -d | 在后台启动 |
docker compose up -d --build | 先重新构建镜像再启动 |
docker compose up -d app | 只启动 app(以及它依赖的服务) |
docker compose up -d --force-recreate | 即使设置没有变化也重建容器 |
docker compose up -d --remove-orphans | 删除配置文件中已不存在的服务对应的容器 |
docker compose stop | 停止,保留容器 |
docker compose start | 启动已停止的容器 |
docker compose restart app | 重启服务(不会应用新设置,见下方实测) |
docker compose down | 停止并删除容器和网络 |
docker compose down -v | 同时删除 Volume(数据会消失) |
docker compose down --rmi local | 同时删除由 Compose 构建的镜像 |
up、stop、start、down 的实际输出见 Compose 入门。
查看状态
$ docker compose ps
NAME IMAGE COMMAND SERVICE CREATED STATUS PORTS
compose-demo-adminer-1 adminer "entrypoint.sh docke…" adminer 10 seconds ago Up 9 seconds 0.0.0.0:8081->8080/tcp, [::]:8081->8080/tcp
compose-demo-db-1 postgres:18 "docker-entrypoint.s…" db 10 seconds ago Up 9 seconds 5432/tcp
compose-demo-web-1 nginx:1.30-alpine "/docker-entrypoint.…" web 10 seconds ago Up 8 seconds 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp
$ docker compose ls
NAME STATUS CONFIG FILES
compose-demo running(3) /work/compose-demo/compose.yaml
$ docker compose images
CONTAINER REPOSITORY TAG PLATFORM IMAGE ID SIZE CREATED
compose-demo-adminer-1 adminer latest linux/amd64 74f29c416e14 164MB 2 weeks ago
compose-demo-db-1 postgres 18 linux/amd64 74935e722416 644MB 6 days ago
compose-demo-web-1 nginx 1.30-alpine linux/amd64 0985e772fb9f 92.8MB 2 weeks ago
$ docker compose top web
SERVICE # PID USER TIME COMMAND
web 1 21356 root 0:00 nginx: master process nginx -g daemon off;
web 1 21425 101 0:00 nginx: worker process
| 命令 | 内容 |
|---|---|
docker compose ps | 此项目的容器及其状态(-a 包含已停止的容器) |
docker compose ls | 这台机器上所有 Compose 项目及其配置文件位置 |
docker compose images | 每个容器使用的镜像、平台和大小 |
docker compose top web | 服务容器内的进程 |
查看日志
$ docker compose logs --tail 2 -t web
web-1 | 2026-10-13T00:18:19.618825771Z 2026/10/13 00:18:19 [notice] 1#1: start worker processes
web-1 | 2026-10-13T00:18:19.619080382Z 2026/10/13 00:18:19 [notice] 1#1: start worker process 30
docker compose logs # 所有服务
docker compose logs -f app # 持续跟踪 app
docker compose logs --tail 50 -t # 最后 50 行,并显示时间
在服务中执行命令
exec:在运行中的容器里
$ docker compose exec web nginx -v
nginx version: nginx/1.30.5
$ docker compose exec db psql -U postgres -c "SELECT now();"
now
-------------------------------
2026-10-13 00:18:28.618314+00
(1 row)
$ docker compose exec -T db pg_dump -U postgres postgres > backup.sql && wc -l backup.sql
27 backup.sql
$ rm backup.sql
- 使用服务名称(
web、db)指定容器,无需关心实际容器名称。 -T禁用伪终端。将输出重定向到文件(例如上面的pg_dump > backup.sql)或在脚本中使用时一定要加上,否则输出中可能混入终端控制字符。docker compose exec web sh会打开一个交互式 shell。
run:启动一个新的一次性容器
$ docker compose run --rm web nginx -t
Container compose-demo-web-run-80040d25219f Creating
Container compose-demo-web-run-80040d25219f Created
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
run 会使用服务的设置(镜像、环境变量、Volume、网络)创建一个新容器来执行命令(名称为 compose-demo-web-run-…),加上 --rm 后,容器结束时会自动删除。上面用它在不影响运行中服务的情况下检查 nginx 设置(nginx -t)。
| exec | run | |
|---|---|---|
| 容器 | 使用已运行的容器 | 创建新容器 |
| 服务需要先启动吗 | 是 | 否 |
应用 ports 吗 | — | 默认不应用,需要时加 --service-ports |
| 适用场景 | 进入容器调试、在运行中的服务里操作 | 运行测试、数据库迁移等一次性任务 |
修改设置后:restart 不够,要用 up -d
这是最常见的误解。来做个实验:在 compose.yaml 的 web 服务中添加环境变量 SITE_TITLE: v2,然后分别试试 restart 和 up -d:
$ docker compose --progress plain restart web
Container compose-demo-web-1 Restarting
Container compose-demo-web-1 Started
$ docker compose exec web sh -c "echo SITE_TITLE=\$SITE_TITLE"
SITE_TITLE=
$ docker compose up -d
[+] up 3/3
✔ Container compose-demo-db-1 Running 0.0s
✔ Container compose-demo-adminer-1 Running 0.0s
✔ Container compose-demo-web-1 Started 0.4s
$ docker compose exec web sh -c "echo SITE_TITLE=\$SITE_TITLE"
SITE_TITLE=v2
restart只是停止再启动现有容器。容器的设置在创建时就已确定,所以看不到新的环境变量(SITE_TITLE=为空)。up -d会对比compose.yaml和现有容器,发现web的设置发生变化后,就会重建web(Started);没有变化的db、adminer则保持原样(Running)。
修改了
compose.yaml或.env后,一律使用docker compose up -d。
构建与镜像
docker compose build # 构建所有设置了 build 的服务
docker compose build --no-cache app
docker compose pull # 下载所有服务的最新镜像
docker compose push # 推送设置了 image 名称的服务
$ docker compose pull
[+] pull 3/3
✔ Image adminer Pulled 0.7s
✔ Image nginx:1.30-alpine Pulled 0.5s
✔ Image postgres:18 Pulled 1.3s
更新使用现成镜像的服务,常见流程如下:
docker compose pull
docker compose up -d
docker image prune -f # 清除已被替换的旧版镜像
检查设置
$ docker compose config --services
db
adminer
web
$ docker compose config --volumes
pgdata
$ docker compose port web 80
0.0.0.0:8080
docker compose config # 显示合并并完成变量替换后的完整设置
docker compose config --services # 列出所有服务名称
docker compose config --volumes # 列出 Volume
docker compose port web 80 # 查看服务容器的某个端口映射到主机的哪个端口
docker compose config 的完整输出示例见 compose.yaml 语法。
其他
docker compose cp web:/etc/nginx/nginx.conf ./nginx.conf # 复制文件
docker compose watch # 开发时检测文件变化并自动同步或重建
docker compose up -d --scale worker=3 # 启动 3 个 worker
全局参数
这些参数写在 docker compose 和子命令之间:
docker compose -f compose.yaml -f compose.prod.yaml up -d
docker compose -p myproject up -d # 指定项目名称
docker compose --env-file .env.prod up -d # 指定 .env 文件
docker compose --profile tools up -d # 启用 profile
docker compose --progress plain up -d # 以纯文本显示进度(适合 CI 日志)
日常场景整理
| 我想要…… | 命令 |
|---|---|
| 开始一天的开发 | docker compose up -d |
修改了 compose.yaml 或 .env | docker compose up -d |
| 修改了 Dockerfile 或依赖列表 | docker compose up -d --build |
| 查看某个服务为什么出故障 | docker compose logs app |
| 进入数据库执行 SQL | docker compose exec db psql -U postgres |
| 执行一次数据库迁移 | docker compose run --rm app <迁移命令> |
| 收工 | docker compose stop 或 down |
| 完全重来(包括数据) | docker compose down -v |
重点回顾
- 修改 compose.yaml 或 .env 后,一律使用
docker compose up -d。 exec用于运行中的容器,run --rm会启动一次性容器。- 使用
docker compose config检查合并后的最终设置。 up与down的完整参数见 docker compose up 和 docker compose down。
动手练习
练习 1:修改 compose.yaml 中 web 的主机端口后,分别试试 docker compose restart web 和 docker compose up -d,哪个会应用新的端口设置?
答案
只有 up -d 会应用。restart 重启的是原来的容器,端口设置在创建容器时就已确定。
练习 2:使用一个一次性容器,在 db 服务的网络中运行 psql --version,并在结束后自动删除容器。
答案
docker compose run --rm db psql --version
常见问题
docker compose restart 和 up -d 有什么区别?
restart 只是重新启动同一个容器,不会应用 compose.yaml 和 .env 的修改;up -d 会对比设置并重建发生变化的服务。
docker compose exec 和 run 应该用哪个?
exec 在已运行的容器中执行命令;run 启动一个新的一次性容器,适合数据库迁移等工作,加上 --rm 可在使用后自动删除。
如何查看所有 Compose 项目?
docker compose ls 会列出这台机器上的所有 Compose 项目及其配置文件位置。
更新于 2026年10月14日