P
Parsyn
/Docs
Back to Home

Self-Hosting & Deployment

For teams that want to run the full Parsyn platform on their own infrastructure. Covers Docker Compose setup, environment configuration, reverse proxy, and production hardening.

Self-hosting is optional. Most users use the hosted platform at parsyn.progatis.com and connect their own workers to it. This guide is for organizations that need to run the entire platform in-house, typically for data sovereignty, compliance, or air-gapped environments.

What you're deploying

ServicePurposePort
Backend APIFastAPI application + WebSocket server8000
PostgreSQL 16Primary database (metadata, users, metrics)5432
Redis 7Sessions, rate limiting, Celery broker6379
MinIOS3-compatible object storage (datasets, models, checkpoints)9000 / 9001
Celery workerAsync tasks (statistics, preprocessing, notifications)N/A
FrontendVue.js dashboard (served by nginx)80

Workers run on separate GPU machines and connect to the backend via WebSocket. They are not part of the Docker Compose stack.

Prerequisites

  • Docker Engine 24+ and Docker Compose v2
  • A server with at least 4 CPU cores and 8 GB RAM
  • 50 GB+ disk space (more for datasets and model storage)
  • A domain name pointed to your server (for HTTPS)

Setup

git clone https://github.com/Progatis/parsyn.git
cd parsyn
cp .env.example .env

Edit .env with your configuration (see below), then:

# Development (with MinIO for local S3)
docker compose up -d

# Production (with Traefik routing)
docker compose -f docker-compose.prod.yml up -d

Verify:

curl https://your-domain.com/health
# {"status": "ok"}

Environment variables

Database

VariableExampleDescription
DATABASE_URLpostgresql+asyncpg://parsyn:secret@db:5432/parsynAsync PostgreSQL connection string.
DB_POOL_SIZE20Connection pool size.

Redis

VariableExample
REDIS_URLredis://redis:6379/0

Object storage

VariableExampleDescription
S3_ENDPOINThttp://minio:9000S3 endpoint. Use https://s3.amazonaws.com for AWS.
S3_BUCKETparsyn-storageBucket for datasets, models, checkpoints.
S3_ACCESS_KEYminioadminS3 access key.
S3_SECRET_KEYminioadminS3 secret key.

Authentication

VariableDescription
JWT_SECRETSecret key for JWT signing. Generate with openssl rand -hex 32. Must be strong in production.
JWT_ALGORITHMSigning algorithm. Default: HS256.

Always generate a random JWT_SECRET for production. If compromised, attackers can forge authentication tokens for any user.

Platform settings

VariableDefaultDescription
ENVIRONMENTdevelopmentSet to production for production. Affects CORS and debug mode.
CORS_ORIGINSComma-separated allowed origins (e.g., https://app.yourdomain.com).
WORKER_HEARTBEAT_TIMEOUT90Seconds before a worker is marked offline.
MAX_CONCURRENT_TRAININGS10Maximum simultaneous training jobs.
MAX_UPLOAD_SIZE_BYTES10737418240Maximum file upload size (10 GB).

Notifications (optional)

ServiceVariables
EmailSMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASSWORD
SlackSLACK_WEBHOOK_URL
TelegramTELEGRAM_BOT_TOKEN
TeamsTEAMS_WEBHOOK_URL
SMSTWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, TWILIO_FROM_NUMBER

Billing (optional)

VariableDescription
STRIPE_SECRET_KEYStripe API key.
STRIPE_WEBHOOK_SECRETStripe webhook signing secret.
STRIPE_SUCCESS_URLRedirect after successful payment.
STRIPE_CANCEL_URLRedirect after cancelled payment.

Reverse proxy (Traefik)

The production Docker Compose file includes Traefik labels for automatic HTTPS and routing. Each exposed service needs the traefik.docker.network label to prevent random connectivity issues.

When a container is on multiple Docker networks, Traefik can pick the wrong internal IP. This causes intermittent 502 errors after deploys. Always set traefik.docker.network explicitly on every exposed service.

# docker-compose.prod.yml (relevant labels)
services:
  backend:
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.parsyn-api.rule=Host(`api.yourdomain.com`)"
      - "traefik.http.routers.parsyn-api.tls.certresolver=letsencrypt"
      - "traefik.http.services.parsyn-api.loadbalancer.server.port=8000"
      - "traefik.docker.network=${PROXY_NETWORK:-coolify}"

Set PROXY_NETWORK to match your Traefik network. Common values: coolify (Coolify PaaS), dokploy-network (Dokploy), traefik or proxy (standalone).

Connecting workers to your instance

Workers connect to your self-hosted platform instead of parsyn.progatis.com:

PLATFORM_URL=wss://api.yourdomain.com/ws/worker
WORKER_ENROLLMENT_KEY=enroll_xyz789...

Database management

The backend runs Alembic migrations automatically on startup. For manual migration:

# Apply pending migrations
docker compose exec backend alembic upgrade head

# Generate migration after model changes
docker compose exec backend alembic revision --autogenerate -m "add preferences table"

# Rollback one migration
docker compose exec backend alembic downgrade -1

Backups

PostgreSQL

# Dump
docker compose exec db pg_dump -U parsyn parsyn > backup_$(date +%Y%m%d).sql

# Restore
cat backup.sql | docker compose exec -T db psql -U parsyn parsyn

Object storage

If using MinIO, back up its data directory. With AWS S3, enable versioning and cross-region replication.

Monitoring

Health checks

# Backend
curl https://api.yourdomain.com/health

# Detailed (database, redis, S3)
curl https://api.yourdomain.com/api/health

Logs

docker compose logs -f backend
docker compose logs --tail 100 celery

The backend outputs structured JSON logs. Pipe them to your log aggregation system (ELK, Loki, Datadog).

Key metrics to watch

  • Active workers: Alert if zero for more than 5 minutes.
  • Stuck jobs: running with no progress for 30+ minutes.
  • API latency: p95 should stay under 500ms.
  • Database pool: Alert at 80% of DB_POOL_SIZE.
  • Disk space: Alert at 80% on MinIO volume and PostgreSQL data.

Production security checklist

  • Generate a strong JWT_SECRET (at least 256 bits).
  • Change MinIO default credentials.
  • Set ENVIRONMENT=production.
  • Use HTTPS for all public endpoints (Traefik + Let's Encrypt).
  • Don't expose database (5432) or Redis (6379) ports publicly.
  • Enable 2FA for admin accounts.
  • Set up regular database backups.
  • Rotate worker API keys periodically.
  • Set TRUST_REMOTE_CODE=false on workers.