c592f426be
Keep runtime grant verification aligned with all database migrations so release builds fail before missing table privileges reach deployment.
103 lines
4.4 KiB
YAML
103 lines
4.4 KiB
YAML
services:
|
|
account-server:
|
|
image: ${ACCOUNT_IMAGE:-ghcr.io/hkgood/osg-account-server}:${IMAGE_TAG:-main}
|
|
pull_policy: always
|
|
restart: unless-stopped
|
|
init: true
|
|
user: "10001:10001"
|
|
stop_grace_period: 30s
|
|
environment:
|
|
APP_ENV: production
|
|
PORT: "8080"
|
|
PUBLIC_BASE_URL: https://account.osglab.com
|
|
INVITE_BASE_URL: https://osglab.com/i
|
|
APP_STORE_URL: ${APP_STORE_URL:?set the production App Store HTTPS URL}
|
|
|
|
# Reuse the existing MySQL; this stack intentionally creates no database.
|
|
DATABASE_URL: ${DATABASE_URL:?set DATABASE_URL for the existing MySQL}
|
|
DATABASE_USER: ${DATABASE_USER:?set DATABASE_USER}
|
|
DATABASE_PASSWORD: ${DATABASE_PASSWORD:?set DATABASE_PASSWORD}
|
|
DATABASE_POOL_SIZE: ${DATABASE_POOL_SIZE:-10}
|
|
DATABASE_MIGRATION_USER: ${DATABASE_MIGRATION_USER:?set DATABASE_MIGRATION_USER}
|
|
DATABASE_MIGRATION_PASSWORD: ${DATABASE_MIGRATION_PASSWORD:?set DATABASE_MIGRATION_PASSWORD}
|
|
|
|
JWT_ISSUER: https://account.osglab.com
|
|
JWT_AUDIENCE: ${JWT_AUDIENCE:-osgkeyboard-ios}
|
|
JWT_SECRET: ${JWT_SECRET:?set a random JWT secret}
|
|
ACCESS_TOKEN_MINUTES: ${ACCESS_TOKEN_MINUTES:-15}
|
|
REFRESH_TOKEN_DAYS: ${REFRESH_TOKEN_DAYS:-30}
|
|
GATEWAY_GRANT_DAYS: ${GATEWAY_GRANT_DAYS:-30}
|
|
FIELD_ENCRYPTION_KEY: ${FIELD_ENCRYPTION_KEY:?set a 32-byte Base64 key}
|
|
IDENTITY_HMAC_KEY: ${IDENTITY_HMAC_KEY:?set a distinct Base64 key}
|
|
IDENTITY_TOMBSTONE_RETENTION_DAYS: ${IDENTITY_TOMBSTONE_RETENTION_DAYS:-365}
|
|
|
|
ADMIN_ENABLED: ${ADMIN_ENABLED:-false}
|
|
ADMIN_BOOTSTRAP_ENABLED: ${ADMIN_BOOTSTRAP_ENABLED:-false}
|
|
ADMIN_BOOTSTRAP_OPERATOR_ID: ${ADMIN_BOOTSTRAP_OPERATOR_ID:-}
|
|
ADMIN_BOOTSTRAP_USERNAME: ${ADMIN_BOOTSTRAP_USERNAME:-}
|
|
ADMIN_BOOTSTRAP_PASSWORD_HASH: ${ADMIN_BOOTSTRAP_PASSWORD_HASH:-}
|
|
ADMIN_BOOTSTRAP_TOTP_SECRET_BASE32: ${ADMIN_BOOTSTRAP_TOTP_SECRET_BASE32:-}
|
|
ADMIN_SESSION_HOURS: ${ADMIN_SESSION_HOURS:-8}
|
|
ADMIN_MAXIMUM_MANUAL_GRANT: ${ADMIN_MAXIMUM_MANUAL_GRANT:-100000}
|
|
|
|
APPLE_TEAM_ID: ${APPLE_TEAM_ID:?set Apple team ID}
|
|
APPLE_KEY_ID: ${APPLE_KEY_ID:?set Apple key ID}
|
|
APPLE_CLIENT_ID: ${APPLE_CLIENT_ID:-com.osgkeyboard.ios}
|
|
APPLE_PRIVATE_KEY_PEM: ${APPLE_PRIVATE_KEY_PEM:?set Apple private key PEM}
|
|
APPLE_INTEGRITY_ENVIRONMENT: production
|
|
APP_ATTEST_CHALLENGE_TTL_SECONDS: ${APP_ATTEST_CHALLENGE_TTL_SECONDS:-300}
|
|
ENFORCE_DEVICE_CHECK: "true"
|
|
ENFORCE_APP_ATTEST: "true"
|
|
|
|
VOLCENGINE_API_KEY: ${VOLCENGINE_API_KEY:?set Volcengine API key}
|
|
VOLCENGINE_RESOURCE_ID: ${VOLCENGINE_RESOURCE_ID:-volc.seedasr.sauc.duration}
|
|
VOLCENGINE_ASR_ENDPOINT: ${VOLCENGINE_ASR_ENDPOINT:-wss://openspeech.bytedance.com/api/v3/sauc/bigmodel}
|
|
DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY:?set DeepSeek API key}
|
|
DEEPSEEK_MODEL: ${DEEPSEEK_MODEL:-deepseek-v4-flash}
|
|
DEEPSEEK_ENDPOINT: ${DEEPSEEK_ENDPOINT:-https://api.deepseek.com/v1}
|
|
|
|
SIGNUP_TRIAL_CREDITS: ${SIGNUP_TRIAL_CREDITS:-1000}
|
|
REFERRAL_INVITER_CREDITS: ${REFERRAL_INVITER_CREDITS:-1000}
|
|
REFERRAL_INVITEE_CREDITS: ${REFERRAL_INVITEE_CREDITS:-1000}
|
|
REFERRAL_BINDING_DAYS: ${REFERRAL_BINDING_DAYS:-7}
|
|
STOREKIT_ENABLED: ${STOREKIT_ENABLED:-true}
|
|
STOREKIT_BUNDLE_ID: ${STOREKIT_BUNDLE_ID:-com.osgkeyboard.ios}
|
|
STOREKIT_APP_APPLE_ID: ${STOREKIT_APP_APPLE_ID:-6781553267}
|
|
STOREKIT_PRODUCTS: ${STOREKIT_PRODUCTS:-500tks:500,1500tks:1500,3000tks:3000}
|
|
ports:
|
|
- "127.0.0.1:${ACCOUNT_BIND_PORT:-18080}:8080"
|
|
read_only: true
|
|
pids_limit: 256
|
|
tmpfs:
|
|
- /tmp:size=64m,mode=1777,noexec,nosuid,nodev
|
|
cap_drop:
|
|
- ALL
|
|
security_opt:
|
|
- no-new-privileges:true
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-q", "-O", "/dev/null", "http://127.0.0.1:8080/health/ready"]
|
|
interval: 30s
|
|
timeout: 3s
|
|
start_period: 30s
|
|
retries: 3
|
|
logging:
|
|
driver: json-file
|
|
options:
|
|
max-size: "10m"
|
|
max-file: "3"
|
|
networks:
|
|
- account-backend
|
|
# Separate egress keeps Apple/provider traffic available when the shared
|
|
# database network was created with Docker's --internal flag.
|
|
- account-egress
|
|
|
|
networks:
|
|
# Pre-create this shared network with:
|
|
# docker network create --internal account-backend
|
|
# Attach the existing MySQL container without publishing port 3306.
|
|
account-backend:
|
|
external: true
|
|
name: ${ACCOUNT_DOCKER_NETWORK:-account-backend}
|
|
account-egress:
|
|
driver: bridge
|