跳至内容
用 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/healthz

3. 备份:先写清「丢了会哭的三样」

#!/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>&1

4. 升级姿势

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——两边互不拖累。