Skip to content

Deployment Guide

Environment Variables

Copy .env.example to .env and configure.

Required

Variable Description
DATABASE_URL PostgreSQL connection string
JWT_SECRET HMAC-SHA256 signing key (access tokens)
JWT_REFRESH_SECRET HMAC-SHA256 signing key (refresh tokens)
S3_ACCESS_KEY / S3_SECRET_KEY MinIO credentials
INITIAL_ADMIN_EMAIL / INITIAL_ADMIN_PASSWORD First admin account (created on first run if no users exist)

Optional

Variable Default Description
BIND_ADDR 127.0.0.1:3000 Listen address
DATABASE_MAX_CONNECTIONS 20 Connection pool size
JWT_ACCESS_TTL_SECS 900 (15min) Access token lifetime
JWT_REFRESH_TTL_SECS 604800 (7d) Refresh token lifetime
S3_ENDPOINT -- S3/MinIO endpoint URL
S3_BUCKET -- Storage bucket name
S3_REGION -- S3 region
S3_PATH_STYLE -- Use path-style addressing
TRANSCODE_CONCURRENCY -- Max concurrent transcode jobs
TRANSCODE_DEFAULT_FORMAT -- Default output format
TRANSCODE_DEFAULT_BITRATE -- Default output bitrate
TRANSCODE_STALE_TIMEOUT_SECS 7200 Reap orphaned transcode jobs after this many seconds
UPLOAD_MAX_SIZE 104857600 (100MB) Max upload size in bytes
STATIC_DIR ./frontend/dist Frontend dist path

RBAC

Role Scope Permissions
super_admin Global Full access to all facilities, users, and system config
facility_admin Facility Manages own facility's data and users
user Facility Read-only access to own facility's data

Database Migrations

Migrations run automatically on startup via sqlx::migrate!() in xylolabs-db.

Migration files: crates/xylolabs-db/migrations/

Docker

# Full stack (production)
docker compose up

# Development mode
docker compose -f docker-compose.dev.yml up

# Test infrastructure
docker compose -f docker-compose.test.yml up -d

Production Deployment

Server

  • Host: api.xylolabs.com (Oracle Cloud Infrastructure)
  • OS: Ubuntu 24.04 LTS
  • User: ubuntu
  • SSH Key: ~/.ssh/xylolabs-prod.pem
  • SSH: ssh -i ~/.ssh/xylolabs-prod.pem ubuntu@api.xylolabs.com

Domains

Domain Purpose Port
api.xylolabs.com API endpoints 3000 (proxied via nginx)
admin.api.xylolabs.com Admin dashboard 3000 (proxied via nginx, serves static + API)

Infrastructure

  • Reverse proxy: nginx with Let's Encrypt (certbot)
  • App: Docker Compose (app + postgres + minio)
  • SSL: Auto-renewed via certbot timer

Deploy

./scripts/deploy.sh

Docker Commands on Server

cd /opt/xylolabs-api
docker compose up -d          # Start services
docker compose logs -f app    # View logs
docker compose restart app    # Restart app
docker compose down           # Stop all