Deployment

PicFast provides several deployment paths. For most users, Docker Compose with a reverse proxy is the best balance of simplicity and production readiness.

Docker Compose (recommended)

Download the compose file and environment template, no cloning needed:

mkdir picfast && cd picfast
wget https://raw.githubusercontent.com/atbeta/picfast/main/docker/docker-compose.yml
wget https://raw.githubusercontent.com/atbeta/picfast/main/docker/.env.example -O .env

Edit .env with your domain, secrets, and configuration, then:

docker compose up -d

The compose file includes PostgreSQL 16 and PicFast. By default PicFast binds to 127.0.0.1:18080 — put a reverse proxy (Nginx, Caddy, NPM) in front for HTTPS. Set PICFAST_HTTP_BIND=0.0.0.0 in .env to bind to all interfaces.

On first startup, open your site and follow the setup wizard. Set PICFAST_APP_ADMIN_EMAIL and PICFAST_APP_ADMIN_PASSWORD in .env to auto-create the admin and skip the wizard.

Data is stored under the current directory:

  • Postgres: ./data/postgres
  • Uploads: ./data/uploads
  • Thumbnails: ./data/thumbnails

Traefik (auto-SSL)

If you already run a Traefik instance with pre-configured TLS certificates, use this variant:

mkdir picfast && cd picfast
wget https://raw.githubusercontent.com/atbeta/picfast/main/docker/docker-compose.traefik.yml
wget https://raw.githubusercontent.com/atbeta/picfast/main/docker/.env.traefik.example -O .env

vim .env  # set domain, database password, JWT secret
docker compose -f docker-compose.traefik.yml up -d

Make sure TRAEFIK_DOCKER_NETWORK in .env matches your Traefik's network.

Docker Hub image (docker run)

Prebuilt images are on Docker Hub. Useful for quick testing or custom setups:

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

See Docker Hub for available tags.

Pre-flight checklist

  • JWT secret: set to a strong random value (openssl rand -hex 32)
  • Server base URL: your actual HTTPS domain
  • Admin credentials: set for headless deployments, or use the setup wizard
  • Database password: don't use example values in production
  • Reverse proxy passes Host and X-Forwarded-Proto headers
  • Upload size limits in reverse proxy match your needs (default 50 MB per file)

Environment variables

All configuration can be set via PICFAST_ prefixed environment variables (they take precedence over config.yaml). See Configuration for the full reference.

PICFAST_SERVER_PORT=8080
PICFAST_SERVER_BASE_URL=https://picfast.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 picfast.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

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

Observability (Prometheus)

PicFast exposes Prometheus metrics on a dedicated internal port (:9190). In Docker Compose, this port is not published to the host — Prometheus scrapes it within the Docker network:

scrape_configs:
  - job_name: picfast
    metrics_path: /metrics
    static_configs:
      - targets: ["app:9190"]

The /health endpoint returns 200 when the database and storage are reachable. Metrics include HTTP request counts, upload throughput, database pool stats, and more.

Backup & maintenance

For full-instance archives (database + optional objects), checksum verification, restore preflight, and consistency checks, use the built‑in picfast maintenance CLI — see Backup & Maintenance.

Quick SQL‑only dump from Postgres (example; container and DB names vary):

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

Updating

docker compose pull
docker compose up -d

Migrations run automatically on startup.

Home network & NAS

For Synology, QNAP, TrueNAS, Unraid, or Raspberry Pi — with Cloudflare/Tailscale/FRP tunnels — see Home Network & NAS.