冷蟊初退 孤灯野澜 志起鸡鸣 墓不悲秋 技术交流 软件开发 商业合作 加Q:411239339

Day 15 Docker Compose入门:一个命令启动全栈应用

浏览:32次阅读
没有评论

共计 3613 个字符,预计需要花费 10 分钟才能阅读完成。

Docker 30 天实战系列 · Day 15

你有没有经历过这样的场景:项目需要同时运行数据库、缓存、后端 API、前端应用,每次启动要敲五六条 docker run 命令,参数一长串,漏一个端口映射整个系统就跑不通?

Docker Compose 就是来终结这种痛苦的。 一个 YAML 文件定义所有服务,一条命令全部拉起。

什么是 Docker Compose

Docker Compose 是 Docker 官方提供的多容器编排工具。它的核心思想很简单:用一个 docker-compose.yml 文件,声明式地描述应用所需的所有服务、网络和存储卷,然后通过 docker compose up 一键启动整个应用栈。

你可以把它理解为一份 " 应用部署说明书 "。以前这份说明书在你脑子里,现在它变成了一个可版本控制、可复现、可分享的文件。

核心原理

Docker Compose 的工作流程分三步:

第一步:解析。 Compose 读取 docker-compose.yml,解析出每个服务的镜像、端口、环境变量、依赖关系等配置。

第二步:构建基础设施。 自动创建一个专属的 bridge 网络(默认以项目目录名为前缀),所有服务加入同一网络。同时创建声明的数据卷。

第三步:按依赖顺序启动容器。 根据 depends_on 声明的依赖关系,决定启动顺序。每个服务名自动注册为 DNS 名称——在容器内部,你可以直接用服务名当主机名访问其他服务。

这意味着:你再也不需要手动查容器 IP,也不需要 --link 做容器互联。Compose 内置的 DNS 解析帮你搞定一切。

YAML 配置详解

一个标准的 docker-compose.yml 长这样:

version: "3.8"

services:
  # 后端 API 服务
  backend:
    build: ./backend          # 从 Dockerfile 构建
    ports:
      - "8080:8080"           # 宿主机端口: 容器端口
    environment:
      - DB_HOST=db            # 直接用服务名作为主机名
      - DB_PORT=5432
      - REDIS_HOST=cache
    depends_on:
      - db
      - cache
    restart: unless-stopped

  # 前端服务
  frontend:
    build: ./frontend
    ports:
      - "3000:3000"
    depends_on:
      - backend

  # PostgreSQL 数据库
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: admin
      POSTGRES_PASSWORD: secret123
    volumes:
      - db_data:/var/lib/postgresql/data  # 持久化存储
    ports:
      - "5432:5432"

  # Redis 缓存
  cache:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  db_data:                    # 声明命名卷 

几个关键配置项拆解说明:

配置项 作用 注意事项
build 指定 Dockerfile 路径并构建镜像 image 二选一,也可同时使用
image 直接拉取已有镜像 指定版本号,避免用 latest
ports 端口映射 格式为 宿主机: 容器 ,注意端口冲突
volumes 数据持久化 命名卷需要在顶层 volumes 声明
depends_on 启动顺序控制 只保证启动顺序,不保证服务就绪
environment 环境变量注入 敏感信息建议使用 .env 文件
restart 重启策略 生产环境推荐 unless-stopped

常用命令速查

掌握以下 8 个命令,日常使用基本够了:

# 启动所有服务(后台运行)docker compose up -d

# 查看运行状态
docker compose ps

# 查看日志(实时跟踪)docker compose logs -f backend

# 停止所有服务
docker compose stop

# 停止并删除容器、网络(保留数据卷)docker compose down

# 停止并删除一切(包括数据卷)——慎用
docker compose down -v

# 重新构建镜像并启动
docker compose up -d --build

# 进入某个服务的容器
docker compose exec backend sh

实战案例:全栈博客系统

假设我们要搭建一个博客系统:React 前端 + Node.js API + MongoDB 数据库 + Nginx 反向代理。

version: "3.8"

services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
    depends_on:
      - frontend
      - api

  frontend:
    build: ./frontend
    expose:
      - "3000"               # 只在内部网络暴露,不映射到宿主机

  api:
    build: ./api
    expose:
      - "4000"
    environment:
      - MONGO_URI=mongodb://mongo:27017/blog
    depends_on:
      - mongo

  mongo:
    image: mongo:7
    volumes:
      - mongo_data:/data/db
    # 不映射端口到宿主机,只允许内部访问——更安全

volumes:
  mongo_data:

这个配置有三个设计要点值得注意:

第一,Nginx 统一入口。 所有外部流量只通过 80 端口进入,由 Nginx 分发到前端或 API,减少暴露面。

第二,expose 代替 ports 前端和 API 使用 expose 仅在 Compose 内部网络可达,外部无法直接访问。

第三,数据库不暴露端口。 MongoDB 没有映射到宿主机,只有同网络的 API 服务能连接,安全性大幅提升。

环境变量管理

硬编码密码在 YAML 里是大忌。推荐使用 .env 文件:

# .env(必须加入 .gitignore)POSTGRES_PASSWORD=my_secure_password
API_SECRET_KEY=a1b2c3d4e5
# docker-compose.yml 中引用
services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}

Compose 会自动读取同目录下的 .env 文件,将变量注入配置中。

常见问题与排坑

Q1:depends_on 设置了,但后端连不上数据库?

depends_on 只保证容器启动顺序,不保证服务就绪。PostgreSQL 容器启动后还需要几秒初始化。解决方案有两种:在应用代码中加入重连机制(推荐),或使用 healthcheck 配合 depends_on.condition

services:
  db:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U admin"]
      interval: 5s
      timeout: 3s
      retries: 5

  backend:
    depends_on:
      db:
        condition: service_healthy

Q2:修改了代码,docker compose up -d 没生效?

Compose 会复用已有镜像。代码变更后需要重新构建:docker compose up -d --build

Q3:数据怎么没了?

如果你用了 docker compose down -v,数据卷会被一起删除。日常停止服务用 docker compose stopdocker compose down(不带 -v)。

Q4:多个项目端口冲突怎么办?

两个项目都映射了 5432:5432 就会冲突。解决方法:修改宿主机端口(如 5433:5432),或者不映射到宿主机——只要同一 Compose 网络内的服务能互相访问就够了。

Compose 与生产环境

Docker Compose 非常适合以下场景:本地开发、CI/CD 测试环境、个人或小团队的单机部署。

但它不适合大规模生产环境。原因很直接:Compose 只能管理单台主机上的容器,没有跨节点调度、自动扩缩容、滚动更新等能力。当你需要管理多台服务器上的容器集群时,应该考虑 Kubernetes 或 Docker Swarm。

一个务实的路径是: 用 Compose 把开发环境跑通,验证架构可行性,再迁移到 K8s 做生产编排。 两者的 YAML 配置思路相通,迁移成本并不高。

小结

Docker Compose 的价值可以用一句话概括: 把 " 一堆容器的启动方式 " 变成 " 一个可版本管理的配置文件 "。

你需要记住的核心操作就三步:写好 docker-compose.yml,执行 docker compose up -d,然后专注于写业务代码。

明天 Day 16,我们聊 Docker 网络模型——理解了网络,你才能真正掌控容器之间的通信。


如果这篇文章对你有帮助,欢迎点赞、在看、转发,这是我持续更新的最大动力。

正文完
创作不易,扫码加点动力
post-qrcode
 0
果较瘦
版权声明:本站原创文章,由 果较瘦 于2026-03-29发表,共计3613字。
转载说明:除特殊说明外本站文章皆由果较瘦原创发布,转载请注明出处。