Skip to content
VDS · Docker 与容器

Docker Compose:一条命令运行多个服务

如何在一个文件中描述应用、数据库和 Web 服务器的组合,用一条命令启动,并在无需手动重建的情况下更新。

更新于 2026年8月23日

您可以用一条很长的 docker run 命令启动单个服务。但两个需要互相访问的服务就不行了:第二天您就会忘记那些参数。Compose 把整个描述搬进一个文件,您可以阅读、编辑,并保存在仓库中。

最小示例

/opt/myapp 目录,其中包含 compose.yaml:

services:
  db:
    image: postgres:17
    restart: unless-stopped
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
      POSTGRES_DB: app
    volumes:
      - db-data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      retries: 5

  app:
    image: ghcr.io/example/app:1.4.2
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
    environment:
      DATABASE_URL: postgres://postgres:${DB_PASSWORD}@db:5432/app
    ports:
      - "127.0.0.1:8080:8080"

volumes:
  db-data:

旁边是 .env 文件:

DB_PASSWORD=long-random-password
chmod 600 .env
docker compose up -d
docker compose ps
docker compose logs -f app

这里的关键点

  • 用名称代替地址。 应用通过名称 db 访问数据库——Compose 会创建一个共享网络,服务名称在其中自动解析。您不需要把数据库端口对外发布,也不应该这样做。
  • restart: unless-stopped。 没有它,机器重启后什么都不会自动恢复。
  • 带健康检查的 depends_on。 普通的 depends_on 只等待容器启动,而不等待数据库准备好接受连接。应用会提前启动并崩溃。
  • 精确的镜像版本。 用 postgres:17,而不是 postgres:latest。使用 latest,某次 pull 会带来一个无法打开旧数据的主版本。
  • 在 127.0.0.1 上发布。 只有通过带证书的 Web 服务器才对外暴露端口。

日常命令

docker compose up -d          # bring up or apply changes
docker compose down           # stop and remove containers (volumes intact)
docker compose down -v        # ...and remove volumes too
docker compose restart app    # restart one service
docker compose exec app sh    # go inside
docker compose pull && docker compose up -d   # update images
docker compose config         # show final file with substitutions

docker compose config 是启动前检查文件的最佳方式:它会显示变量展开成了什么,以及是否有缩进丢失。

docker compose down -v 会连同数据库一起删除卷。这是不可逆的。在执行任何带 -v 的操作之前,请确认您有副本——参见备份。

环境文件

用叠加文件把同一套栈区分测试和生产很方便:

docker compose -f compose.yaml -f compose.prod.yaml up -d

第二个文件只覆盖差异部分:内存限制、发布的端口和日志级别。

常见错误

  • 把密钥放在保存在仓库中的 compose.yaml 里。 请把它们放在权限为 600 的 .env 中,并且不要提交。
  • 混用 docker-compose 和 docker compose。 旧的 v1 版本不理解某些语法,并且会把项目存储在不同的名称下。请安装插件——参见Docker 安装。
  • 把数据放在容器里而不是卷中。 执行 docker compose down 后,数据会消失。参见卷。
  • 没有内存限制。 一个服务吃光整台机器的内存,内核就会杀掉它的邻居。参见资源限制。