全栈工程师:运维篇(二):docker-compose 理解

10 阅读2分钟

# 简说

docker 非常需要实践,核心重点围绕以下三座大山,掌握后可快速上手:

  1. 构建时和运行时
  2. 变量优先级
  3. 网络(默认桥接模式)

有疑问可咨询 docker官方ai

# docker Compose 文件详解

docker启动时需指定大量参数(如 -e/-env_file指定环境变量、-v指定数据卷、-p指定端口等),命令冗长繁琐。Compose可将所有参数整合到一个配置文件中,实现一键启动,方便分享和部署。

## 示例

services: #固定写法 服务
  nest-admin-server: # 服务名称
    # 指定镜像(下载后运行);若指定--build,则直接构建后运行
    images: 1960825664/hello:latest  # 用户名/镜像名:标签名
    build: .    #在当前目录寻找dockerfile进行构建,"." 为当前目录
    #两者二选一
    #build:  
    #  context: .
    #  dockerfile: apps/web/DockerFile  # 明确指定文件名,多用于monorepo
    #  args:
          - NODE_ENV=${NODE_ENV} #使用${NODE_ENV},NODE_ENV可以来自env_file或者environment.
    container_name: nest-admin-server  #容器名称
    pull_policy: always  # 无论本地是否有镜像,均重新下载
    restart: always    #容器异常时自动重启
    command: [ "pm2-runtime", "ecosystem.config.js" ] # 容器开机运行命令,可与Dockerfile的entry结合使用
    env_file:  #指定运行时环境变量文件(仅作用于Compose,不用于构建阶段)
      - .env
      - .env.production
    environment:   # 运行时优先级大于上面
      - NODE_ENV=${NODE_ENV}
      
    ports:
      - '${APP_PORT}:${APP_PORT}' # 宿主机端口:容器端口,变量来自env_file
    volumes:  # 数据持久化,将宿主机db_data映射到容器指定路径
      - db_data:/var/lib/postgresql/data
    networks:
      - nest_admin_net  #指定服务所属网络,同网络服务可通过服务名互相访问

networks: #创建网络(可理解为路由器)
  nest_admin_net:
    name: nest_admin_net
    driver: bridge  #桥接模式,不懂可参考技术蛋老师的网络协议讲解
volumes:
  db_data:

# docker Compose 命令表

# 一、核心生命周期管理
# 启动Compose服务(后台运行,推荐)
docker compose up -d
# 注释: -d 后台运行,默认读取当前目录docker-compose.yml

# 启动指定Compose文件的服务(后台运行)
docker compose -f docker-compose.prod.yml up -d
# 注释: -f 指定配置文件,适配开发/生产多环境

# 停止Compose服务(保留容器、网络等资源)
docker compose stop
# 注释: 仅停止服务,可通过start重启

# 停止并删除容器、网络(保留数据卷)
docker compose down
# 注释: 适合临时测试后清理,不丢失持久化数据

# 停止并删除所有资源(含数据卷)
docker compose down -v
# 注释: -v 删除数据卷,谨慎使用(会丢失数据)

# 重启所有运行中的Compose服务
docker compose restart
# 注释: 未启动的服务不会主动启动

# 重启指定Compose服务
docker compose restart nest-admin-server
# 注释: 仅重启指定名称的服务

# 二、Compose 配置检查与调试
# 查看解析环境变量后的配置详情
docker compose config
# 注释: 验证配置语法,显示完整解析结果

# 查看指定环境文件的配置详情
docker compose --env-file .env.prod config
# 注释: 查看指定环境下的实际生效配置

# 实时跟踪所有服务日志
docker compose logs -f
# 注释: 可加服务名查看单个服务日志(如 docker compose logs -f nest-admin-server)

# 实时跟踪指定服务日志
docker compose logs -f nest-admin-server
# 注释: 便于定位单个服务问题

# 三、Compose 镜像与构建相关
# 构建Compose文件中定义的镜像(需配置build字段)
docker compose build
# 注释: 镜像已存在则不重新构建

# 强制构建镜像(忽略缓存)
docker compose build --no-cache
# 注释: 依赖更新后适用,重新构建所有镜像

# 拉取Compose文件中指定的镜像(需配置image字段)
docker compose pull
# 注释: 本地已有镜像则更新至最新版本

# 拉取指定服务的镜像
docker compose pull nest-admin-server
# 注释: 不影响其他服务

# 四、Compose 服务管理
# 查看所有Compose服务状态
docker compose ps
# 注释: 显示容器ID、名称、状态、端口映射等信息

# 进入指定服务容器(交互模式)
docker compose exec -it nest-admin-server /bin/bash
# 注释: -it 开启交互,nest-admin-server为服务名

# 在指定服务容器内执行单次命令(无需进入)
docker compose exec nest-admin-server ls /app
# 注释: 执行完自动退出

# 查看指定服务详细信息
docker compose inspect nest-admin-server
# 注释: 查看容器、网络、挂载等全部信息

# 五、Compose 其他常用命令
# 查看Compose版本
docker compose version
# 注释: 确认版本与配置文件兼容性

# 静默验证配置文件语法
docker compose config -q
# 注释: 无错误则无输出,有错误显示异常信息

# 暂停所有Compose服务
docker compose pause
# 注释: 暂停容器运行,恢复用unpause命令

# 恢复暂停的Compose服务
docker compose unpause
# 注释: 恢复容器正常运行

# docker compose 调试检查

# 查看项目根目录默认env_file(.env)的配置详情
docker compose config  
# 查看指定环境文件(.env.prod)的实际生效环境变量
docker compose --env-file .env.prod config

# 核心难点:build.args、env_file与environment的关系

三者核心区别在于作用阶段不同,变量不会自动流转,需手动显式传递,具体如下:

  • build.args(构建参数) :仅作用于镜像构建阶段,需通过 Dockerfile 的 ARG 指令声明,可通过 docker build --build-arg 传递。不会自动出现在镜像/容器中,除非用 ENV 显式传递。
  • env_file(文件变量) :仅作用于容器运行阶段,通过 Compose 的 env_file 字段加载,注入容器环境,等同于 environment。
  • environment(环境变量) :作用于构建和运行两个阶段,可通过 Dockerfile 的 ENV 指令、docker run 或 Compose 的 environment 字段设置,会持久化到镜像和容器。

关键注意点

  1. ARG 不能直接使用 environment 或 env_file 里的变量,需通过 --build-arg 显式传递(如:export MY_VAR=value && docker build --build-arg MY_VAR .)。
  2. Compose 中,environment/env_file 的变量不会自动传递给 build.args,需在 Compose 文件中手动引用(如:args: {MY_ARG: ${MY_ENV_VAR}})。

# 注意事项

  • docker compose 会默认读取同级目录下的 .env 文件。
  • 环境变量优先级(从高到低):docker run -e > compose environment> env_file > Dockerfile ENV
  • bridge 是默认网络驱动,无需显式声明;默认 bridge 网络允许容器间通信,并通过 NAT 访问外网。

# 总结:

  1. 环境变量优先级:Dockerfile ENV < env_file < compose environment < docker run -e
  2. 核心区分:构建时(Dockerfile、build.args)、运行时(Compose、env_file、environment),变量需手动显式传递。
  3. Dockerfile 中,ARG 用于构建时固定变量,ENV 用于运行时可修改变量;Compose 中,build.args 与 environment/env_file 互不自动继承。