Concepts, value, and typical clone scenarios — less code.
Concepts, value, and typical clone scenarios — less code.
Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Підготовка контенту платформи Ring
Ring Platform supports three deployment targets: k3s cluster (production), Vercel (preview), and Docker (self-hosted). The platform uses a unified environment configuration; only DB_BACKEND_MODE and RING_DEPLOY_TARGET change between targets.
This page is a deployment strategy overview. For step-by-step instructions see the dedicated deployment pages: Vercel, Docker, Self-hosted, and Environment configuration.
The primary production target is a Kubernetes cluster (5.161.246.54). All Ringdom empire clones run on this cluster.
TUNNEL_HUB_MODE=k8s-postgres)Vercel is suitable for preview deployments and rapid prototyping. Serverless route handlers run on Vercel Edge — the custom server (server.ts) is not used, so native WebSocket Tunnel is unavailable. Tunnel reverts to SSE + long-polling.
RING_DEPLOY_TARGET=vercel and NEXT_PUBLIC_RING_DEPLOY_TARGET=vercelDB_BACKEND_MODE=firebase-full (Firestore) or k8s-postgres-fcm (requires a reachable PostgreSQL host)Docker deployment is documented for community self-hosting (OSS repository). The Dockerfile builds a production image with the custom server (server.ts) and native WSS Tunnel support. PostgreSQL runs as a companion container or external service.
DB_BACKEND_MODE=k8s-postgres-fcm)The single source of truth for all environment variables is env.local.template in the repository root. Key decisions:
| Variable | Purpose |
|---|---|
DB_BACKEND_MODE | Database adapter: k8s-postgres-fcm (recommended), firebase-full, or supabase-fcm |
RING_DEPLOY_TARGET | Tunnel and runtime mode: k8s, vercel, or self-hosted |
AUTH_SECRET | Auth.js session encryption (generate with openssl rand -base64 32) |
AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET | Google OAuth credentials |
See Environment configuration for the complete variable reference.
Never commit real secrets to Git. Copy env.local.template to .env.local (gitignored) and fill in production values. On k3s, inject secrets via Kubernetes secrets; on Vercel, use the Vercel dashboard environment variables.
Ring Platform supports three deployment targets: k3s cluster (production), Vercel (preview), and Docker (self-hosted). The platform uses a unified environment configuration; only DB_BACKEND_MODE and RING_DEPLOY_TARGET change between targets.
This page is a deployment strategy overview. For step-by-step instructions see the dedicated deployment pages: Vercel, Docker, Self-hosted, and Environment configuration.
The primary production target is a Kubernetes cluster (5.161.246.54). All Ringdom empire clones run on this cluster.
TUNNEL_HUB_MODE=k8s-postgres)Vercel is suitable for preview deployments and rapid prototyping. Serverless route handlers run on Vercel Edge — the custom server (server.ts) is not used, so native WebSocket Tunnel is unavailable. Tunnel reverts to SSE + long-polling.
RING_DEPLOY_TARGET=vercel and NEXT_PUBLIC_RING_DEPLOY_TARGET=vercelDB_BACKEND_MODE=firebase-full (Firestore) or k8s-postgres-fcm (requires a reachable PostgreSQL host)Docker deployment is documented for community self-hosting (OSS repository). The Dockerfile builds a production image with the custom server (server.ts) and native WSS Tunnel support. PostgreSQL runs as a companion container or external service.
DB_BACKEND_MODE=k8s-postgres-fcm)The single source of truth for all environment variables is env.local.template in the repository root. Key decisions:
| Variable | Purpose |
|---|---|
DB_BACKEND_MODE | Database adapter: k8s-postgres-fcm (recommended), firebase-full, or supabase-fcm |
RING_DEPLOY_TARGET | Tunnel and runtime mode: k8s, vercel, or self-hosted |
AUTH_SECRET | Auth.js session encryption (generate with openssl rand -base64 32) |
AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET | Google OAuth credentials |
See Environment configuration for the complete variable reference.
Never commit real secrets to Git. Copy env.local.template to .env.local (gitignored) and fill in production values. On k3s, inject secrets via Kubernetes secrets; on Vercel, use the Vercel dashboard environment variables.
Ring Platform supports three deployment targets: k3s cluster (production), Vercel (preview), and Docker (self-hosted). The platform uses a unified environment configuration; only DB_BACKEND_MODE and RING_DEPLOY_TARGET change between targets.
This page is a deployment strategy overview. For step-by-step instructions see the dedicated deployment pages: Vercel, Docker, Self-hosted, and Environment configuration.
The primary production target is a Kubernetes cluster (5.161.246.54). All Ringdom empire clones run on this cluster.
TUNNEL_HUB_MODE=k8s-postgres)Vercel is suitable for preview deployments and rapid prototyping. Serverless route handlers run on Vercel Edge — the custom server (server.ts) is not used, so native WebSocket Tunnel is unavailable. Tunnel reverts to SSE + long-polling.
RING_DEPLOY_TARGET=vercel and NEXT_PUBLIC_RING_DEPLOY_TARGET=vercelDB_BACKEND_MODE=firebase-full (Firestore) or k8s-postgres-fcm (requires a reachable PostgreSQL host)Docker deployment is documented for community self-hosting (OSS repository). The Dockerfile builds a production image with the custom server (server.ts) and native WSS Tunnel support. PostgreSQL runs as a companion container or external service.
DB_BACKEND_MODE=k8s-postgres-fcm)The single source of truth for all environment variables is env.local.template in the repository root. Key decisions:
| Variable | Purpose |
|---|---|
DB_BACKEND_MODE | Database adapter: k8s-postgres-fcm (recommended), firebase-full, or supabase-fcm |
RING_DEPLOY_TARGET | Tunnel and runtime mode: k8s, vercel, or self-hosted |
AUTH_SECRET | Auth.js session encryption (generate with openssl rand -base64 32) |
AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET | Google OAuth credentials |
See Environment configuration for the complete variable reference.
Never commit real secrets to Git. Copy env.local.template to .env.local (gitignored) and fill in production values. On k3s, inject secrets via Kubernetes secrets; on Vercel, use the Vercel dashboard environment variables.
The Dockerfile builds a multi-stage production image with the custom server and native WSS Tunnel. It uses dumb-init as the entrypoint and runs a health check on /api/health.
Build:
Only build-time safe variables (NEXT_PUBLIC_*, DB_BACKEND_MODE) should be passed as build args. Sensitive secrets (AUTH_GOOGLE_SECRET, DB_PASSWORD, WAYFORPAY_SECRET_KEY) are injected at runtime via environment variables or secrets management.
Run:
See Docker deployment for docker-compose configuration and PostGIS setup, and Self-hosted deployment for the community OSS setup with install.sh.
The platform uses a single database abstraction layer via getDatabaseService() (see lib/database/DatabaseService.ts). The active adapter is selected by DB_BACKEND_MODE:
k8s-postgres-fcm — PostgreSQL for all CRUD, Firebase Admin SDK for FCM push only. Recommended for production and local dev.firebase-full — Firestore (Firebase) for all CRUD. Fastest setup for prototyping and Vercel.supabase-fcm — Supabase PostgreSQL for database, Firebase Admin SDK for FCM push only.See Backend modes and databases for a deep comparison.
Firestore client SDK (db.collection(...).doc(...).get()) is not used in this platform. All database access goes through getDatabaseService() with methods findById(collection, id), create(collection, data), update(collection, id, data), delete(collection, id), and query({ collection, filters?, orderBy?, pagination? }).
Clear caches and retry:
Verify AUTH_SECRET is set and consistent across deployments. Auth.js v5 uses AUTH_SECRET (not NEXTAUTH_SECRET). Google OAuth variables are AUTH_GOOGLE_ID and AUTH_GOOGLE_SECRET (not GOOGLE_CLIENT_ID).
Check that PostgreSQL is reachable from the deployment target:
Validate that DB_HOST, DB_PORT, DB_NAME, DB_USER, and DB_PASSWORD match your PostgreSQL configuration.
Verify RING_DEPLOY_TARGET and NEXT_PUBLIC_RING_DEPLOY_TARGET are set. On Vercel, native WebSocket is unavailable — Tunnel falls back to SSE + long-polling automatically. On k3s or Docker, ensure TUNNEL_HUB_MODE=k8s-postgres is set.
# Database
DB_BACKEND_MODE=k8s-postgres-fcm
DB_HOST=postgres.ring-platform-org.svc.cluster.local
DB_PORT=5432
DB_NAME=ring_platform
DB_USER=ring_user
DB_PASSWORD=<from-k8s-secret>
DB_SSL=true
DB_POOL_SIZE=20
DB_TIMEOUT=30000
# Auth.js
AUTH_SECRET=<from-k8s-secret>
AUTH_GOOGLE_ID=<from-k8s-secret>
AUTH_GOOGLE_SECRET=<from-k8s-secret>
# Tunnel
RING_DEPLOY_TARGET=k8s
NEXT_PUBLIC_RING_DEPLOY_TARGET=k8s
TUNNEL_HUB_MODE=k8s-postgres
# Firebase Admin (FCM only — optional)
AUTH_FIREBASE_PROJECT_ID=<your-project-id>
AUTH_FIREBASE_CLIENT_EMAIL=<your-service-account-email>
AUTH_FIREBASE_PRIVATE_KEY="<your-private-key>"
# Payments
WAYFORPAY_MERCHANT_ACCOUNT=<from-k8s-secret>
WAYFORPAY_SECRET_KEY=<from-k8s-secret>
{
"crons": [
{
"path": "/api/cron/cleanup-usernames",
"schedule": "*/5 * * * *"
}
]
}The Dockerfile builds a multi-stage production image with the custom server and native WSS Tunnel. It uses dumb-init as the entrypoint and runs a health check on /api/health.
Build:
Only build-time safe variables (NEXT_PUBLIC_*, DB_BACKEND_MODE) should be passed as build args. Sensitive secrets (AUTH_GOOGLE_SECRET, DB_PASSWORD, WAYFORPAY_SECRET_KEY) are injected at runtime via environment variables or secrets management.
Run:
See Docker deployment for docker-compose configuration and PostGIS setup, and Self-hosted deployment for the community OSS setup with install.sh.
The platform uses a single database abstraction layer via getDatabaseService() (see lib/database/DatabaseService.ts). The active adapter is selected by DB_BACKEND_MODE:
k8s-postgres-fcm — PostgreSQL for all CRUD, Firebase Admin SDK for FCM push only. Recommended for production and local dev.firebase-full — Firestore (Firebase) for all CRUD. Fastest setup for prototyping and Vercel.supabase-fcm — Supabase PostgreSQL for database, Firebase Admin SDK for FCM push only.See Backend modes and databases for a deep comparison.
Firestore client SDK (db.collection(...).doc(...).get()) is not used in this platform. All database access goes through getDatabaseService() with methods findById(collection, id), create(collection, data), update(collection, id, data), delete(collection, id), and query({ collection, filters?, orderBy?, pagination? }).
Clear caches and retry:
Verify AUTH_SECRET is set and consistent across deployments. Auth.js v5 uses AUTH_SECRET (not NEXTAUTH_SECRET). Google OAuth variables are AUTH_GOOGLE_ID and AUTH_GOOGLE_SECRET (not GOOGLE_CLIENT_ID).
Check that PostgreSQL is reachable from the deployment target:
Validate that DB_HOST, DB_PORT, DB_NAME, DB_USER, and DB_PASSWORD match your PostgreSQL configuration.
Verify RING_DEPLOY_TARGET and NEXT_PUBLIC_RING_DEPLOY_TARGET are set. On Vercel, native WebSocket is unavailable — Tunnel falls back to SSE + long-polling automatically. On k3s or Docker, ensure TUNNEL_HUB_MODE=k8s-postgres is set.
# Database
DB_BACKEND_MODE=k8s-postgres-fcm
DB_HOST=postgres.ring-platform-org.svc.cluster.local
DB_PORT=5432
DB_NAME=ring_platform
DB_USER=ring_user
DB_PASSWORD=<from-k8s-secret>
DB_SSL=true
DB_POOL_SIZE=20
DB_TIMEOUT=30000
# Auth.js
AUTH_SECRET=<from-k8s-secret>
AUTH_GOOGLE_ID=<from-k8s-secret>
AUTH_GOOGLE_SECRET=<from-k8s-secret>
# Tunnel
RING_DEPLOY_TARGET=k8s
NEXT_PUBLIC_RING_DEPLOY_TARGET=k8s
TUNNEL_HUB_MODE=k8s-postgres
# Firebase Admin (FCM only — optional)
AUTH_FIREBASE_PROJECT_ID=<your-project-id>
AUTH_FIREBASE_CLIENT_EMAIL=<your-service-account-email>
AUTH_FIREBASE_PRIVATE_KEY="<your-private-key>"
# Payments
WAYFORPAY_MERCHANT_ACCOUNT=<from-k8s-secret>
WAYFORPAY_SECRET_KEY=<from-k8s-secret>
{
"crons": [
{
"path": "/api/cron/cleanup-usernames",
"schedule": "*/5 * * * *"
}
]
}The Dockerfile builds a multi-stage production image with the custom server and native WSS Tunnel. It uses dumb-init as the entrypoint and runs a health check on /api/health.
Build:
Only build-time safe variables (NEXT_PUBLIC_*, DB_BACKEND_MODE) should be passed as build args. Sensitive secrets (AUTH_GOOGLE_SECRET, DB_PASSWORD, WAYFORPAY_SECRET_KEY) are injected at runtime via environment variables or secrets management.
Run:
See Docker deployment for docker-compose configuration and PostGIS setup, and Self-hosted deployment for the community OSS setup with install.sh.
The platform uses a single database abstraction layer via getDatabaseService() (see lib/database/DatabaseService.ts). The active adapter is selected by DB_BACKEND_MODE:
k8s-postgres-fcm — PostgreSQL for all CRUD, Firebase Admin SDK for FCM push only. Recommended for production and local dev.firebase-full — Firestore (Firebase) for all CRUD. Fastest setup for prototyping and Vercel.supabase-fcm — Supabase PostgreSQL for database, Firebase Admin SDK for FCM push only.See Backend modes and databases for a deep comparison.
Firestore client SDK (db.collection(...).doc(...).get()) is not used in this platform. All database access goes through getDatabaseService() with methods findById(collection, id), create(collection, data), update(collection, id, data), delete(collection, id), and query({ collection, filters?, orderBy?, pagination? }).
Clear caches and retry:
Verify AUTH_SECRET is set and consistent across deployments. Auth.js v5 uses AUTH_SECRET (not NEXTAUTH_SECRET). Google OAuth variables are AUTH_GOOGLE_ID and AUTH_GOOGLE_SECRET (not GOOGLE_CLIENT_ID).
Check that PostgreSQL is reachable from the deployment target:
Validate that DB_HOST, DB_PORT, DB_NAME, DB_USER, and DB_PASSWORD match your PostgreSQL configuration.
Verify RING_DEPLOY_TARGET and NEXT_PUBLIC_RING_DEPLOY_TARGET are set. On Vercel, native WebSocket is unavailable — Tunnel falls back to SSE + long-polling automatically. On k3s or Docker, ensure TUNNEL_HUB_MODE=k8s-postgres is set.
# Database
DB_BACKEND_MODE=k8s-postgres-fcm
DB_HOST=postgres.ring-platform-org.svc.cluster.local
DB_PORT=5432
DB_NAME=ring_platform
DB_USER=ring_user
DB_PASSWORD=<from-k8s-secret>
DB_SSL=true
DB_POOL_SIZE=20
DB_TIMEOUT=30000
# Auth.js
AUTH_SECRET=<from-k8s-secret>
AUTH_GOOGLE_ID=<from-k8s-secret>
AUTH_GOOGLE_SECRET=<from-k8s-secret>
# Tunnel
RING_DEPLOY_TARGET=k8s
NEXT_PUBLIC_RING_DEPLOY_TARGET=k8s
TUNNEL_HUB_MODE=k8s-postgres
# Firebase Admin (FCM only — optional)
AUTH_FIREBASE_PROJECT_ID=<your-project-id>
AUTH_FIREBASE_CLIENT_EMAIL=<your-service-account-email>
AUTH_FIREBASE_PRIVATE_KEY="<your-private-key>"
# Payments
WAYFORPAY_MERCHANT_ACCOUNT=<from-k8s-secret>
WAYFORPAY_SECRET_KEY=<from-k8s-secret>
{
"crons": [
{
"path": "/api/cron/cleanup-usernames",
"schedule": "*/5 * * * *"
}
]
}
docker build \
--platform linux/amd64 \
--build-arg AUTH_SECRET="your-auth-secret" \
--build-arg DB_BACKEND_MODE=k8s-postgres-fcm \
--build-arg DB_HOST=postgres.example.com \
--build-arg DB_PORT=5432 \
--build-arg DB_NAME=ring_platform \
--build-arg DB_USER=ring_user \
--build-arg NEXT_PUBLIC_APP_URL=https://your-domain.com \
--build-arg NEXT_PUBLIC_API_URL=https://your-domain.com \
-t ring-platform .
docker run -d \
-p 3000:3000 \
-e AUTH_SECRET=<from-secret-store> \
-e AUTH_GOOGLE_ID=<from-secret-store> \
-e AUTH_GOOGLE_SECRET=<from-secret-store> \
-e DB_BACKEND_MODE=k8s-postgres-fcm \
-e DB_HOST=postgres.example.com \
-e DB_PORT=5432 \
-e DB_NAME=ring_platform \
-e DB_USER=ring_user \
-e DB_PASSWORD=<from-secret-store> \
-e DB_SSL=true \
-e RING_DEPLOY_TARGET=self-hosted \
-e NEXT_PUBLIC_RING_DEPLOY_TARGET=self-hosted \
ring-platform
# Verify database connection (any mode)
# Uses getDatabaseService() — NOT a Firebase client SDK
# lib/firebase.ts does not exist in this codebase
rm -rf .next node_modules
npm install
npm run type-check
npm run build
# From k3s pod
kubectl exec deploy/ring-platform -- wget -qO- http://postgres:5432
# From Docker
docker exec ring-platform nc -zv postgres.example.com 5432
docker build \
--platform linux/amd64 \
--build-arg AUTH_SECRET="your-auth-secret" \
--build-arg DB_BACKEND_MODE=k8s-postgres-fcm \
--build-arg DB_HOST=postgres.example.com \
--build-arg DB_PORT=5432 \
--build-arg DB_NAME=ring_platform \
--build-arg DB_USER=ring_user \
--build-arg NEXT_PUBLIC_APP_URL=https://your-domain.com \
--build-arg NEXT_PUBLIC_API_URL=https://your-domain.com \
-t ring-platform .
docker run -d \
-p 3000:3000 \
-e AUTH_SECRET=<from-secret-store> \
-e AUTH_GOOGLE_ID=<from-secret-store> \
-e AUTH_GOOGLE_SECRET=<from-secret-store> \
-e DB_BACKEND_MODE=k8s-postgres-fcm \
-e DB_HOST=postgres.example.com \
-e DB_PORT=5432 \
-e DB_NAME=ring_platform \
-e DB_USER=ring_user \
-e DB_PASSWORD=<from-secret-store> \
-e DB_SSL=true \
-e RING_DEPLOY_TARGET=self-hosted \
-e NEXT_PUBLIC_RING_DEPLOY_TARGET=self-hosted \
ring-platform
# Verify database connection (any mode)
# Uses getDatabaseService() — NOT a Firebase client SDK
# lib/firebase.ts does not exist in this codebase
rm -rf .next node_modules
npm install
npm run type-check
npm run build
# From k3s pod
kubectl exec deploy/ring-platform -- wget -qO- http://postgres:5432
# From Docker
docker exec ring-platform nc -zv postgres.example.com 5432
docker build \
--platform linux/amd64 \
--build-arg AUTH_SECRET="your-auth-secret" \
--build-arg DB_BACKEND_MODE=k8s-postgres-fcm \
--build-arg DB_HOST=postgres.example.com \
--build-arg DB_PORT=5432 \
--build-arg DB_NAME=ring_platform \
--build-arg DB_USER=ring_user \
--build-arg NEXT_PUBLIC_APP_URL=https://your-domain.com \
--build-arg NEXT_PUBLIC_API_URL=https://your-domain.com \
-t ring-platform .
docker run -d \
-p 3000:3000 \
-e AUTH_SECRET=<from-secret-store> \
-e AUTH_GOOGLE_ID=<from-secret-store> \
-e AUTH_GOOGLE_SECRET=<from-secret-store> \
-e DB_BACKEND_MODE=k8s-postgres-fcm \
-e DB_HOST=postgres.example.com \
-e DB_PORT=5432 \
-e DB_NAME=ring_platform \
-e DB_USER=ring_user \
-e DB_PASSWORD=<from-secret-store> \
-e DB_SSL=true \
-e RING_DEPLOY_TARGET=self-hosted \
-e NEXT_PUBLIC_RING_DEPLOY_TARGET=self-hosted \
ring-platform
# Verify database connection (any mode)
# Uses getDatabaseService() — NOT a Firebase client SDK
# lib/firebase.ts does not exist in this codebase
rm -rf .next node_modules
npm install
npm run type-check
npm run build
# From k3s pod
kubectl exec deploy/ring-platform -- wget -qO- http://postgres:5432
# From Docker
docker exec ring-platform nc -zv postgres.example.com 5432