用 Docker Compose 搭一套可维护的个人云服务
用 Docker Compose 搭一套可维护的个人云服务
July 10, 2026
一个人维护几台服务,最怕三个月后看不懂当时怎么装的。Compose 的价值是把「怎么跑」写成文件。
1. 目录约定
~/stack/
docker-compose.yml
.env # 不进 git
Caddyfile 或 nginx/ # 入口配置
data/
postgres/
redis/
backups/2. 可运行骨架(示意)
# docker-compose.yml
services:
api:
image: your/api:latest
env_file: .env
environment:
DATABASE_URL: postgres://app:${POSTGRES_PASSWORD}@db:5432/app
REDIS_URL: redis://redis:6379/0
depends_on:
db:
condition: service_healthy
redis:
condition: service_healthy
ports:
- "127.0.0.1:3090:8080" # 只给本机 Nginx
restart: unless-stopped
logging:
driver: json-file
options:
max-size: "10m"
max-file: "3"
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: app
volumes:
- ./data/postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U app -d app"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
redis:
image: redis:7-alpine
command: ["redis-server", "--save", "60", "1", "--loglevel", "warning"]
volumes:
- ./data/redis:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
restart: unless-stopped.env:
POSTGRES_PASSWORD=change-me-long-random启动:
docker compose up -d
docker compose ps
curl -fsS http://127.0.0.1:3090/healthz3. 备份:先写清「丢了会哭的三样」
#!/usr/bin/env bash
# backup.sh
set -euo pipefail
ROOT="$HOME/stack"
DAY=$(date +%F)
OUT="$ROOT/backups/$DAY"
mkdir -p "$OUT"
docker compose -f "$ROOT/docker-compose.yml" exec -T db \
pg_dump -U app app | gzip > "$OUT/app.sql.gz"
tar -C "$ROOT" -czf "$OUT/redis.tgz" data/redis
cp "$ROOT/docker-compose.yml" "$OUT/"
cp "$ROOT/.env" "$OUT/env.gpg.ready" # 建议再 gpg 加密后外传
echo "backup done: $OUT"cron:
15 3 * * * /home/ubuntu/stack/backup.sh >> /var/log/stack-backup.log 2>&14. 升级姿势
docker compose pull api
docker compose up -d --no-deps api
docker compose logs -f --tail=200 api
# 不行就回滚镜像 tag有状态组件(Postgres)升级前先备份;别在磁盘 90% 时做大版本迁移。
5. 案例:sub2api 一类「API + DB + Redis」
与现网类似的组合:
app:业务postgres/redis:有状态- 宿主机 Nginx:子域反代到
127.0.0.1:3090
健康检查让依赖就绪后再接流量;日志轮转避免 Docker json-file 吃满 40G 盘。个人云不需要 K8s,需要的是可描述、可备份、可回滚。
6. 清单
- 公网端口只留 80/443
- 业务端口绑
127.0.0.1 - 健康检查 +
restart - 日志
max-size - 备份脚本与恢复演练(至少成功恢复过一次)
- 密钥不进 git
主站静态内容(Hugo)可继续独立发布;动态服务进 Compose——两边互不拖累。