Deployment (WIP)
This guide covers deploying quickslice on Fly.io and Railway. Both platforms support Docker deployments with persistent volumes for SQLite.
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
DATABASE_URL |
No | quickslice.db |
Path to SQLite database file. Use /data/quickslice.db with volume mount |
HOST |
No | 127.0.0.1 |
Server bind address. Set to 0.0.0.0 for containers |
PORT |
No | 8080 |
Server port |
SECRET_KEY_BASE |
Recommended | Auto-generated | Session encryption key (64+ chars). Must persist across restarts |
EXTERNAL_BASE_URL |
Optional | http://localhost:8080 |
Base URL of your application (used for OAuth redirect URIs and client metadata). Use http://127.0.0.1:8080 for loopback mode |
OAUTH_LOOPBACK_MODE |
Optional | false |
Set to true for local development without ngrok. Uses loopback client IDs instead of client metadata URLs |
PLC_DIRECTORY_URL |
Optional | https://plc.directory |
PLC directory URL override (useful for self-hosted PLC directories) |
Critical Environment Variables
- DATABASE_URL: Must point to a persistent volume location
- SECRET_KEY_BASE: Generate with
openssl rand -base64 48. Store as a secret and keep persistent - HOST: Set to
0.0.0.0in container environments
SQLite Volume Setup
SQLite requires persistent storage for three files:
{DATABASE_URL}- Main database file{DATABASE_URL}-shm- Shared memory file{DATABASE_URL}-wal- Write-ahead log
IMPORTANT: Without persistent storage, all data will be lost on container restart.
Fly.io
1. Create a volume
fly volumes create app_data --size 10
2. Configure fly.toml
Create fly.toml in your project root:
app = 'your-app-name'
primary_region = 'sjc'
[build]
dockerfile = "Dockerfile"
[env]
DATABASE_URL = '/data/quickslice.db'
HOST = '0.0.0.0'
PORT = '8080'
[http_service]
internal_port = 8080
force_https = true
auto_stop_machines = 'stop'
auto_start_machines = true
min_machines_running = 1
[[mounts]]
source = 'app_data'
destination = '/data'
[[vm]]
memory = '1gb'
cpu_kind = 'shared'
cpus = 1
3. Set secrets
fly secrets set SECRET_KEY_BASE=$(openssl rand -base64 48)
4. Deploy
fly deploy
5. Verify health
fly status
curl https://your-app.fly.dev/health
Railway
1. Create a new project
Connect your GitHub repository or deploy from the CLI.
2. Configure environment variables
In the Railway dashboard, add these variables:
DATABASE_URL=/data/quickslice.db
HOST=0.0.0.0
PORT=8080
SECRET_KEY_BASE=<generate-with-openssl-rand>
3. Add a volume
In the Railway dashboard:
- Go to your service settings
- Add a volume mount
- Mount path:
/data - Size: 10GB (or as needed)
4. Configure health check
In the service settings, set the health check path to /health.
5. Deploy
Railway will automatically deploy when you push to your connected branch.
Optional: railway.json
Create railway.json for declarative configuration:
{
"$schema": "https://railway.app/railway.schema.json",
"build": {
"builder": "DOCKERFILE",
"dockerfilePath": "Dockerfile"
},
"deploy": {
"numReplicas": 1,
"restartPolicyType": "ON_FAILURE",
"restartPolicyMaxRetries": 10,
"healthcheckPath": "/health",
"healthcheckTimeout": 100
}
}
Docker Compose (Self-Hosted)
For self-hosted deployments, use the published Docker image:
version: "3.8"
services:
quickslice:
image: ghcr.io/bigmoves/quickslice:latest
ports:
- "8080:8080"
volumes:
- quickslice-data:/data
- ./lexicons:/app/priv/lexicons:ro # Optional: custom lexicons
environment:
- HOST=0.0.0.0
- PORT=8080
- DATABASE_URL=/data/quickslice.db
- SECRET_KEY_BASE=${SECRET_KEY_BASE}
restart: unless-stopped
healthcheck:
test: ["CMD", "wget", "--spider", "-q", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
volumes:
quickslice-data:
Create a .env file for secrets:
SECRET_KEY_BASE=<generate-with-openssl-rand>
Start the service:
docker compose up -d
Post-Deployment
Health check
Verify the service is running:
curl https://your-app-url/health
Expected response:
{"status":"healthy"}
Access GraphiQL
Navigate to /graphiql (requires authentication).
Database access
Fly.io:
fly ssh console
sqlite3 /data/quickslice.db
Railway: Use the Railway CLI or connect via SSH from the dashboard.
Docker:
docker exec -it <container-name> sqlite3 /data/quickslice.db
Logs
Fly.io:
fly logs
Railway:
View logs in the dashboard or use railway logs.
Docker:
docker compose logs -f quickslice
Backfill Configuration
Control memory usage during backfill operations with these environment variables:
| Variable | Default | Description |
|---|---|---|
BACKFILL_MAX_PDS_WORKERS |
10 | Max concurrent PDS endpoints being processed |
BACKFILL_PDS_CONCURRENCY |
4 | Max concurrent repo fetches per PDS |
BACKFILL_MAX_HTTP_CONCURRENT |
50 | Global HTTP request limit |
BACKFILL_REPO_TIMEOUT |
60 | Timeout per repo fetch (seconds) |
Recommended Settings by VPS Size
1GB RAM (e.g., Railway starter):
BACKFILL_MAX_PDS_WORKERS=8
BACKFILL_PDS_CONCURRENCY=2
BACKFILL_MAX_HTTP_CONCURRENT=30
2GB RAM:
BACKFILL_MAX_PDS_WORKERS=15
BACKFILL_PDS_CONCURRENCY=4
BACKFILL_MAX_HTTP_CONCURRENT=50
4GB+ RAM:
BACKFILL_MAX_PDS_WORKERS=25
BACKFILL_PDS_CONCURRENCY=6
BACKFILL_MAX_HTTP_CONCURRENT=100
Resource Requirements
Minimum:
- Memory: 1GB
- CPU: 1 shared core
- Disk: 10GB volume (for SQLite database)
Recommendations:
- Scale memory for high-traffic deployments
- Use SSD-backed volumes for SQLite performance
- Monitor database size and scale volume as needed