【docker】--4.Docker Compose

张开发
2026/5/13 17:20:42 15 分钟阅读

分享文章

【docker】--4.Docker Compose
目录1.Docker Compose 简介2.Docker Compose 安装LinuxmacOSwindows PC3.Docker Compose 使用3.1.准备3.2.创建 Dockerfile 文件3.3.创建 docker-compose.yml3.4.使用 Compose 命令构建应用4.Docker Compose 指令4.1.顶级结构Top-level Keys4.2.services 下常用指令详解 1. 镜像与构建 2. 网络与通信 3. 存储与挂载⚙️ 4. 运行控制 5. 环境与安全 6. 依赖与编排 7. 部署Swarm 模式专用 8. 日志与监控 9. 敏感数据Secrets1.Docker Compose 简介Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose您可以使用 YML 文件来配置应用程序需要的所有服务。然后使用一个命令就可以从 YML 文件配置中创建并启动所有服务。Compose 使用的三个步骤:使用 Dockerfile 定义应用程序的环境。使用 docker-compose.yml 定义构成应用程序的服务这样它们可以在隔离环境中一起运行。最后执行 docker-compose up 命令来启动并运行整个应用程序。docker-compose.yml 的配置案例如下配置参数参考下文:# 这是一个 Docker Compose 的 yaml 配置文件示例 version: 3 # 定义版本这里使用的是 3 版本的格式适用于 Docker Compose services: # 定义服务集合 web: # 定义名为 web 的服务 build: . # 指定构建上下文为当前目录下的 Dockerfile ports: # 映射端口将主机的 5000 端口映射到容器的 5000 端口 - 5000:5000 volumes: # 挂载卷使主机上的目录与容器内的目录同步 - .:/code # 将当前目录挂载到容器的 /code 路径下 - logvolume01:/var/log # 挂载一个名为 logvolume01 的数据卷到容器的 /var/log 目录 links: # 链接到另一个服务redis便于服务间通信 - redis # 表示 web 服务将会链接到 redis 服务 redis: # 定义名为 redis 的服务 image: redis # 使用 Docker Hub 上官方的 redis 镜像 volumes: # 定义在顶层的数据卷可以在多个服务之间共享或重用 logvolume01: {} # 声明一个名为 logvolume01 的数据卷{} 表示使用默认设置2.Docker Compose 安装LinuxLinux 上我们可以从 Github 上下载它的二进制包来使用最新发行的版本地址:https://github.com/docker/compose/releases。运行以下命令以下载 Docker Compose 的当前稳定版本:$ sudo curl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose要安装其他版本的 Compose请替换 1.24.1。将可执行权限应用于二进制文件:$ sudo chmod x /usr/local/bin/docker-compose创建软链:$ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose测试是否安装成功:$ docker-compose --version cker-compose version 1.24.1, build 4667896b注意: 对于 alpine需要以下依赖包: py-pippython-devlibffi-devopenssl-devgcclibc-dev和 make。macOSMac 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序因此 Mac 用户不需要单独安装 Compose。Docker 安装说明可以参阅 MacOS Docker 安装。windows PCWindows 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序因此 Windows 用户不需要单独安装 Compose。Docker 安装说明可以参阅 Windows Docker 安装。3.Docker Compose 使用3.1.准备$ mkdir composetest $ cd composetest在测试目录中创建一个名为 app.py 的文件并复制粘贴以下内容:composetest/app.py 文件代码# 导入所需模块 import time # 用于实现重试时的延时 import redis # 用于连接和操作 Redis 缓存数据库 from flask import Flask # Flask Web 框架 # 创建 Flask 应用实例 app Flask(__name__) # 连接到 Redis 服务器假设 Redis 容器名为 redis端口为默认 6379 cache redis.Redis(hostredis, port6379) def get_hit_count(): 尝试从 Redis 中获取并递增访问计数最多重试 5 次 retries 5 # 最大重试次数 while True: try: # 使用 Redis 的 incr 命令对 hits 键进行原子自增并返回当前值 return cache.incr(hits) except redis.exceptions.ConnectionError as exc: # 如果连接失败且重试次数已用完则抛出异常 if retries 0: raise exc # 否则减少重试次数等待 0.5 秒后重试 retries - 1 time.sleep(0.5) # 定义根路径的路由 app.route(/) def hello(): 处理首页请求返回包含访问次数的欢迎信息 count get_hit_count() # 获取当前访问次数 return Hello World! I have been seen {} times.\n.format(count)在此示例中redis 是应用程序网络上的 redis 容器的主机名该主机使用的端口为 6379。在 composetest 目录中创建另一个名为 requirements.txt 的文件内容如下:flask redis3.2.创建 Dockerfile 文件在 composetest 目录中创建一个名为的文件 Dockerfile内容如下:# 使用轻量级的 Python 3.7 Alpine 镜像作为基础 FROM python:3.7-alpine # 设置工作目录为 /code WORKDIR /code # 设置环境变量指定 Flask 入口文件 ENV FLASK_APP app.py # 设置环境变量允许容器外部访问0.0.0.0 代表所有网络接口 ENV FLASK_RUN_HOST 0.0.0.0 # 安装系统级依赖编译器和头文件用于编译 Python 包中的 C 代码--no-cache 避免缓存占用空间 RUN apk add --no-cache gcc musl-dev linux-headers # 将本地的 requirements.txt 复制到容器中利用 Docker 缓存机制只有当文件变化时才重新安装依赖 COPY requirements.txt requirements.txt # 安装 Python 依赖包 RUN pip install -r requirements.txt # 将当前目录下的所有文件复制到容器的 /code 目录 COPY . . # 容器启动时运行的命令使用 Flask 自带的开发服务器 CMD [flask, run]3.3.创建 docker-compose.yml在测试目录中创建一个名为 docker-compose.yml 的文件然后粘贴以下内容:# yaml 配置 version: 3 services: web: build: . ports: - 5000:5000 redis: image: redis:alpine该 Compose 文件定义了两个服务:web 和 redis。web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。3.4.使用 Compose 命令构建应用在测试目录中执行以下命令来启动应用程序:docker-compose up如果你想在后台执行该服务可以加上 -d 参数:docker-compose up -d4.Docker Compose 指令顶级命令services: # 必填定义所有服务容器 volumes: # 可选声明命名卷named volumes networks: # 可选声明自定义网络4.1.version指定本 yml 依从的 compose 哪个版本制定的。⚠️ 注意从Docker Compose v2.0开始version字段已被弃用你之前看到的警告就是这个原因可安全删除。4.2.services指令是整个 Compose 配置的核心部分用于定义应用所依赖的各个服务容器如 Web 应用、数据库、缓存等。每个服务对应一个 Docker 容器。也就是依赖镜像4.1.顶级结构Top-level Keys指令必填说明services✅ 是定义所有服务每个服务对应一个容器volumes否声明命名卷named volumesnetworks否声明自定义网络secrets否声明敏感数据v3.1configs否声明配置文件Swarm 模式4.2.services下常用指令详解 1. 镜像与构建指令类型示例说明imagestringimage: redis:alpine使用现有镜像可带 tag 或 digestbuildstring / objectbuild: ./dirbuild:nbsp;nbsp;context: ./appnbsp;nbsp;dockerfile: Dockerfile.prodnbsp;nbsp;args: { buildno: 1 }nbsp;nbsp;target: prodnbsp;nbsp;labels: [keyvalue]构建上下文-context: 构建目录-dockerfile: 指定 Dockerfile 名-args: 构建参数仅构建时可用-target: 多阶段构建目标-labels: 给镜像打标签✅image与build通常二选一。 2. 网络与通信指令示例说明ports- 8080:80- 5000映射宿主机 ↔ 容器端口格式[host:]container[/protocol]exposeexpose: [6379]仅暴露端口给其他服务不映射到宿主机networksnetworks: [frontend, backend]加入指定网络需在顶层定义支持别名some-net: { aliases: [web1, app] }extra_hosts- host1:192.168.1.10添加/etc/hosts条目类似--add-hostdnsdns: 8.8.8.8dns: [8.8.8.8, 1.1.1.1]自定义 DNS 服务器dns_searchdns_search: example.com自定义 DNS 搜索域network_modenetwork_mode: hostnetwork_mode: nonenetwork_mode: service:db覆盖默认网络模式慎用 3. 存储与挂载指令示例说明volumes- ./data:/var/lib/redis绑定挂载- db_vol:/var/lib/mysql命名卷挂载主机目录或命名卷tmpfstmpfs: /tmptmpfs: [/run, /tmp]挂载临时内存文件系统devices- /dev/ttyUSB0:/dev/ttyUSB0映射设备到容器volumes: - backend_picture_data:/app/app/data/picture - backend_seg_results:/app/segmentation_results - ./models:/models:robackend_seg_results:/app/segmentation_results同理这是将容器内的/app/segmentation_results目录可能存放 SAM 模型生成的分割结果挂载到另一个命名卷backend_seg_results。数据同样会被持久化重启服务不会丢失。./models:/models:ro左边./models是相对于当前docker-compose.yml文件所在目录的一个宿主机路径即项目中的models/文件夹。右边/models是容器内的目标路径。:ro表示read-only只读容器可以读取该目录下的文件但不能修改或写入。作用将宿主机上的模型文件如sam_vit_l_0b3195.pth只读地共享给容器使用。这样你可以在宿主机上管理模型文件下载、替换等而容器始终使用最新版本且无法意外修改模型。左侧形式类型是否持久化谁管理./xxx、/xxx、~/xxxBind Mount绑定挂载是存在你指定的位置你用户xxx纯名字无/Named Volume命名卷是存在 Docker 管理区Docker⚙️ 4. 运行控制指令示例说明commandcommand: [python, app.py]覆盖容器启动命令entrypointentrypoint: /code/init.sh覆盖入口点ENTRYPOINTcontainer_namecontainer_name: my-web指定容器名称默认为project_service_indexrestartrestart: unless-stopped重启策略no默认alwayson-failureunless-stoppedstop_signalstop_signal: SIGUSR1自定义停止信号默认SIGTERMstop_grace_periodstop_grace_period: 30s发送SIGKILL前等待时间默认 10shealthcheckhealthcheck:nbsp;nbsp;test: [CMD, curl, -f, http://localhost]nbsp;nbsp;interval: 30snbsp;nbsp;timeout: 10snbsp;nbsp;retries: 3nbsp;nbsp;start_period: 40s健康检查配置 5. 环境与安全指令示例说明environmentenvironment:nbsp;nbsp;RACK_ENV: developmentnbsp;nbsp;SHOW: true设置环境变量布尔值需加引号env_fileenv_file: .envenv_file: [common.env, web.env]从文件加载环境变量cap_add/cap_dropcap_add: [ALL]cap_drop: [SYS_PTRACE]添加/删除 Linux 内核能力security_optsecurity_opt: [label:type:unconfined_t]修改 SELinux/AppArmor 标签sysctlssysctls: { net.core.somaxconn: 1024 }设置内核参数ulimitsulimits:nbsp;nbsp;nofile: { soft: 20000, hard: 40000 }nbsp;nbsp;nproc: 65535覆盖资源限制cgroup_parentcgroup_parent: m-executor-abcd指定父 cgroup继承资源限制 6. 依赖与编排指令示例说明depends_ondepends_on: [db, redis]控制启动/停止顺序⚠️不等待服务就绪仅控制容器创建顺序✅ 若需“等待服务可用”请在应用中实现重试逻辑或使用wait-for-it.sh、dockerize等工具。 7. 部署Swarm 模式专用仅在docker stack deploy时生效docker-compose up会忽略表格指令示例说明deploydeploy:nbsp;nbsp;mode: replicatednbsp;nbsp;replicas: 3nbsp;nbsp;resources:nbsp;nbsp;nbsp;nbsp;limits: { cpus: 0.5, memory: 50M }nbsp;nbsp;restart_policy: { condition: on-failure, delay: 5s }nbsp;nbsp;update_config: { parallelism: 2, delay: 10s }集群部署配置-mode:replicated/global-replicas: 副本数-resources: 资源限制-restart_policy: 重启策略-update_config: 滚动更新策略-rollback_config: 回滚策略 8. 日志与监控指令示例说明logginglogging:nbsp;nbsp;driver: json-filenbsp;nbsp;options:nbsp;nbsp;nbsp;nbsp;max-size: 200knbsp;nbsp;nbsp;nbsp;max-file: 10日志驱动配置支持json-file,syslog,none可限制日志大小和数量 9. 敏感数据Secrets指令示例说明secretssecrets: [my_secret]顶层secrets:nbsp;nbsp;my_secret: { file: ./secret.txt }安全传递密码、密钥等容器内路径/run/secrets/name5.docker问题5.1.更新了容器代码之后如何重构镜像1.确认容器名称或 ID你已经知道容器名是deploy-backend-1从你的命令看出。2.提交容器为新镜像docker commit deploy-backend-1 my-backend:updateddeploy-backend-1当前容器名my-backend:updated新镜像名和标签可自定义如backend:v2✅ 这会把容器当前的整个文件系统状态包括你cp进去的GWO20250630m.py、修改的db.py等打包成一个新镜像。3.让 docker-compose 使用这个新镜像修改你的docker-compose.yml不再从源码构建而是直接使用新镜像1backend: 2 # 注释掉 build 部分 3 # build: 4 # context: ../backend 5 # dockerfile: Dockerfile 6 7 # 改为 image 8 image: my-backend:updated 9 restart: unless-stopped 10 # ... 其他配置保持不变4.重新创建服务1docker-compose up -d backend现在即使你删除旧容器新启动的容器也会包含你的修改。5.2.我现在在本地构建好了我的项目镜像上传到服务器上面部署并且服务器上面有我的全部项目代码服务器构建镜像过程中拉去前后端包失败无法访问包的网络那我可以通过修改服务器代码直接重构我的镜像吗我的意思是修改服务器上的代码之后可不可以直接使用已有的镜像为基础重构代码这样就不用重新安装环境了✅ 推荐方案基于已有镜像 本地代码构建新镜像无需联网你不需要重新安装环境因为基础镜像已经包含了所有依赖。你只需要写一个简单的Dockerfile把服务器上的新代码 COPY 进去构建新镜像 ——全程不联网 具体操作步骤在服务器上执行1.确保服务器上有最新代码假设你的后端代码在1/home/user/project/backend/2.创建一个轻量级Dockerfile.update# 使用你已有的、包含完整环境的镜像作为基础 FROM my-backend:latest # ← 替换成你实际的镜像名 # 删除旧代码可选如果路径会冲突 RUN rm -rf /app/app/* # 复制服务器上的新代码进去 COPY ./backend/ /app/app/ # 设置工作目录根据你原来的配置 WORKDIR /app/app # 如果需要可以指定启动命令通常继承自原镜像可省略 # CMD [uvicorn, main:app, --host, 0.0.0.0, --port, 8000] 这个 Dockerfile只做一件事用新代码覆盖旧代码其他一切Python、torch、系统库都复用原镜像。3.构建新镜像不联网cd /home/user/project # 构建时指定新 Dockerfile docker build \ -t my-backend:updated \ -f Dockerfile.update \ .✅ 因为所有依赖已在my-backend:latest中这一步不会下载任何包秒级完成4.更新 docker-compose.yml如果需要如果你的docker-compose.yml原来是用build现在可以改为用新镜像backend: image: my-backend:updated # ← 使用新镜像 # 注释掉 build 部分避免服务器尝试重新构建完整环境 # build: ... restart: unless-stopped # ... 其他配置不变5.重启服务docker-compose up -d backend

更多文章