Deployment

This guide covers production deployment of PicFast with Docker Compose, reverse proxy, and production-grade configuration.

Docker Compose (recommended)

For a full production stack with PostgreSQL, PicFast, and Traefik reverse proxy in a single compose file:

cd docker
cp .env.traefik.example .env
# Edit .env with your domain, secrets, and credentials
docker compose -f docker-compose.traefik.yml up -d

On first startup, the setup wizard runs in your browser to create your first admin account. Set PICFAST_APP_ADMIN_EMAIL and PICFAST_APP_ADMIN_PASSWORD to auto-create the admin and skip the wizard for headless deployments.

The Traefik compose file includes:

  • PostgreSQL 16 with persistent volume
  • PicFast application with automatic Let's Encrypt SSL via Traefik
  • Traefik configured as the reverse proxy with auto-renewing certificates

Docker Hub image

Prebuilt images are published to Docker Hub at xbeta/picfast. This is the recommended way to deploy — no cloning, no building.

Quick test with docker run

docker network create picfast-net

docker run -d --name picfast-db --network picfast-net \
  -e POSTGRES_PASSWORD=devonly \
  -v picfast-pgdata:/var/lib/postgresql/data \
  postgres:16-alpine

docker run -d --name picfast --network picfast-net -p 18080:8080 \
  -e PICFAST_DATABASE_URL='postgres://postgres:devonly@picfast-db:5432/postgres?sslmode=disable' \
  -e PICFAST_JWT_SECRET='change-me-in-production' \
  -e PICFAST_SERVER_BASE_URL='http://localhost:18080' \
  -v picfast-uploads:/app/data/uploads \
  -v picfast-thumbnails:/app/data/thumbnails \
  xbeta/picfast:latest

Available tags:

  • latest — latest stable build from main
  • vX.Y.Z — specific release version
  • sha-<commit> — commit-traceable build

Pre-flight checklist

Before going to production, verify these settings:

  • PICFAST_JWT_SECRET — strong random value (use openssl rand -hex 32)
  • PICFAST_SERVER_BASE_URL — your actual HTTPS domain
  • PICFAST_APP_ADMIN_EMAIL / PICFAST_APP_ADMIN_PASSWORD — set for headless deployments
  • POSTGRES_PASSWORD — don't use example passwords
  • Reverse proxy correctly passes Host and X-Forwarded-Proto headers
  • Upload size limits in reverse proxy match your requirements

Environment variables

All config keys can be set via PICFAST_ prefixed environment variables. Environment variables take precedence over config.yaml values. Full reference: Configuration.

PICFAST_SERVER_PORT=8080
PICFAST_SERVER_BASE_URL=https://pics.example.com
PICFAST_JWT_SECRET=your-strong-secret
PICFAST_DATABASE_URL=postgres://picfast:picfast@localhost:5432/picfast?sslmode=disable
PICFAST_STORAGE_LOCAL_ROOT=./data/uploads
PICFAST_STORAGE_THUMBNAIL_DIR=./data/thumbnails

Reverse proxy

Nginx

server {
    listen 443 ssl;
    server_name pics.example.com;

    ssl_certificate /etc/ssl/certs/pics.crt;
    ssl_certificate_key /etc/ssl/private/pics.key;

    client_max_body_size 100M;

    location / {
        proxy_pass http://127.0.0.1:18080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Caddy

pics.example.com {
    reverse_proxy 127.0.0.1:18080
    request_body {
        max_size 100MB
    }
}

Traefik

Add these labels to your Docker Compose service:

labels:
  - "traefik.enable=true"
  - "traefik.http.routers.picfast.rule=Host`pics.example.com`"
  - "traefik.http.routers.picfast.tls=true"
  - "traefik.http.services.picfast.loadbalancer.server.port=8080"

Database backup

docker exec picfast-db pg_dump -U picfast picfast > backup.sql

Updating

When using the Docker Hub image:

docker pull xbeta/picfast:latest
docker stop picfast && docker rm picfast
# Re-run your docker run command with the same volumes

When using docker-compose:

docker compose pull
docker compose up -d

Database migrations run automatically on startup.

Home network & NAS

For deploying on home hardware like Synology, QNAP, or Raspberry Pi — with tunnels (Cloudflare, Tailscale, FRP) to expose your instance to the internet — see Home Network & NAS.

Development deployment

For building from source (requires Go 1.26+, Node 20+, pnpm):

git clone https://github.com/atbeta/picfast.git
cd picfast
make docker-up          # PostgreSQL + Mailpit
cp .env.example .env
go run ./cmd/picfast    # backend
cd web && pnpm install && pnpm dev  # frontend

For more development details, see the development section of the GitHub README.