Installation
Presswerk runs as three Docker containers: the application, PostgreSQL, and Keycloak (identity provider).
System Requirements
Section titled “System Requirements”| Component | Minimum | Recommended |
|---|---|---|
| CPU | 2 cores | 4 cores |
| RAM | 4 GB | 8 GB |
| Disk | 20 GB | 50 GB+ (depends on report volume) |
| OS | Linux (amd64), macOS | Linux (Ubuntu 22.04+, Debian 12+) |
| Docker | 24.0+ | Latest stable |
| Docker Compose | v2.20+ | Latest stable |
Ports: 8080 (application), 8081 (Keycloak), 5432 (PostgreSQL, internal only)
One-Line Install
Section titled “One-Line Install”curl -fsSL https://presswerk.app/install.sh | bashThis downloads Docker Compose files, generates secure passwords, pulls images, and starts all services. You will be prompted for your app domain, Keycloak domain, and admin email.
For non-interactive installation:
export APP_DOMAIN=reports.acme.com \ KEYCLOAK_HOSTNAME=auth-reports.acme.com \ ADMIN_EMAIL=admin@acme.com \ && curl -fsSL https://presswerk.app/install.sh | bashSee Air-Gapped Install for environments without internet access.
Manual Install
Section titled “Manual Install”1. Create project directory
Section titled “1. Create project directory”mkdir presswerk && cd presswerk2. Create docker-compose.yml
Section titled “2. Create docker-compose.yml”services: postgres: image: postgres:16-alpine container_name: presswerk-postgres environment: POSTGRES_USER: ${DB_USER:-presswerk} POSTGRES_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD must be set} POSTGRES_DB: ${DB_NAME:-presswerk} volumes: - postgres_data:/var/lib/postgresql/data configs: - source: init-keycloak-schema target: /docker-entrypoint-initdb.d/init-keycloak-schema.sql healthcheck: test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-presswerk} -d ${DB_NAME:-presswerk}"] interval: 10s timeout: 5s retries: 5 restart: unless-stopped
keycloak: image: ${DOCKER_REGISTRY:-ghcr.io/fs2-software}/presswerk-keycloak:${APP_VERSION:-latest} container_name: presswerk-keycloak command: start --import-realm --health-enabled=true environment: KC_DB: postgres KC_DB_URL: jdbc:postgresql://postgres:5432/${DB_NAME:-presswerk} KC_DB_SCHEMA: keycloak KC_DB_USERNAME: ${DB_USER:-presswerk} KC_DB_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD must be set} KC_HOSTNAME: https://${KEYCLOAK_HOSTNAME:?KEYCLOAK_HOSTNAME must be set} KC_HTTP_ENABLED: "true" KC_PROXY_HEADERS: xforwarded KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN_USER:-admin} KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:?KEYCLOAK_ADMIN_PASSWORD must be set} ports: - "${KEYCLOAK_PORT:-8081}:8080" depends_on: postgres: condition: service_healthy healthcheck: test: ["CMD-SHELL", "exec 3<>/dev/tcp/localhost/9000 && echo -e 'GET /health/ready HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' >&3 && cat <&3 | head -1 | grep -q '200 OK'"] interval: 10s timeout: 5s retries: 12 start_period: 30s restart: unless-stopped
app: image: ${DOCKER_REGISTRY:-ghcr.io/fs2-software}/presswerk:${APP_VERSION:-latest} container_name: presswerk-app environment: SPRING_DATASOURCE_URL: jdbc:postgresql://postgres:5432/${DB_NAME:-presswerk} SPRING_DATASOURCE_USERNAME: ${DB_USER:-presswerk} SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD:?DB_PASSWORD must be set} PRESSWERK_EDITION: core PRESSWERK_TENANCY_MODE: single KEYCLOAK_URL: http://keycloak:8080 KEYCLOAK_PUBLIC_URL: ${KEYCLOAK_PUBLIC_URL:?KEYCLOAK_PUBLIC_URL must be set} KEYCLOAK_ADMIN_USER: ${KEYCLOAK_ADMIN_USER:-admin} KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:?KEYCLOAK_ADMIN_PASSWORD must be set} APP_DOMAIN: ${APP_DOMAIN:?APP_DOMAIN must be set} IMAGE_STORAGE_PATH: /var/data/presswerk/images IMAGE_BASE_URL: https://${APP_DOMAIN:?APP_DOMAIN must be set}/api/images SMTP_HOST: ${SMTP_HOST:-} SMTP_PORT: ${SMTP_PORT:-587} SMTP_USERNAME: ${SMTP_USERNAME:-} SMTP_PASSWORD: ${SMTP_PASSWORD:-} SMTP_FROM: ${SMTP_FROM:-noreply@presswerk.app} INITIAL_ADMIN_EMAIL: ${INITIAL_ADMIN_EMAIL:-} INITIAL_ADMIN_PASSWORD: ${INITIAL_ADMIN_PASSWORD:-} ports: - "${APP_PORT:-8080}:8080" volumes: - image_data:/var/data/presswerk/images - export_temp:/tmp/presswerk depends_on: postgres: condition: service_healthy keycloak: condition: service_healthy restart: unless-stopped
volumes: postgres_data: name: presswerk_postgres image_data: name: presswerk_images export_temp: name: presswerk_export
networks: default: name: presswerk
configs: init-keycloak-schema: content: | CREATE SCHEMA IF NOT EXISTS keycloak;3. Create .env
Section titled “3. Create .env”# RequiredAPP_DOMAIN=reports.your-domain.comDB_PASSWORD=your-secure-database-passwordKEYCLOAK_HOSTNAME=auth-reports.your-domain.comKEYCLOAK_PUBLIC_URL=https://auth-reports.your-domain.comKEYCLOAK_ADMIN_PASSWORD=your-keycloak-admin-passwordINITIAL_ADMIN_EMAIL=admin@your-domain.comINITIAL_ADMIN_PASSWORD=your-temporary-password
# OptionalAPP_VERSION=latestAPP_PORT=8080KEYCLOAK_PORT=80814. Start services
Section titled “4. Start services”docker compose up -d5. Verify
Section titled “5. Verify”docker compose pscurl http://localhost:8080/api/actuator/healthInitial Setup
Section titled “Initial Setup”- Open Presswerk at
https://reports.your-domain.com - Sign in with the admin email and temporary password shown during installation
- You will be prompted to set a new password on first login