ops: keep production imports local and backups non-root
This commit is contained in:
parent
ae31f2e567
commit
0595dbfd86
|
|
@ -19,5 +19,8 @@ TEST_MODE=false
|
||||||
POSTGRES_DB=cents
|
POSTGRES_DB=cents
|
||||||
POSTGRES_USER=cents
|
POSTGRES_USER=cents
|
||||||
POSTGRES_PASSWORD=change-me
|
POSTGRES_PASSWORD=change-me
|
||||||
|
# Host uid/gid used by the backup container when writing ./backups/db.
|
||||||
|
BACKUP_UID=1001
|
||||||
|
BACKUP_GID=1001
|
||||||
APP_TIME_ZONE=Asia/Shanghai
|
APP_TIME_ZONE=Asia/Shanghai
|
||||||
EXCHANGE_RATE_API_URL=https://api.frankfurter.dev
|
EXCHANGE_RATE_API_URL=https://api.frankfurter.dev
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
backup/
|
||||||
|
services/api/src/import-excel.ts
|
||||||
legacy-cent-app/
|
legacy-cent-app/
|
||||||
node_modules/
|
node_modules/
|
||||||
dist/
|
dist/
|
||||||
|
|
|
||||||
|
|
@ -85,7 +85,9 @@ docker compose --env-file .env -f compose.pro.yaml exec api \
|
||||||
|
|
||||||
## 生产数据库备份
|
## 生产数据库备份
|
||||||
|
|
||||||
`backup` 容器每天北京时间 `03:00` 将 PostgreSQL 备份到生产 clone 目录下的 `./backups`。备份采用 PostgreSQL custom format,并在写入后校验;超过 30 天的备份会自动删除。
|
`backup` 容器每天北京时间 `03:00` 将 PostgreSQL 备份到生产 clone 目录下的 `./backups/db`。备份容器使用宿主机普通用户运行,不会以 root 保存备份文件。备份采用 PostgreSQL custom format,并在写入后校验;超过 30 天的备份会自动删除。
|
||||||
|
|
||||||
|
`BACKUP_UID` 和 `BACKUP_GID` 应设置为生产宿主机运行 Cents 的普通用户 UID/GID;默认值为 `1001`。
|
||||||
|
|
||||||
查看调度和备份日志:
|
查看调度和备份日志:
|
||||||
|
|
||||||
|
|
@ -103,5 +105,5 @@ docker compose --env-file .env -f compose.pro.yaml exec backup \
|
||||||
备份文件位于宿主机:
|
备份文件位于宿主机:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
./backups/cents-YYYYMMDD-HHMMSS.dump
|
./backups/db/cents-YYYYMMDD-HHMMSS.dump
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ services:
|
||||||
backup:
|
backup:
|
||||||
image: postgres:17-alpine
|
image: postgres:17-alpine
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
user: "${BACKUP_UID:-1001}:${BACKUP_GID:-1001}"
|
||||||
environment:
|
environment:
|
||||||
TZ: Asia/Shanghai
|
TZ: Asia/Shanghai
|
||||||
PGHOST: db
|
PGHOST: db
|
||||||
|
|
@ -45,7 +46,7 @@ services:
|
||||||
PGPASSWORD: ${POSTGRES_PASSWORD}
|
PGPASSWORD: ${POSTGRES_PASSWORD}
|
||||||
entrypoint: ["/usr/local/bin/cents-backup"]
|
entrypoint: ["/usr/local/bin/cents-backup"]
|
||||||
volumes:
|
volumes:
|
||||||
- ./backups:/backups
|
- ./backups/db:/backups
|
||||||
- ./deploy/postgres-backup.sh:/usr/local/bin/cents-backup:ro
|
- ./deploy/postgres-backup.sh:/usr/local/bin/cents-backup:ro
|
||||||
depends_on:
|
depends_on:
|
||||||
db:
|
db:
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,13 @@ case "${1:-cron}" in
|
||||||
run_backup
|
run_backup
|
||||||
;;
|
;;
|
||||||
cron)
|
cron)
|
||||||
|
cron_dir=/tmp/cents-crontabs
|
||||||
|
mkdir -p "$cron_dir"
|
||||||
printf '%s\n' \
|
printf '%s\n' \
|
||||||
'0 3 * * * /usr/local/bin/cents-backup run >> /proc/1/fd/1 2>> /proc/1/fd/2' \
|
'0 3 * * * /usr/local/bin/cents-backup run >> /proc/1/fd/1 2>> /proc/1/fd/2' \
|
||||||
> /etc/crontabs/root
|
> "$cron_dir/$(id -u)"
|
||||||
printf 'Backup scheduler started: daily at 03:00 %s, retaining 30 days\n' "${TZ:-local time}"
|
printf 'Backup scheduler started: daily at 03:00 %s, retaining 30 days\n' "${TZ:-local time}"
|
||||||
exec crond -f -l 2
|
exec crond -f -l 2 -c "$cron_dir"
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
printf 'Unknown command: %s\n' "$1" >&2
|
printf 'Unknown command: %s\n' "$1" >&2
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@
|
||||||
"dev:web:tunnel": "npm run dev --workspace @cents/web -- --port 6064",
|
"dev:web:tunnel": "npm run dev --workspace @cents/web -- --port 6064",
|
||||||
"dev:api": "npm run dev --workspace @cents/api",
|
"dev:api": "npm run dev --workspace @cents/api",
|
||||||
"user:add": "npm run user:add --workspace @cents/api --",
|
"user:add": "npm run user:add --workspace @cents/api --",
|
||||||
|
"data:import": "npm run data:import --workspace @cents/api --",
|
||||||
"build": "npm run build --workspaces --if-present",
|
"build": "npm run build --workspaces --if-present",
|
||||||
"typecheck": "npm run typecheck --workspaces --if-present",
|
"typecheck": "npm run typecheck --workspaces --if-present",
|
||||||
"lint": "npm run lint --workspaces --if-present"
|
"lint": "npm run lint --workspaces --if-present"
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
"start": "tsx src/server.ts",
|
"start": "tsx src/server.ts",
|
||||||
"bootstrap": "tsx src/bootstrap.ts",
|
"bootstrap": "tsx src/bootstrap.ts",
|
||||||
"user:add": "tsx src/add-user.ts",
|
"user:add": "tsx src/add-user.ts",
|
||||||
|
"data:import": "tsx src/import-excel.ts",
|
||||||
"password:reset": "tsx src/reset-password.ts",
|
"password:reset": "tsx src/reset-password.ts",
|
||||||
"build": "tsc --noEmit",
|
"build": "tsc --noEmit",
|
||||||
"typecheck": "tsc --noEmit"
|
"typecheck": "tsc --noEmit"
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue