feat(deploy): openclaw-01 生产部署脚本、systemd 单元与部署文档

This commit is contained in:
2026-10-30 18:49:31 +08:00
parent 9ac3b46430
commit 57767c77a1
8 changed files with 346 additions and 0 deletions
+50
View File
@@ -0,0 +1,50 @@
#!/usr/bin/env bash
# 在 fnsvr-01 的共享 PostgreSQL 上给「生产」建独立的库与角色。
#
# 为什么独立角色:生产库和开发库在同一个实例(fnsvr-01:8432)。复用 dadao_app
# 等于拿到开发口令就能连生产;所以生产用 dadao_prod_owner / dadao_prod_app,
# 迁移里的 GRANT 与 DEFAULT PRIVILEGES 会按 APP_DB_ROLE / OWNER_DB_ROLE 生成。
#
# 在 fnsvr-01 上以 root 执行(需要 docker 权限):
# OWNER_PW='...' APP_PW='...' bash deploy/prod/provision-db.sh
#
# 幂等:角色或库已存在时跳过创建(不会重置已有口令)。
set -euo pipefail
CONTAINER=${CONTAINER:-1Panel-postgresql-wIKz}
DB=${DB:-dadaotask_prod}
OWNER_ROLE=${OWNER_ROLE:-dadao_prod_owner}
APP_ROLE=${APP_ROLE:-dadao_prod_app}
: "${OWNER_PW:?需要 OWNER_PW 环境变量(迁移角色口令)}"
: "${APP_PW:?需要 APP_PW 环境变量(应用角色口令)}"
echo "== 建角色与库:$DB(owner=$OWNER_ROLE app=$APP_ROLE)=="
docker exec -i "$CONTAINER" psql -U dbadmin -d postgres -v ON_ERROR_STOP=1 -q \
-v owner_role="$OWNER_ROLE" -v owner_pw="$OWNER_PW" \
-v app_role="$APP_ROLE" -v app_pw="$APP_PW" -v db="$DB" <<'SQL'
SELECT format('CREATE ROLE %I LOGIN PASSWORD %L', :'owner_role', :'owner_pw')
WHERE NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = :'owner_role')\gexec
SELECT format('CREATE ROLE %I LOGIN PASSWORD %L', :'app_role', :'app_pw')
WHERE NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = :'app_role')\gexec
-- 应用角色绝不能是 superuser / bypassrls,否则 RLS 直接被跳过
SELECT format('ALTER ROLE %I NOSUPERUSER NOBYPASSRLS NOCREATEDB NOCREATEROLE', :'app_role')\gexec
SELECT format('ALTER ROLE %I NOSUPERUSER NOBYPASSRLS', :'owner_role')\gexec
SELECT format('CREATE DATABASE %I OWNER %I', :'db', :'owner_role')
WHERE NOT EXISTS (SELECT 1 FROM pg_database WHERE datname = :'db')\gexec
SQL
echo "== 库内权限(schema 归 owner,app 只能读写数据)=="
docker exec -i "$CONTAINER" psql -U dbadmin -d "$DB" -v ON_ERROR_STOP=1 -q \
-v owner_role="$OWNER_ROLE" -v app_role="$APP_ROLE" <<'SQL'
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
SELECT format('ALTER SCHEMA public OWNER TO %I', :'owner_role')\gexec
SELECT format('GRANT CONNECT ON DATABASE %I TO %I', current_database(), :'app_role')\gexec
SELECT format('GRANT USAGE ON SCHEMA public TO %I', :'app_role')\gexec
SQL
echo "== 自检 =="
docker exec -i "$CONTAINER" psql -U dbadmin -d "$DB" -tAc \
"select current_database(), (select rolname from pg_roles where rolname='$APP_ROLE'),
(select rolsuper from pg_roles where rolname='$APP_ROLE'),
(select rolbypassrls from pg_roles where rolname='$APP_ROLE')"
echo "完成。注意:建表与 RLS 由 alembic(deploy.sh 第 3 步)负责。"