chore(server): define Railway service deployment config
This commit is contained in:
@@ -24,6 +24,46 @@ pnpm dev:backend
|
||||
The command uses `server/docker-compose.yaml` and exposes only Caddy at
|
||||
`http://localhost:6112`.
|
||||
|
||||
## Railway deployment
|
||||
|
||||
API and Auth are separate long-running Railway services built from the same
|
||||
repository. Keep each service's **Root Directory** at the repository root:
|
||||
both Dockerfiles copy workspace manifests and shared packages from that build
|
||||
context. In each Railway service, configure the Config File Path explicitly:
|
||||
|
||||
| Service | Config File Path | Public role | Private dependency |
|
||||
| --- | --- | --- | --- |
|
||||
| Resource API | `/server/apps/api/railway.toml` | Product and resource API | Auth issuer and JWKS |
|
||||
| Auth | `/server/apps/auth/railway.toml` | Better Auth and OIDC issuer | Resource API deletion endpoint |
|
||||
|
||||
Each config pins its own Dockerfile, start command, `/readyz` healthcheck, and
|
||||
watch patterns. A change only deploys a service when it changes that service,
|
||||
one of its copied shared packages, or a copied root build input.
|
||||
|
||||
### Service-to-service contract
|
||||
|
||||
Share database, Redis, and observability variables using Railway reference
|
||||
variables rather than copying secret values between services. Configure the
|
||||
two directional private links as follows:
|
||||
|
||||
| Consumer | Variable | Value source | Purpose |
|
||||
| --- | --- | --- | --- |
|
||||
| Resource API | `AUTH_SERVER_URL` | Auth's canonical public issuer URL | JWT issuer, audience, and public JWKS identity |
|
||||
| Resource API | `AUTH_SERVER_INTERNAL_URL` | Auth's Railway private domain | Private JWKS fetch; it does not change issuer validation |
|
||||
| Auth | `PUBLIC_URL` | Auth's canonical public issuer URL | Better Auth and OIDC issuer URL; must equal API `AUTH_SERVER_URL` |
|
||||
| Auth | `RESOURCE_SERVER_URL` | API's Railway private domain | Private call before deleting a user's business data |
|
||||
|
||||
Set `RATE_LIMIT_TRUSTED_PROXY=railway` only for services directly receiving
|
||||
Railway proxy traffic. Keep `/internal/*` private: Auth calls the API over its
|
||||
private domain, and public routing must not expose the API's internal Auth
|
||||
routes.
|
||||
|
||||
The API remains the shared database migration owner. Do not add a Railway
|
||||
pre-deploy migration command to Auth, and do not make Auth startup run shared
|
||||
migrations. After either service deploys, Railway must receive `200` from that
|
||||
service's `/readyz`; deployment success alone is not sufficient evidence that
|
||||
the service can reach its required dependencies.
|
||||
|
||||
## Not included
|
||||
|
||||
Frontend applications remain under `apps/`. Cross-runtime server SDK and
|
||||
|
||||
@@ -35,8 +35,8 @@ the API and Auth container ports private.
|
||||
|
||||
## Service boundaries
|
||||
|
||||
- `AUTH_SERVER_URL` is the public issuer origin used for JWKS, issuer, and
|
||||
audience validation. With Caddy routing, it remains `https://api.airi.build`.
|
||||
- `AUTH_SERVER_URL` is Auth's canonical public issuer origin used for JWKS,
|
||||
issuer, and audience validation. It must exactly equal Auth's `PUBLIC_URL`.
|
||||
- `/internal/auth/*` is reachable only on the deployment's trusted private
|
||||
network. The public edge must reject `/internal/*` and the API service must
|
||||
not have its own public ingress.
|
||||
@@ -46,3 +46,16 @@ the API and Auth container ports private.
|
||||
under `server/apps/auth` is imported.
|
||||
- `ADMIN_UI_URL` controls the standalone admin UI redirect and defaults to
|
||||
`https://admin.airi.build`.
|
||||
|
||||
## Railway
|
||||
|
||||
Deploy this as the Resource API Railway service with Config File Path
|
||||
`/server/apps/api/railway.toml`; keep the service Root Directory at the
|
||||
repository root because the Dockerfile copies shared workspace packages. The
|
||||
config owns its Dockerfile, start command, `/readyz` healthcheck, and the
|
||||
watch patterns for every copied build input.
|
||||
|
||||
Set `AUTH_SERVER_INTERNAL_URL` from Auth's Railway private domain. It is only
|
||||
the private JWKS route; `AUTH_SERVER_URL` remains the public Auth issuer URL.
|
||||
See [`server/README.md`](../../README.md#railway-deployment) for the complete
|
||||
cross-service variable and migration contract.
|
||||
|
||||
@@ -3,9 +3,17 @@ builder = "DOCKERFILE"
|
||||
dockerfilePath = "/server/apps/api/production/railway/Dockerfile"
|
||||
watchPatterns = [
|
||||
"server/apps/api/**",
|
||||
"server/packages/**",
|
||||
"pnpm-lock.yaml"
|
||||
"server/packages/auth-shared/**",
|
||||
"server/packages/drizzle-migration/**",
|
||||
"packages/server-sdk-shared/**",
|
||||
"package.json",
|
||||
"pnpm-lock.yaml",
|
||||
"pnpm-workspace.yaml",
|
||||
"tsconfig.json",
|
||||
"patches/**"
|
||||
]
|
||||
|
||||
[deploy]
|
||||
startCommand = "pnpm -F @proj-airi/api-server start"
|
||||
healthcheckPath = "/readyz"
|
||||
healthcheckTimeout = 100
|
||||
|
||||
@@ -42,6 +42,21 @@ pnpm dev:backend
|
||||
stay on its private network. The internal `/internal/*` boundary has no
|
||||
application token, and Caddy rejects that path at the public edge.
|
||||
|
||||
## Railway
|
||||
|
||||
Deploy this as the Auth Railway service with Config File Path
|
||||
`/server/apps/auth/railway.toml`; keep the service Root Directory at the
|
||||
repository root because the Dockerfile copies workspace manifests and
|
||||
`server/packages/auth-shared`. The config owns its Dockerfile, start command,
|
||||
`/readyz` healthcheck, and the watch patterns for each copied build input.
|
||||
|
||||
Set `PUBLIC_URL` to this service's canonical public issuer URL, and make the
|
||||
Resource API's `AUTH_SERVER_URL` exactly the same value. Set
|
||||
`RESOURCE_SERVER_URL` from the Resource API's Railway private domain; do not
|
||||
run shared database migrations from Auth. See
|
||||
[`server/README.md`](../../README.md#railway-deployment) for the complete
|
||||
service contract.
|
||||
|
||||
## Do not use it for
|
||||
|
||||
- Product APIs, billing, model routing, chat, or WebSocket business state.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
[build]
|
||||
builder = "DOCKERFILE"
|
||||
dockerfilePath = "/server/apps/auth/Dockerfile"
|
||||
watchPatterns = [
|
||||
"server/apps/auth/**",
|
||||
"server/packages/auth-shared/**",
|
||||
"package.json",
|
||||
"pnpm-lock.yaml",
|
||||
"pnpm-workspace.yaml",
|
||||
"tsconfig.json",
|
||||
"patches/**"
|
||||
]
|
||||
|
||||
[deploy]
|
||||
startCommand = "pnpm -F @proj-airi/auth-server start"
|
||||
healthcheckPath = "/readyz"
|
||||
healthcheckTimeout = 100
|
||||
Reference in New Issue
Block a user