services: tokenhub-backend: container_name: tokenhub-backend image: ghcr.io/astaxie/tokenhub-backend:${TOKENHUB_IMAGE_TAG:-latest} build: context: .. dockerfile: backend/Dockerfile args: GOPROXY: ${GOPROXY:-https://goproxy.cn,direct} restart: unless-stopped mem_limit: ${TOKENHUB_CONTAINER_MEMORY_LIMIT:-4g} memswap_limit: ${TOKENHUB_CONTAINER_MEMORY_LIMIT:-4g} environment: GOMEMLIMIT: ${GOMEMLIMIT:-2GiB} TOKENHUB_ENV: ${TOKENHUB_ENV:-prod} TOKENHUB_DEPLOYMENT_TYPE: container TOKENHUB_MANAGED_UPDATES: "true" TOKENHUB_INSTALL_ROOT: /opt/tokenhub TOKENHUB_RUN_MODE: all TOKENHUB_HTTP_ADDR: :8080 TOKENHUB_PUBLIC_BASE_URL: ${TOKENHUB_PUBLIC_BASE_URL:-http://localhost:8080} TOKENHUB_RELEASE_REPOSITORY: ${TOKENHUB_RELEASE_REPOSITORY:-astaxie/TokenHub} TOKENHUB_PLUGIN_DIR: ${TOKENHUB_PLUGIN_DIR:-/app/plugins} TOKENHUB_PLUGIN_MARKETPLACE_URL: ${TOKENHUB_PLUGIN_MARKETPLACE_URL:-} TOKENHUB_TRUSTED_PROXY_CIDRS: ${TOKENHUB_TRUSTED_PROXY_CIDRS:-} TOKENHUB_PROVIDER_UPSTREAM_ACCESS_MODE: ${TOKENHUB_PROVIDER_UPSTREAM_ACCESS_MODE:-strict} TOKENHUB_PROVIDER_UPSTREAM_PROXY_LOCAL: ${TOKENHUB_PROVIDER_UPSTREAM_PROXY_LOCAL:-false} TOKENHUB_PROVIDER_UPSTREAM_ALLOWED_CIDRS: ${TOKENHUB_PROVIDER_UPSTREAM_ALLOWED_CIDRS:-} TOKENHUB_PROVIDER_UPSTREAM_NAT64_PREFIX: ${TOKENHUB_PROVIDER_UPSTREAM_NAT64_PREFIX:-} TOKENHUB_PROVIDER_UPSTREAM_ALLOW_LOOPBACK: ${TOKENHUB_PROVIDER_UPSTREAM_ALLOW_LOOPBACK:-false} HTTP_PROXY: ${HTTP_PROXY:-} HTTPS_PROXY: ${HTTPS_PROXY:-} NO_PROXY: ${NO_PROXY:-} TOKENHUB_CORS_ALLOWED_ORIGINS: ${TOKENHUB_CORS_ALLOWED_ORIGINS:-http://localhost:3000} TOKENHUB_ADMIN_TOKEN: ${TOKENHUB_ADMIN_TOKEN:-change-me-tokenhub-admin-token} TOKENHUB_BOOTSTRAP_ADMIN_PASSWORD: ${TOKENHUB_BOOTSTRAP_ADMIN_PASSWORD:-change-me-tokenhub-admin-password} TOKENHUB_SECRET_KEY: ${TOKENHUB_SECRET_KEY:-change-me-tokenhub-secret-key} TOKENHUB_DATABASE_URL: ${TOKENHUB_DATABASE_URL:-sqlite:///app/data/tokenhub.db} TOKENHUB_SQLITE_BACKUP_DIR: /app/data/backups TOKENHUB_MODEL_CATALOG_FILE: /opt/tokenhub/current/catalog/model-catalog.yaml TOKENHUB_PROVIDER_CATALOG_FILE: /opt/tokenhub/current/catalog/provider-catalog.json TOKENHUB_SEED_DEMO: ${TOKENHUB_SEED_DEMO:-false} TOKENHUB_RESOURCE_FAILURE_THRESHOLD: ${TOKENHUB_RESOURCE_FAILURE_THRESHOLD:-3} TOKENHUB_RESOURCE_COOLDOWN_SECONDS: ${TOKENHUB_RESOURCE_COOLDOWN_SECONDS:-300} TOKENHUB_RESOURCE_COOLDOWN_MAX_SECONDS: ${TOKENHUB_RESOURCE_COOLDOWN_MAX_SECONDS:-3600} TOKENHUB_METRICS_ENABLED: ${TOKENHUB_METRICS_ENABLED:-false} TOKENHUB_METRICS_TOKEN: ${TOKENHUB_METRICS_TOKEN:-} TOKENHUB_METRICS_PROJECT_LABEL: ${TOKENHUB_METRICS_PROJECT_LABEL:-false} TOKENHUB_TRACING_ENABLED: ${TOKENHUB_TRACING_ENABLED:-false} TOKENHUB_TRACING_ENDPOINT: ${TOKENHUB_TRACING_ENDPOINT:-} TOKENHUB_TRACING_HEADERS: ${TOKENHUB_TRACING_HEADERS:-} TOKENHUB_TRACING_CAPTURE_PAYLOADS: ${TOKENHUB_TRACING_CAPTURE_PAYLOADS:-false} TOKENHUB_TRACING_SAMPLE_RATIO: ${TOKENHUB_TRACING_SAMPLE_RATIO:-1} TOKENHUB_TRACING_TIMEOUT_SECONDS: ${TOKENHUB_TRACING_TIMEOUT_SECONDS:-10} TOKENHUB_TRACING_QUEUE_SIZE: ${TOKENHUB_TRACING_QUEUE_SIZE:-2048} TOKENHUB_UPSTREAM_NON_STREAM_TIMEOUT_SECONDS: ${TOKENHUB_UPSTREAM_NON_STREAM_TIMEOUT_SECONDS:-120} TOKENHUB_UPSTREAM_STREAM_IDLE_TIMEOUT_SECONDS: ${TOKENHUB_UPSTREAM_STREAM_IDLE_TIMEOUT_SECONDS:-300} TOKENHUB_MAX_JSON_REQUEST_BYTES: ${TOKENHUB_MAX_JSON_REQUEST_BYTES:-8388608} TOKENHUB_MAX_MULTIMODAL_REQUEST_BYTES: ${TOKENHUB_MAX_MULTIMODAL_REQUEST_BYTES:-33554432} TOKENHUB_IN_FLIGHT_LEASE_TTL_SECONDS: ${TOKENHUB_IN_FLIGHT_LEASE_TTL_SECONDS:-300} TOKENHUB_CLUSTER_LOCK_TTL_SECONDS: ${TOKENHUB_CLUSTER_LOCK_TTL_SECONDS:-180} TOKENHUB_BILLING_REDIS_URL: ${TOKENHUB_BILLING_REDIS_URL:-} TOKENHUB_GRACEFUL_SHUTDOWN_SECONDS: ${TOKENHUB_GRACEFUL_SHUTDOWN_SECONDS:-150} TOKENHUB_IMAGE_WORKER_CONCURRENCY: ${TOKENHUB_IMAGE_WORKER_CONCURRENCY:-2} TOKENHUB_RESPONSE_WORKER_CONCURRENCY: ${TOKENHUB_RESPONSE_WORKER_CONCURRENCY:-2} TOKENHUB_RESPONSE_POLL_INTERVAL_MILLIS: ${TOKENHUB_RESPONSE_POLL_INTERVAL_MILLIS:-250} TOKENHUB_RESPONSE_JOB_TIMEOUT_SECONDS: ${TOKENHUB_RESPONSE_JOB_TIMEOUT_SECONDS:-300} TOKENHUB_RESPONSE_LEASE_TTL_SECONDS: ${TOKENHUB_RESPONSE_LEASE_TTL_SECONDS:-30} TOKENHUB_RESPONSE_RESULT_TTL_SECONDS: ${TOKENHUB_RESPONSE_RESULT_TTL_SECONDS:-3600} TOKENHUB_RESPONSE_MAX_QUEUED_JOBS: ${TOKENHUB_RESPONSE_MAX_QUEUED_JOBS:-1000} TOKENHUB_SEMANTIC_ROUTING_ENABLED: ${TOKENHUB_SEMANTIC_ROUTING_ENABLED:-false} TOKENHUB_SEMANTIC_ROUTING_PROJECTS: ${TOKENHUB_SEMANTIC_ROUTING_PROJECTS:-} TOKENHUB_TYPESAFE_API_KEY: ${TOKENHUB_TYPESAFE_API_KEY:-} TOKENHUB_TYPESAFE_MODEL: ${TOKENHUB_TYPESAFE_MODEL:-jev-1.13.0} TOKENHUB_SEMANTIC_ROUTING_TIMEOUT_MS: ${TOKENHUB_SEMANTIC_ROUTING_TIMEOUT_MS:-1000} TOKENHUB_CACHE_AFFINITY_ENABLED: ${TOKENHUB_CACHE_AFFINITY_ENABLED:-false} TOKENHUB_CACHE_AFFINITY_MODELS: ${TOKENHUB_CACHE_AFFINITY_MODELS:-} TOKENHUB_CACHE_AFFINITY_ALLOW_USER_SCOPE: ${TOKENHUB_CACHE_AFFINITY_ALLOW_USER_SCOPE:-false} TOKENHUB_GUARDRAIL_MODEL_URL: ${TOKENHUB_GUARDRAIL_MODEL_URL:-} TOKENHUB_GUARDRAIL_MODEL_API_KEY: ${TOKENHUB_GUARDRAIL_MODEL_API_KEY:-} TOKENHUB_GUARDRAIL_MODEL_NAME: ${TOKENHUB_GUARDRAIL_MODEL_NAME:-Qwen/Qwen3Guard-Gen-0.6B} TOKENHUB_GUARDRAIL_MODEL_TIMEOUT_SECONDS: ${TOKENHUB_GUARDRAIL_MODEL_TIMEOUT_SECONDS:-10} TOKENHUB_API_BASE_URL: ${TOKENHUB_API_BASE_URL:-${NEXT_PUBLIC_API_BASE_URL:-http://localhost:8080}} TOKENHUB_FRONTEND_HOST: 0.0.0.0 TOKENHUB_FRONTEND_PORT: 3000 ports: - "${TOKENHUB_BACKEND_PORT:-8080}:8080" - "${TOKENHUB_FRONTEND_PORT:-3000}:3000" volumes: - tokenhub-data:/app/data - tokenhub-plugins:/app/plugins - tokenhub-releases:/opt/tokenhub healthcheck: test: - CMD - node - -e - Promise.all([fetch('http://127.0.0.1:8080/healthz'),fetch('http://127.0.0.1:3000')]).then(rs=>process.exit(rs.every(r=>r.ok)?0:1)).catch(()=>process.exit(1)) interval: 10s timeout: 5s retries: 12 start_period: 20s stop_grace_period: ${TOKENHUB_STOP_GRACE_PERIOD:-180s} networks: - tokenhub volumes: tokenhub-data: name: tokenhub-data tokenhub-plugins: name: tokenhub-plugins tokenhub-releases: name: tokenhub-releases networks: tokenhub: name: tokenhub