刚开始用 Docker 的时候,我写了一大串 docker run 命令,参数又多又乱,后来想改个端口或者加个环境变量,得翻半天历史记录。自从换成 Docker Compose 之后,部署和管理容器变得舒服多了。
Docker Compose 的核心思想是把一个应用的多个服务写在一个 YAML 文件里,一条命令就能启动整个应用栈。这篇文章总结我用 Compose 部署过的一些常用服务,给想入门的人做个参考。
为什么用 Docker Compose
相比 docker run,Compose 有几个明显优势:
- 配置集中管理:所有服务的镜像、端口、环境变量、挂载都写在一个文件里。
- 一键启停:
docker-compose up -d启动所有服务,docker-compose down停止。 - 服务自动组网:同一个 compose 项目里的服务自动在同一个网络里,可以通过服务名互相访问。
- 便于迁移:换服务器的时候把
docker-compose.yml和数据目录复制过去就行。
基础写法
一个最简单的 docker-compose.yml 长这样:
1version: '3.8'
2
3services:
4 web:
5 image: nginx:alpine
6 ports:
7 - "80:80"
8 volumes:
9 - ./html:/usr/share/nginx/html
10 restart: unless-stopped
启动:
1docker-compose up -d
-d 表示后台运行。
部署一个静态博客
我的博客前端是 Hugo 生成的静态文件,后端用 Nginx 提供服务。Compose 文件很简单:
1version: '3.8'
2
3services:
4 blog:
5 image: nginx:alpine
6 container_name: blog
7 ports:
8 - "80:80"
9 - "443:443"
10 volumes:
11 - ./public:/usr/share/nginx/html
12 - ./nginx.conf:/etc/nginx/conf.d/default.conf
13 - ./ssl:/etc/nginx/ssl
14 restart: unless-stopped
./public 是 Hugo 构建出来的静态文件目录。每次更新博客后,重新构建并替换这个目录里的文件即可。
部署 WordPress + MySQL
很多老项目还是 WordPress,用 Compose 部署 WordPress 和数据库非常方便:
1version: '3.8'
2
3services:
4 db:
5 image: mysql:8.0
6 container_name: wp_db
7 environment:
8 MYSQL_ROOT_PASSWORD: root_password
9 MYSQL_DATABASE: wordpress
10 MYSQL_USER: wordpress
11 MYSQL_PASSWORD: wordpress_password
12 volumes:
13 - db_data:/var/lib/mysql
14 restart: unless-stopped
15
16 wordpress:
17 image: wordpress:latest
18 container_name: wp_app
19 ports:
20 - "8080:80"
21 environment:
22 WORDPRESS_DB_HOST: db:3306
23 WORDPRESS_DB_USER: wordpress
24 WORDPRESS_DB_PASSWORD: wordpress_password
25 WORDPRESS_DB_NAME: wordpress
26 volumes:
27 - wp_data:/var/www/html
28 depends_on:
29 - db
30 restart: unless-stopped
31
32volumes:
33 db_data:
34 wp_data:
注意 WORDPRESS_DB_HOST 直接写 db:3306,因为 Compose 会自动把服务名解析成 IP。
部署 Uptime Kuma 监控
Uptime Kuma 是个很好用的监控工具,我自己也在用:
1version: '3.8'
2
3services:
4 uptime-kuma:
5 image: louislam/uptime-kuma:1
6 container_name: uptime-kuma
7 ports:
8 - "3001:3001"
9 volumes:
10 - ./data:/app/data
11 restart: unless-stopped
启动后访问 http://服务器IP:3001 进行初始化配置。
部署 Vaultwarden 密码管理器
Vaultwarden 是 Bitwarden 的 Rust 轻量实现,适合个人或小团队自建:
1version: '3.8'
2
3services:
4 vaultwarden:
5 image: vaultwarden/server:latest
6 container_name: vaultwarden
7 environment:
8 WEBSOCKET_ENABLED: "true"
9 SIGNUPS_ALLOWED: "false"
10 volumes:
11 - ./vw-data:/data
12 ports:
13 - "8080:80"
14 restart: unless-stopped
SIGNUPS_ALLOWED: "false" 表示关闭公开注册,只允许管理员手动邀请用户。自建密码管理器一定要注意安全。
部署 Nginx 反向代理
如果一台服务器上跑了多个服务,前面加一个 Nginx 做反向代理是标准做法:
1version: '3.8'
2
3services:
4 nginx:
5 image: nginx:alpine
6 container_name: nginx
7 ports:
8 - "80:80"
9 - "443:443"
10 volumes:
11 - ./nginx.conf:/etc/nginx/nginx.conf
12 - ./ssl:/etc/nginx/ssl
13 restart: unless-stopped
14
15 app1:
16 image: myapp1:latest
17 container_name: app1
18 restart: unless-stopped
19
20 app2:
21 image: myapp2:latest
22 container_name: app2
23 restart: unless-stopped
对应的 nginx.conf 里可以用服务名做 upstream:
1server {
2 listen 80;
3 server_name app1.example.com;
4
5 location / {
6 proxy_pass http://app1:8080;
7 }
8}
9
10server {
11 listen 80;
12 server_name app2.example.com;
13
14 location / {
15 proxy_pass http://app2:8080;
16 }
17}
几个使用技巧
1. 使用 .env 文件管理敏感信息
不要把密码直接写在 docker-compose.yml 里,可以用 .env 文件:
1MYSQL_ROOT_PASSWORD=your_password
然后在 compose 文件里引用:
1environment:
2 MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
2. 合理设置 restart 策略
一般服务用 unless-stopped,表示除非手动停止,否则 always 重启。测试环境可以用 no。
3. 限制容器资源
生产环境建议限制 CPU 和内存,防止某个容器把资源吃光:
1deploy:
2 resources:
3 limits:
4 cpus: '0.5'
5 memory: 512M
6 reservations:
7 cpus: '0.25'
8 memory: 256M
4. 使用 networks 隔离不同项目
如果一台服务器上跑了多个项目,最好给每个项目单独的网络,避免服务名冲突:
1networks:
2 project_a:
3 driver: bridge
常用命令
1# 启动所有服务(后台)
2docker-compose up -d
3
4# 查看日志
5docker-compose logs -f
6
7# 重启某个服务
8docker-compose restart 服务名
9
10# 停止并删除容器
11docker-compose down
12
13# 停止并删除容器和数据卷(慎用)
14docker-compose down -v
15
16# 拉取最新镜像
17docker-compose pull
18
19# 重新构建
20docker-compose up -d --build
总结
Docker Compose 是我目前最喜欢的小型项目部署方式。它不像 Kubernetes 那么重,又比纯 docker run 好管理得多。
这篇文章给的几个模板都是我自己实际在用的,你可以根据需求改一改端口、路径和密码就能跑起来。如果刚开始接触 Docker,建议先从一个简单的静态博客或者 Uptime Kuma 入手,熟练之后再挑战多服务组合。