Stateless Docker Compose
This Docker Compose configuration runs only the application containers (frontend, backend, publisher) and connects to external managed services for PostgreSQL, Redis, and S3-compatible storage. This is the recommended setup for:
- Production environments
- High-availability deployments
- Kubernetes or container orchestration platforms
- Environments with managed database services (AWS RDS, DigitalOcean, Neon, etc.)
When to Use This Configuration
Section titled “When to Use This Configuration”Use this configuration when:
- You have access to managed PostgreSQL, Redis, and S3 storage services
- You need horizontal scaling (multiple backend/publisher instances)
- You want to separate compute from storage
- You’re deploying in a high-availability environment
For simpler deployments or local installations, consider using the Stateful Docker Compose configuration instead.
Configuration File
Section titled “Configuration File”# Production Docker Compose - Uses pre-built images from GHCR# Usage: docker compose -f docker-compose.prod.yml up -d## Requires external services:# - PostgreSQL database# - Redis instance# - S3-compatible storage (AWS S3, Cloudflare R2, etc.)
services: backend: image: ghcr.io/isekai-sh/isekai-backend:${IMAGE_TAG:-latest} container_name: isekai-backend ports: - "${BACKEND_PORT:-4000}:4000" environment: # Database & Cache (Must be set in .env) DATABASE_URL: ${DATABASE_URL} REDIS_URL: ${REDIS_URL}
# Application Config FRONTEND_URL: ${FRONTEND_URL:-http://localhost:3000} PORT: 4000 NODE_ENV: production
# Security SESSION_SECRET: ${SESSION_SECRET} ENCRYPTION_KEY: ${ENCRYPTION_KEY} COOKIE_DOMAIN: ${COOKIE_DOMAIN:-} SESSION_MAX_AGE_DAYS: ${SESSION_MAX_AGE_DAYS:-7} REFRESH_TOKEN_EXPIRY_DAYS: ${REFRESH_TOKEN_EXPIRY_DAYS:-90}
# DeviantArt OAuth DEVIANTART_CLIENT_ID: ${DEVIANTART_CLIENT_ID} DEVIANTART_CLIENT_SECRET: ${DEVIANTART_CLIENT_SECRET} DEVIANTART_REDIRECT_URI: ${DEVIANTART_REDIRECT_URI}
# S3-Compatible Storage S3_ENDPOINT: ${S3_ENDPOINT} S3_REGION: ${S3_REGION:-us-east-1} S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID} S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY} S3_BUCKET_NAME: ${S3_BUCKET_NAME:-isekai-uploads} S3_PUBLIC_URL: ${S3_PUBLIC_URL} S3_FORCE_PATH_STYLE: ${S3_FORCE_PATH_STYLE:-false}
SESSION_STORE: ${SESSION_STORE:-redis} env_file: - .env restart: always networks: - isekai-network healthcheck: test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:4000/api/health", ] interval: 30s timeout: 10s retries: 3 start_period: 40s
publisher: image: ghcr.io/isekai-sh/isekai-publisher:${IMAGE_TAG:-latest} container_name: isekai-publisher ports: - "${PUBLISHER_HEALTH_PORT:-8000}:8000" environment: DATABASE_URL: ${DATABASE_URL} REDIS_URL: ${REDIS_URL} NODE_ENV: production
DEVIANTART_CLIENT_ID: ${DEVIANTART_CLIENT_ID} DEVIANTART_CLIENT_SECRET: ${DEVIANTART_CLIENT_SECRET}
# S3-Compatible Storage S3_ENDPOINT: ${S3_ENDPOINT} S3_REGION: ${S3_REGION:-us-east-1} S3_ACCESS_KEY_ID: ${S3_ACCESS_KEY_ID} S3_SECRET_ACCESS_KEY: ${S3_SECRET_ACCESS_KEY} S3_BUCKET_NAME: ${S3_BUCKET_NAME:-isekai-uploads} S3_PUBLIC_URL: ${S3_PUBLIC_URL} S3_FORCE_PATH_STYLE: ${S3_FORCE_PATH_STYLE:-false}
# Publisher Tuning PUBLISHER_CONCURRENCY: ${PUBLISHER_CONCURRENCY:-5} PUBLISHER_MAX_ATTEMPTS: ${PUBLISHER_MAX_ATTEMPTS:-7} PUBLISHER_JOB_TIMEOUT_MS: ${PUBLISHER_JOB_TIMEOUT_MS:-600000}
HEALTH_CHECK_PORT: 8000 HEALTH_CHECK_ENABLED: true env_file: - .env restart: always networks: - isekai-network healthcheck: test: [ "CMD-SHELL", "wget --no-verbose --tries=1 --spider http://localhost:8000/health || exit 1", ] interval: 30s timeout: 10s retries: 3 start_period: 40s
frontend: image: ghcr.io/isekai-sh/isekai-frontend:${IMAGE_TAG:-latest} container_name: isekai-frontend ports: - "${FRONTEND_PORT:-3000}:80" environment: VITE_API_URL: ${VITE_API_URL} VITE_DEVIANTART_CLIENT_ID: ${DEVIANTART_CLIENT_ID} VITE_S3_PUBLIC_URL: ${S3_PUBLIC_URL} env_file: - .env depends_on: - backend restart: always networks: - isekai-network healthcheck: test: [ "CMD", "wget", "--no-verbose", "--tries=1", "--spider", "http://localhost:80/", ] interval: 30s timeout: 10s retries: 3
networks: isekai-network: driver: bridgeService Breakdown
Section titled “Service Breakdown”Backend (backend)
Section titled “Backend (backend)”- Image:
ghcr.io/isekai-sh/isekai-backend - Purpose: API server, authentication, and job scheduling
- External Dependencies: Managed PostgreSQL, Redis, and S3 storage
- Port: 4000 (configurable via
BACKEND_PORT)
Publisher (publisher)
Section titled “Publisher (publisher)”- Image:
ghcr.io/isekai-sh/isekai-publisher - Purpose: Background worker for publishing to DeviantArt
- External Dependencies: Managed PostgreSQL, Redis, and S3 storage
- Port: 8000 (health check endpoint)
- Scaling: Can run multiple instances for higher throughput
Frontend (frontend)
Section titled “Frontend (frontend)”- Image:
ghcr.io/isekai-sh/isekai-frontend - Purpose: User interface (React SPA)
- Dependencies: Backend API
- Port: 80 internally, mapped to 3000 externally (configurable via
FRONTEND_PORT)
Required Environment Variables
Section titled “Required Environment Variables”Since this configuration uses external services, you must provide connection strings in your .env file:
# External Database (REQUIRED)DATABASE_URL="postgresql://user:password@your-db-host:5432/isekai?sslmode=require"
# External Redis (REQUIRED)REDIS_URL="rediss://default:password@your-redis-host:6379"
# S3-Compatible Storage (REQUIRED)# See Storage Setup guide for provider-specific valuesS3_ENDPOINT=https://your-storage-endpointS3_REGION=us-east-1S3_ACCESS_KEY_ID=your-access-keyS3_SECRET_ACCESS_KEY=your-secret-keyS3_BUCKET_NAME=isekai-uploadsS3_PUBLIC_URL=https://your-public-url
# All other variables from the Environment Variables reference# ...See the Storage Setup guide for provider-specific S3 configuration (Cloudflare R2, AWS S3, DigitalOcean Spaces, etc.).
Scaling Strategy
Section titled “Scaling Strategy”This configuration makes it easy to scale your deployment:
Horizontal Scaling
Section titled “Horizontal Scaling”- Backend: Scale to multiple instances behind a load balancer
- Publisher: Scale to process more jobs concurrently
- Frontend: Scale for high traffic (served via CDN recommended)
Example with Docker Compose
Section titled “Example with Docker Compose”# Scale publisher to 3 instancesdocker compose up -d --scale publisher=3