{"slug": "how-to-self-host-an-ai-api-gateway-with-sub2api", "title": "How to Self-Host an AI API Gateway With Sub2API", "summary": "Sub2API is an open-source AI API gateway that lets developers self-host a unified endpoint for multiple AI providers, handling authentication, routing, usage accounting, and concurrency limits. The project provides a Docker-based deployment with PostgreSQL and Redis, and requires careful configuration of environment variables and reverse proxy settings for production use. Developer Wei Shaw warns that distributing quota from AI subscriptions may violate upstream terms of service.", "body_md": "Sub2API can put one Base URL in front of several AI providers and accounts. Your clients use keys that you issue, while the gateway handles authentication, routing, usage accounting, and concurrency limits.\n\nGetting the containers online is the easy part. Once the gateway is running, you also own its database, Redis instance, TLS endpoint, credentials, logs, backups, and upgrades.\n\nThis guide builds the smallest useful private setup and shows what to verify before giving anyone else access.\n\nThe request path looks like this:\n\nSub2API currently supports multiple upstream account types, platform API keys, token-level usage accounting, sticky-session scheduling, per-user and per-account concurrency controls, rate limits, composite groups, and an admin dashboard.\n\nThis does not make you independent of the upstream provider. If an upstream account is suspended, overloaded, or incompatible with a request, the gateway cannot manufacture capacity or model access.\n\nThe project README also warns that distributing quota from AI subscriptions may violate upstream terms of service. Keep the first deployment private, use accounts you are authorized to use, and review the provider terms before sharing or selling access.\n\nSub2API is useful when you need to:\n\nIf one person calls one official API, adding a gateway usually makes the system more fragile. Self-hosting starts to pay off when access management and routing are already becoming a coordination problem.\n\nFor the Docker path, you need a Linux server, Docker 20.10 or newer, Docker Compose v2, a domain, and at least one authorized upstream account or API key. PostgreSQL and Redis are included in the official Compose stack.\n\nThe project provides a deployment preparation script. Download it first so you can inspect what it will run:\n\n```\nmkdir -p sub2api-deploy\ncd sub2api-deploy\n\ncurl -fsSLo docker-deploy.sh \\\n  https://raw.githubusercontent.com/Wei-Shaw/sub2api/main/deploy/docker-deploy.sh\n\nless docker-deploy.sh\nchmod +x docker-deploy.sh\n./docker-deploy.sh\n```\n\nThe script saves the Compose definition as `docker-compose.yml`\n\n, creates `.env`\n\n, generates the PostgreSQL password and application secrets, and prepares local data directories. It prints the generated credentials to the terminal, so do not paste that output into an issue or chat.\n\nBefore starting the stack, edit `.env`\n\n. If Nginx or Caddy will run on the same server, bind Sub2API to loopback so port 8080 is not exposed directly:\n\n```\nBIND_HOST=127.0.0.1\nSERVER_PORT=8080\nADMIN_EMAIL=you@example.com\nADMIN_PASSWORD=replace-with-a-generated-password\nTZ=UTC\n```\n\nKeep the generated `JWT_SECRET`\n\n, `TOTP_ENCRYPTION_KEY`\n\n, and `POSTGRES_PASSWORD`\n\nstable. Changing them later can invalidate sessions, break existing 2FA configuration, or disconnect the database.\n\nStart the services and check their status:\n\n```\ndocker compose up -d\ndocker compose ps\ndocker compose logs -f sub2api\n```\n\nIn another shell, check the local health endpoint:\n\n```\ncurl -i http://127.0.0.1:8080/health\n```\n\nConfirm that the Sub2API, PostgreSQL, and Redis containers are healthy. Seeing the login page is not enough to prove that the dependencies are working.\n\nUse a domain and HTTPS for the public Base URL. Sub2API handles long-lived SSE and WebSocket traffic, so the reverse proxy must avoid buffering those responses or closing them too early.\n\nThe relevant part of an Nginx configuration is:\n\n```\n# Place these directives in the http block.\nunderscores_in_headers on;\nmap $http_upgrade $connection_upgrade {\n    default upgrade;\n    ''      close;\n}\n\nserver {\n    listen 443 ssl http2;\n    server_name api.example.com;\n\n    # Add your TLS certificate configuration here.\n\n    location / {\n        proxy_pass http://127.0.0.1:8080;\n        proxy_http_version 1.1;\n\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $remote_addr;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection $connection_upgrade;\n\n        proxy_buffering off;\n        proxy_request_buffering off;\n        proxy_read_timeout 1800s;\n        proxy_send_timeout 1800s;\n    }\n}\n```\n\n`underscores_in_headers on;`\n\nmatters because Nginx otherwise drops headers such as `session_id`\n\n, which Sub2API uses for sticky-session routing.\n\nIf you put a CDN in front of the server, restrict origin access and configure trusted proxy ranges instead of accepting forwarded IP headers from any client. The project's [edge security guide](https://github.com/Wei-Shaw/sub2api/blob/main/deploy/EDGE_SECURITY.md) covers that setup in more detail.\n\nVerify the public route separately:\n\n```\ncurl -i https://api.example.com/health\n```\n\nStart with one route you can understand end to end. The dashboard labels may change between releases, but the setup is roughly:\n\nThere are two different credentials in this setup:\n\n``` php\nUpstream credential  -> Sub2API uses it to call the provider\nSub2API key          -> your client uses it to call the gateway\n```\n\nGive clients the second key. They should not need the upstream credential.\n\nFor an OpenAI Responses-compatible route, make a small request with the test user's key:\n\n```\nexport OPENAI_BASE_URL=\"https://api.example.com/v1\"\nexport OPENAI_API_KEY=\"your-sub2api-key\"\n\ncurl \"$OPENAI_BASE_URL/responses\" \\\n  -H \"Authorization: Bearer $OPENAI_API_KEY\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"model\": \"your-model-alias\",\n    \"input\": \"Return exactly: gateway-ok\"\n  }'\n```\n\nClaude Code commonly uses:\n\n```\nexport ANTHROPIC_BASE_URL=\"https://api.example.com\"\nexport ANTHROPIC_AUTH_TOKEN=\"your-sub2api-key\"\nclaude\n```\n\nFor Codex, start with a clean shell:\n\n```\nexport OPENAI_BASE_URL=\"https://api.example.com/v1\"\nexport OPENAI_API_KEY=\"your-sub2api-key\"\ncodex\n```\n\nAfter the first request, open the dashboard and check the record. Confirm that the expected user, key, group, account, model, token count, and charge were used.\n\nThen test the behavior your real client depends on:\n\nAlso try an invalid key, a user with no remaining budget, and an unavailable upstream. These tests tell you whether access stops cleanly and whether a failure can silently reach the wrong model.\n\nBefore using the gateway for regular work:\n\n`latest`\n\nunattended.`/health`\n\n, container restarts, disk space, upstream errors, latency, and certificate expiry.`.env`\n\n, the Compose file, application data, and PostgreSQL.Do not copy a live PostgreSQL data directory and assume it is consistent. Use `pg_dump`\n\n, a database-aware storage snapshot, or stop the stack before taking a filesystem archive. Encrypt backups and test a restore on another machine.\n\nSub2API is a reasonable choice when you want to own the gateway policy and are willing to operate the supporting infrastructure.\n\nIf you would rather not maintain PostgreSQL, Redis, TLS, backups, security, and upstream accounts, do not self-host merely because the code is available. You can compare existing AI API relay services, including services built with Sub2API, on [CCNavX](https://ccnavx.com/directory/sub2api-proxy).", "url": "https://wpnews.pro/news/how-to-self-host-an-ai-api-gateway-with-sub2api", "canonical_source": "https://dev.to/skedaddle/how-to-self-host-an-ai-api-gateway-with-sub2api-3i99", "published_at": "2026-07-26 14:16:15+00:00", "updated_at": "2026-07-26 14:30:16.930021+00:00", "lang": "en", "topics": ["developer-tools", "ai-infrastructure", "ai-products"], "entities": ["Sub2API", "Wei Shaw", "Docker", "PostgreSQL", "Redis", "Nginx"], "alternates": {"html": "https://wpnews.pro/news/how-to-self-host-an-ai-api-gateway-with-sub2api", "markdown": "https://wpnews.pro/news/how-to-self-host-an-ai-api-gateway-with-sub2api.md", "text": "https://wpnews.pro/news/how-to-self-host-an-ai-api-gateway-with-sub2api.txt", "jsonld": "https://wpnews.pro/news/how-to-self-host-an-ai-api-gateway-with-sub2api.jsonld"}}