docker stack 是 swarm 模式下用于生产部署的机制,需启用 swarm、使用 v3.4+ compose 文件、禁用 build、显式配置 network/volume/deploy/healthcheck,通过 docker stack deploy 一键部署并支持滚动更新与回滚。

Docker Stack 是 Docker Swarm 模式下专为生产环境设计的部署机制,它直接复用(或稍作改造)docker-compose.yml 文件,但要求配置更严谨、语义更明确。与开发阶段常用的 docker-compose up 不同,stack deploy 面向集群、强调稳定性、可扩展性和运维可控性。要实现真正“一键式”的全栈应用生产部署,关键不在写得快,而在写得准——尤其是 network、volume、deploy 和 healthcheck 这四类配置必须到位。
确认环境已进入 Swarm 模式
Stack 只能在启用 Swarm 的节点上运行。单机环境也需初始化 Swarm:
- 执行 docker swarm init 启动本地 Swarm(输出中会给出 join token,集群部署时备用)
- 验证:运行 docker node ls 应看到当前节点状态为 Ready 且角色为 Leader
- 注意:Docker Stack 不支持
build指令,所有镜像必须提前构建并推送到私有或公共仓库(如docker build -t my-registry.com/web:prod . && docker push my-registry.com/web:prod)
编写符合 Stack 要求的 docker-compose.yml
版本至少为 3.4,推荐使用 3.8 或 3.9;移除开发专用字段(build、volumes 中的源码挂载、container_name 等),补全生产必需项:
-
networks:显式定义 overlay 网络,服务间通信依赖它
networks:<br> app-net:<br> driver: overlay<br> attachable: true
-
volumes:声明命名卷,用于持久化数据库、日志等
volumes:<br> db_data:<br> driver: local
-
deploy:控制副本数、更新策略、资源限制和放置约束
deploy:<br> replicas: 3<br> update_config:<br> parallelism: 1<br> delay: 10s<br> resources:<br> limits:<br> cpus: '0.5'<br> memory: 512M<br> placement:<br> constraints:<br> - node.role == worker
-
healthcheck:每个核心服务都应配置,Swarm 依赖它做自动故障转移
healthcheck:<br> test: ["CMD", "curl", "-f", "http://localhost:3000/health"]<br> interval: 30s<br> timeout: 10s<br> retries: 3<br> start_period: 40s
一键部署与日常运维命令
文件就绪后,只需一条命令即可拉起整个栈(假设文件名为 prod-stack.yml):
-
部署:
docker stack deploy -c prod-stack.yml myapp(myapp是栈名,将作为服务前缀) -
查看状态:
docker stack services myapp查服务列表,docker service ps myapp_web查某服务实例详情 -
滚动更新:修改镜像标签后再次执行
docker stack deploy,Swarm 自动按update_config执行灰度发布 -
回滚:
docker service update --rollback myapp_web -
清理:
docker stack rm myapp(注意:命名卷默认保留,需手动docker volume rm)
典型全栈 YAML 片段(Laravel + Nginx + MySQL + Redis)
以下为精简可运行的核心结构,省略了具体构建细节,聚焦 Stack 生产语法:
version: '3.8'
services:
web:
image: my-registry.com/laravel-nginx:prod
ports: - "80:80"
networks: [app-net]
deploy:
replicas: 2
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost/"]
interval: 30s
depends_on: [app, redis]
<p>app:
image: my-registry.com/laravel-app:prod
networks: [app-net]
environment:</p>
- DB_HOST=db
- REDIS_HOST=redis deploy: replicas: 3 resources: limits: {memory: 1G, cpus: '1.0'}
db: image: mysql:8.0 environment: {MYSQL_ROOT_PASSWORD: "secure123"} volumes: [db_data:/var/lib/mysql] networks: [app-net] deploy: placement: constraints: [node.labels.db == true]
redis: image: redis:7-alpine networks: [app-net] deploy: replicas: 1
networks: app-net: driver: overlay
volumes: db_data:











