| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- #!/usr/bin/env bash
- # =============================================================================
- # FranklinWH Toolbox - Casdoor 安装脚本(Docker 方式)
- # =============================================================================
- # 作用:以 Docker Compose 部署 Casdoor(casbin/casdoor),并:
- # 1. 在本地 PostgreSQL 中创建 casdoor 角色与 casdoor 数据库
- # 2. 生成 docker-compose.yml 与 conf/app.conf
- # 3. 首次启动时用 --createDatabase=true 让 Casdoor 建表并写入初始数据
- # 4. 常规启动容器(端口 8010->8000,与线上一致)
- #
- # 前置条件:
- # - Docker + docker compose 插件已安装(可用 install_deps.sh docker)
- # - PostgreSQL 已安装并运行(本机 :5432)
- #
- # 环境变量:
- # CASDOOR_DIR Casdoor 部署目录 (默认 /home/$USER/docker/casdoor)
- # CASDOOR_PORT 对外端口(->容器8000) (默认 8010)
- # CASDOOR_PG_HOST PG 主机(容器内视角) (默认 host.docker.internal)
- # CASDOOR_PG_PORT PG 端口 (默认 5432)
- # CASDOOR_PG_USER Casdoor 使用的 PG 角色 (默认 casdoor)
- # CASDOOR_PG_PASSWORD Casdoor PG 角色密码 (默认 casdoor)
- # CASDOOR_DB_NAME Casdoor 数据库名 (默认 casdoor)
- # CASDOOR_ORIGIN Casdoor 对外访问地址 (默认 http://localhost:8010)
- # =============================================================================
- set -euo pipefail
- CASDOOR_DIR="${CASDOOR_DIR:-$HOME/docker/casdoor}"
- # TODO: [确认] Casdoor 对外端口(默认 8010,需与反向代理 /casdoor 一致)
- CASDOOR_PORT="${CASDOOR_PORT:-8010}"
- CASDOOR_PG_HOST="${CASDOOR_PG_HOST:-host.docker.internal}"
- CASDOOR_PG_PORT="${CASDOOR_PG_PORT:-5432}"
- CASDOOR_PG_USER="${CASDOOR_PG_USER:-casdoor}"
- # TODO: [必填] Casdoor 数据库口令——请通过环境变量传入强口令,勿使用默认 casdoor
- CASDOOR_PG_PASSWORD="${CASDOOR_PG_PASSWORD:-casdoor}"
- CASDOOR_DB_NAME="${CASDOOR_DB_NAME:-casdoor}"
- # TODO: [必填] Casdoor 对外访问地址(origin)——填成实际域名,如 https://<域名>/casdoor
- CASDOOR_ORIGIN="${CASDOOR_ORIGIN:-http://localhost:${CASDOOR_PORT}}"
- c_reset='\033[0m'; c_blue='\033[1;34m'; c_green='\033[1;32m'; c_yellow='\033[1;33m'; c_red='\033[1;31m'
- info() { echo -e "${c_blue}[INFO]${c_reset} $*"; }
- ok() { echo -e "${c_green}[ OK ]${c_reset} $*"; }
- warn() { echo -e "${c_yellow}[WARN]${c_reset} $*"; }
- err() { echo -e "${c_red}[FAIL]${c_reset} $*" >&2; }
- # docker compose 命令探测(插件 or 独立二进制)
- compose() {
- if docker compose version >/dev/null 2>&1; then
- docker compose "$@"
- elif command -v docker-compose >/dev/null 2>&1; then
- docker-compose "$@"
- else
- err "未找到 docker compose,请先安装(install_deps.sh docker)"; return 1
- fi
- }
- # ---------------------------------------------------------------------------
- # 1. PostgreSQL:建角色 + 建库
- # ---------------------------------------------------------------------------
- provision_pg() {
- info "在 PostgreSQL 中准备 Casdoor 角色与数据库 ..."
- command -v psql >/dev/null 2>&1 || { err "未找到 psql,请先安装 PostgreSQL"; return 1; }
- # 角色(幂等)
- sudo -u postgres psql -v ON_ERROR_STOP=1 \
- -v role="${CASDOOR_PG_USER}" -v pwd="${CASDOOR_PG_PASSWORD}" <<'SQL'
- SELECT format('CREATE ROLE %I LOGIN PASSWORD %L', :'role', :'pwd')
- WHERE NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = :'role')
- \gexec
- SQL
- # 数据库(幂等,owner=角色)
- sudo -u postgres psql -v ON_ERROR_STOP=1 \
- -v db="${CASDOOR_DB_NAME}" -v role="${CASDOOR_PG_USER}" <<'SQL'
- SELECT format('CREATE DATABASE %I OWNER %I ENCODING ''UTF8''', :'db', :'role')
- WHERE NOT EXISTS (SELECT 1 FROM pg_database WHERE datname = :'db')
- \gexec
- SQL
- ok "PostgreSQL:角色 ${CASDOOR_PG_USER} / 数据库 ${CASDOOR_DB_NAME} 就绪"
- # 允许容器经 host-gateway 连接本机 PG:确保监听地址与 pg_hba 允许
- warn "请确认 PostgreSQL 允许来自 Docker 网段的连接(listen_addresses 与 pg_hba.conf)。"
- warn "常见做法:postgresql.conf 设 listen_addresses='*';pg_hba.conf 增加 host ${CASDOOR_DB_NAME} ${CASDOOR_PG_USER} 172.16.0.0/12 scram-sha-256,然后 systemctl reload postgresql。"
- }
- # ---------------------------------------------------------------------------
- # 2. 生成 compose 与 app.conf
- # ---------------------------------------------------------------------------
- write_files() {
- info "生成 Casdoor 部署文件到 ${CASDOOR_DIR} ..."
- mkdir -p "${CASDOOR_DIR}/conf"
- # 数据源:Casdoor postgres driver 使用 keyword=value DSN;末尾 dbname 由 dbName 指定
- local dsn="user=${CASDOOR_PG_USER} password=${CASDOOR_PG_PASSWORD} host=${CASDOOR_PG_HOST} port=${CASDOOR_PG_PORT} sslmode=disable dbname="
- cat > "${CASDOOR_DIR}/docker-compose.yml" <<EOF
- services:
- casdoor:
- restart: always
- image: casbin/casdoor:latest
- entrypoint: /bin/sh -c './server'
- ports:
- - "${CASDOOR_PORT}:8000"
- environment:
- RUNNING_IN_DOCKER: "true"
- extra_hosts:
- - "host.docker.internal:host-gateway"
- volumes:
- - ./conf:/conf/
- EOF
- cat > "${CASDOOR_DIR}/conf/app.conf" <<EOF
- appname = casdoor
- httpport = 8000
- runmode = prod
- copyrequestbody = true
- driverName = postgres
- dataSourceName = ${dsn}
- dbName = ${CASDOOR_DB_NAME}
- tableNamePrefix =
- showSql = false
- redisEndpoint =
- defaultStorageProvider =
- isCloudIntranet = false
- authState = "casdoor"
- verificationCodeTimeout = 10
- initScore = 0
- logPostOnly = true
- isUsernameLowered = false
- origin = ${CASDOOR_ORIGIN}
- originFrontend =
- staticBaseUrl = "https://cdn.casbin.org"
- isDemoMode = false
- batchSize = 100
- enableGzip = true
- ldapServerPort = 389
- radiusServerPort = 1812
- radiusDefaultOrganization = "built-in"
- quota = {"organization": -1, "user": -1, "application": -1, "provider": -1}
- logConfig = {"filename": "logs/casdoor.log", "maxdays":99999, "perm":"0770"}
- initDataNewOnly = false
- initDataFile = "./init_data.json"
- frontendBaseDir = "../cc_0"
- EOF
- ok "已生成 docker-compose.yml 与 conf/app.conf"
- }
- # ---------------------------------------------------------------------------
- # 3. 首次建表 + 启动
- # ---------------------------------------------------------------------------
- start_casdoor() {
- cd "${CASDOOR_DIR}"
- # 首次:让 Casdoor 建表并写入初始数据(--createDatabase=true)
- info "首次初始化 Casdoor 数据表(--createDatabase=true)..."
- docker run --rm \
- --add-host host.docker.internal:host-gateway \
- -v "${CASDOOR_DIR}/conf:/conf/" \
- casbin/casdoor:latest \
- /bin/sh -c './server --createDatabase=true' || \
- warn "初始化返回非零(若为“表已存在”可忽略)"
- info "启动 Casdoor 容器 ..."
- compose up -d
- sleep 3
- compose ps
- ok "Casdoor 已启动:${CASDOOR_ORIGIN}(默认管理员 admin/123)"
- }
- main() {
- info "== 安装 Casdoor(Docker)=="
- command -v docker >/dev/null 2>&1 || { err "未找到 docker,请先安装(install_deps.sh docker)"; exit 1; }
- provision_pg
- write_files
- start_casdoor
- cat <<EOF
- ${c_green}Casdoor 部署完成${c_reset}
- 目录 : ${CASDOOR_DIR}
- 访问地址 : ${CASDOOR_ORIGIN}
- 管理员 : admin / 123(首次登录后请立即修改)
- 后续配置 : 见 deploy/DEPLOYMENT.md 的《Casdoor 配置》章节
- (创建组织 organization_franklinwh_toolbox、应用 app-franklinwh-toolbox,
- 取得 clientId/clientSecret/证书,并配置反向代理 /casdoor)
- EOF
- }
- main "$@"
|