feat(docker): PostgreSQL 每日自动备份
- 新增 backup.sh: pg_dump + gzip,自动清理过期备份 - production compose 添加 backup 服务: cron 每日 02:00 执行 - 可通过 BACKUP_CRON / BACKUP_KEEP_DAYS 环境变量自定义
This commit is contained in:
43
docker/backup.sh
Normal file
43
docker/backup.sh
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# PostgreSQL 自动备份脚本
|
||||||
|
# 用法:
|
||||||
|
# 手动: ./docker/backup.sh
|
||||||
|
# 自动: 由 docker compose backup 服务每日 02:00 执行
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BACKUP_DIR="${BACKUP_DIR:-/backups}"
|
||||||
|
PG_HOST="${PGHOST:-postgres}"
|
||||||
|
PG_PORT="${PGPORT:-5432}"
|
||||||
|
PG_USER="${PGUSER:-erp}"
|
||||||
|
PG_DB="${PGDATABSE:-erp}"
|
||||||
|
KEEP_DAYS="${KEEP_DAYS:-7}"
|
||||||
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
||||||
|
FILENAME="${PG_DB}_${TIMESTAMP}.sql.gz"
|
||||||
|
FILEPATH="${BACKUP_DIR}/${FILENAME}"
|
||||||
|
|
||||||
|
mkdir -p "${BACKUP_DIR}"
|
||||||
|
|
||||||
|
echo "[$(date -Iseconds)] 开始备份 ${PG_DB} → ${FILEPATH}"
|
||||||
|
|
||||||
|
if pg_dump \
|
||||||
|
-h "${PG_HOST}" \
|
||||||
|
-p "${PG_PORT}" \
|
||||||
|
-U "${PG_USER}" \
|
||||||
|
-d "${PG_DB}" \
|
||||||
|
--format=plain \
|
||||||
|
--no-owner \
|
||||||
|
--no-privileges \
|
||||||
|
| gzip > "${FILEPATH}"; then
|
||||||
|
SIZE=$(du -h "${FILEPATH}" | cut -f1)
|
||||||
|
echo "[$(date -Iseconds)] 备份完成: ${FILENAME} (${SIZE})"
|
||||||
|
else
|
||||||
|
echo "[$(date -Iseconds)] 备份失败!" >&2
|
||||||
|
rm -f "${FILEPATH}"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 清理过期备份
|
||||||
|
DELETED=$(find "${BACKUP_DIR}" -name "${PG_DB}_*.sql.gz" -mtime +${KEEP_DAYS} -delete -print | wc -l)
|
||||||
|
if [ "${DELETED}" -gt 0 ]; then
|
||||||
|
echo "[$(date -Iseconds)] 已清理 ${DELETED} 个过期备份(>${KEEP_DAYS}天)"
|
||||||
|
fi
|
||||||
79
docker/docker-compose.production.yml
Normal file
79
docker/docker-compose.production.yml
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
# 生产环境 Docker Compose 配置
|
||||||
|
# 使用方式: docker compose -f docker/docker-compose.yml -f docker/docker-compose.production.yml up -d
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: ..
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: hms-server
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${APP_PORT:-3000}:3000"
|
||||||
|
- "${METRICS_PORT:-9090}:9090"
|
||||||
|
env_file:
|
||||||
|
- .env.production
|
||||||
|
environment:
|
||||||
|
ERP__DATABASE__URL: postgres://${POSTGRES_USER:-erp}:${POSTGRES_PASSWORD}@postgres:${POSTGRES_PORT:-5432}/${POSTGRES_DB:-erp}
|
||||||
|
ERP__REDIS__URL: redis://:${REDIS_PASSWORD}@redis:${REDIS_PORT:-6379}
|
||||||
|
volumes:
|
||||||
|
- app-uploads:/app/uploads
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:3000/api/v1/health"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 5s
|
||||||
|
start_period: 60s
|
||||||
|
retries: 3
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: "2"
|
||||||
|
memory: 1024M
|
||||||
|
reservations:
|
||||||
|
cpus: "0.5"
|
||||||
|
memory: 256M
|
||||||
|
networks:
|
||||||
|
- hms-internal
|
||||||
|
|
||||||
|
# 每日自动备份 — 每天凌晨 02:00 执行 pg_dump,保留 7 天
|
||||||
|
# 手动触发: docker compose -f docker/docker-compose.yml -f docker/docker-compose.production.yml run --rm backup
|
||||||
|
backup:
|
||||||
|
image: postgres:16-alpine
|
||||||
|
container_name: hms-backup
|
||||||
|
restart: unless-stopped
|
||||||
|
entrypoint: >
|
||||||
|
sh -c "
|
||||||
|
echo '$$BACKUP_CRON /usr/local/bin/backup.sh' > /etc/crontabs/root &&
|
||||||
|
crond -f -l 2
|
||||||
|
"
|
||||||
|
environment:
|
||||||
|
PGHOST: postgres
|
||||||
|
PGPORT: "${POSTGRES_PORT:-5432}"
|
||||||
|
PGUSER: "${POSTGRES_USER:-erp}"
|
||||||
|
PGDATABASE: "${POSTGRES_DB:-erp}"
|
||||||
|
BACKUP_DIR: /backups
|
||||||
|
KEEP_DAYS: "${BACKUP_KEEP_DAYS:-7}"
|
||||||
|
BACKUP_CRON: "${BACKUP_CRON:-0 2 * * *}"
|
||||||
|
volumes:
|
||||||
|
- ./backup.sh:/usr/local/bin/backup.sh:ro
|
||||||
|
- backup_data:/backups
|
||||||
|
depends_on:
|
||||||
|
postgres:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- hms-internal
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
app-uploads:
|
||||||
|
driver: local
|
||||||
|
backup_data:
|
||||||
|
driver: local
|
||||||
|
|
||||||
|
networks:
|
||||||
|
hms-internal:
|
||||||
|
driver: bridge
|
||||||
Reference in New Issue
Block a user