How to Self-Host Pretix with Docker Compose

What Is Pretix?

Pretix is an open-source event ticketing platform built with Python and Django. It handles ticket sales, seating charts, check-in management, and payment processing for events of any size — from local meetups to multi-day conferences. It replaces Eventbrite, Tito, and similar SaaS ticketing platforms, giving you full control over your ticket sales, attendee data, and branding without per-ticket fees.

Updated February 2026: Verified with latest Docker images and configurations.

The project is maintained by rami.io GmbH and has been in active development since 2014.

Prerequisites

  • A Linux server (Ubuntu 22.04+ recommended)
  • Docker and Docker Compose installed (guide)
  • 2 GB of free RAM (minimum)
  • 10 GB of free disk space
  • A domain name with SSL (required for payment processing)
  • SMTP credentials for sending email (ticket confirmations, order receipts)

Docker Compose Configuration

Create a project directory:

mkdir -p /opt/pretix && cd /opt/pretix

Create a pretix.cfg configuration file:

[pretix]
instance_name=My Pretix
url=https://tickets.yourdomain.com
currency=USD
; Timezone for event displays
timezone=America/New_York
; Default language
locale=en
; Set to true after initial setup
registration=on
; Data directory inside the container
datadir=/data

[django]
; Generate a strong random secret — use: python3 -c "import secrets; print(secrets.token_urlsafe(50))"
secret=CHANGE_THIS_TO_A_RANDOM_STRING_AT_LEAST_50_CHARACTERS

[database]
backend=postgresql
name=pretix
user=pretix
password=CHANGE_THIS_STRONG_DB_PASSWORD
host=postgres
port=5432

[redis]
location=redis://redis:6379/0
; Use Redis for session storage (faster than database)
sessions=true

[celery]
broker=redis://redis:6379/1
backend=redis://redis:6379/2

[mail]
; SMTP settings for sending tickets and order confirmations
from[email protected]
host=smtp.yourdomain.com
port=587
user=your-smtp-user
password=your-smtp-password
tls=on
; ssl=off

Create a docker-compose.yml file:

services:
  postgres:
    image: postgres:16.6-alpine
    restart: unless-stopped
    environment:
      POSTGRES_DB: pretix
      POSTGRES_USER: pretix
      POSTGRES_PASSWORD: CHANGE_THIS_STRONG_DB_PASSWORD  # Must match pretix.cfg
    volumes:
      - pretix-db:/var/lib/postgresql/data
    networks:
      - pretix-net
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U pretix"]
      interval: 10s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7.4-alpine
    restart: unless-stopped
    volumes:
      - pretix-redis:/data
    networks:
      - pretix-net
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5

  pretix:
    image: pretix/pretix:2026.2.0
    restart: unless-stopped
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    ports:
      - "127.0.0.1:8345:80"  # Bind to localhost — use reverse proxy for public access
    volumes:
      - ./pretix.cfg:/etc/pretix/pretix.cfg:ro  # Configuration file
      - pretix-data:/data  # Media uploads, logs, cache
    environment:
      AUTOMIGRATE: "yes"  # Run database migrations on startup
    networks:
      - pretix-net

volumes:
  pretix-db:
  pretix-redis:
  pretix-data:

networks:
  pretix-net:

Create a .env file alongside:

# No additional env vars needed — all config is in pretix.cfg
# The database password must match between docker-compose.yml and pretix.cfg

Start the stack:

docker compose up -d

Wait about 60 seconds for database migrations to complete on first start. Check progress:

docker compose logs -f pretix

Look for Booting worker messages indicating the web and task workers are ready.

Initial Setup

  1. Navigate to https://tickets.yourdomain.com (or http://localhost:8345 if not using a reverse proxy yet)
  2. Create your admin account at the registration page
  3. After creating your account, edit pretix.cfg and set registration=off to prevent public signups
  4. Restart the container: docker compose restart pretix

Creating Your First Event

  1. Log into the admin panel
  2. Click “Create a new organizer” — this is your organization/brand
  3. Under your organizer, click “Create a new event”
  4. Configure:
    • Event name, dates, and timezone
    • Currency and tax settings
    • Ticket categories and pricing
    • Payment methods (Stripe, PayPal, bank transfer, manual)
  5. Go to the “Shop” section to customize your ticket page design
  6. Enable the event when ready to sell

Configuration

Key Configuration Options

SectionKeyPurposeDefault
[pretix]urlPublic URL of your instanceRequired
[pretix]currencyDefault currencyEUR
[pretix]registrationAllow new account creationon
[pretix]timezoneServer timezoneUTC
[django]secretCryptographic secret keyRequired
[database]backendDatabase typesqlite3
[mail]fromSender address for emailspretix@localhost
[mail]hostSMTP server hostnamelocalhost
[mail]tlsUse STARTTLSoff

Payment Providers

Pretix supports multiple payment providers as plugins:

ProviderPluginCost
StripeBuilt-in2.9% + $0.30
PayPalBuilt-in2.99% + fixed fee
Bank transferBuilt-inFree
Manual paymentBuilt-inFree
MollieCommunity pluginVaries
SquareCommunity plugin2.6% + $0.10

Configure payment providers per-event under Settings → Payment.

Email Configuration

Pretix sends emails for order confirmations, ticket delivery, and event updates. SMTP is required for production use.

Test your email configuration:

docker compose exec pretix python -m pretix runserver --check-email

If using Gmail SMTP:

  • Host: smtp.gmail.com
  • Port: 587
  • TLS: on
  • Use an App Password (not your regular password)

Plugins

Pretix has a plugin system. Common plugins include:

  • pretix-pages — add custom content pages to your ticket shop
  • pretix-venueless — virtual event platform integration
  • pretix-passbook — Apple Wallet ticket delivery
  • pretix-covid-certificates — COVID certificate validation (legacy)

Install plugins by adding them to the Docker image or using pip inside the container.

Reverse Proxy

Pretix requires HTTPS for payment processing. Configure your reverse proxy to forward traffic to port 8345.

Nginx Proxy Manager:

  • Forward hostname: pretix
  • Forward port: 80 (internal container port, or 8345 from host)
  • Enable SSL with Let’s Encrypt
  • Set “Websockets Support” to on

Caddy configuration:

tickets.yourdomain.com {
    reverse_proxy localhost:8345
}

Nginx manual configuration:

server {
    listen 443 ssl http2;
    server_name tickets.yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    client_max_body_size 100M;

    location / {
        proxy_pass http://127.0.0.1:8345;
        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;
    }
}

See Reverse Proxy Setup for detailed instructions.

Backup

What to Back Up

DataLocationImportance
PostgreSQL databasepretix-db volumeCritical — all orders, attendees, event data
Media uploadspretix-data volume (/data/media/)Important — ticket designs, event images
Configuration./pretix.cfgImportant — contains secrets and settings
Redis datapretix-redis volumeLow — cache and sessions, regenerated automatically

Database Backup

docker compose exec postgres pg_dump -U pretix pretix > pretix-backup-$(date +%Y%m%d).sql

Full Volume Backup

docker compose stop pretix
tar czf pretix-data-$(date +%Y%m%d).tar.gz -C /var/lib/docker/volumes/ pretix-data
docker compose start pretix

See Backup Strategy for automated backup approaches.

Troubleshooting

Pretix Won’t Start — Migration Errors

Symptom: Container logs show django.db.utils.OperationalError or migration failures.

Fix:

docker compose exec pretix python -m pretix migrate
docker compose restart pretix

Emails Not Sending

Symptom: Orders complete but no confirmation emails arrive.

Fix:

  1. Verify SMTP credentials in pretix.cfg
  2. Check the Celery worker is running: docker compose logs pretix | grep "celery"
  3. Verify the Redis connection — Celery uses Redis as its message broker
  4. Check your SMTP provider’s sending limits

Static Files Missing (404 on CSS/JS)

Symptom: Pretix loads but looks unstyled — CSS and JavaScript return 404.

Fix:

docker compose exec pretix python -m pretix updateassets
docker compose restart pretix

Slow Performance Under Load

Symptom: Pages load slowly during high-traffic ticket sales.

Fix: Increase the number of Gunicorn workers:

services:
  pretix:
    environment:
      NUM_WORKERS: "8"  # Default is 2x CPU cores

Also consider adding a CDN for static assets and increasing PostgreSQL’s shared_buffers.

Payment Provider Configuration Error

Symptom: “Payment method not available” or payment page errors.

Fix:

  1. Ensure HTTPS is properly configured — payment providers require SSL
  2. Check the url in pretix.cfg matches your actual domain
  3. Verify API credentials for your payment provider in the event settings

Resource Requirements

ResourceMinimumRecommended
RAM1 GB2-4 GB
CPU1 core2+ cores
Disk5 GB10-20 GB (scales with media)
NetworkStable connectionLow-latency for ticket sales

Memory breakdown: PostgreSQL ~128 MB, Redis ~50 MB, Pretix web worker ~256-512 MB, Celery worker ~128-256 MB.

Verdict

Pretix is the best self-hosted ticketing platform available. It handles everything from free community events to paid multi-day conferences with reserved seating. The admin interface is polished, the plugin ecosystem covers common needs, and the check-in app works well for door management.

Choose Pretix if you run events regularly and want to eliminate per-ticket fees from Eventbrite or Tito. A single event selling 200 tickets at $50 each would cost $650+ in Eventbrite fees — your VPS hosting for an entire year costs less than one event’s platform fees.

Skip Pretix if you only run one or two events per year — the setup and maintenance overhead won’t justify the savings.

Comments