Skip to content

Use Docker Compose

This guide explains how to run the PERSEUS platform using Docker Compose. A Podman workflow is included below.

Docker Engine and Docker-Compose v2 or Podman (see Podman section).

A .env file next to your Compose file with the required PERSEUS settings (database, secrets, etc.).

Create a folder backup next to your docker-compose.yml file. This folder will be mounted into the perseus-core container and holds the daily backups of all PERSEUS data. Read more about this mechanism in the documentation. You can change the path to the mounted backup directory in the docker-compose.yml.

Optional local folders for custom content:

  • ./custom-services → mounted into the core container
  • ./custom-states → mounted into the core container

Create docker-compose.yml with the following content (identical to what we ship, with inline comments). If you run Podman on SELinux systems (e.g., Fedora), add :Z to bind mounts (see the Podman tips below).

docker-compose.yml
services:
perseus-core:
image: docker.io/pc2upb/perseus-core:latest
pull_policy: always
ports:
- "8000:8000" # Core listens on 8000 inside the container
networks:
- database_network
volumes:
- core-rsa:/home/perseus/perseus/security/keys
- ./backups:/home/perseus/perseus/backups
- ./custom-services:/home/perseus/perseus/services/custom
- ./custom-states:/home/perseus/perseus/states/custom
env_file:
- .env
restart: unless-stopped
perseus-frontend:
image: docker.io/pc2upb/perseus-frontend:latest
pull_policy: always
ports:
- "8001:80" # Frontend is served on port 80 inside the container
environment:
- CORE_URL=<HOST>/api # Replace <HOST> with your host, i.e. https://perseus.pc2.uni-paderborn.de
restart: unless-stopped
mongodb:
image: docker.io/library/mongo:latest
networks:
- database_network
volumes:
- mongodb-data:/mongodb
restart: unless-stopped
networks:
database_network:
volumes:
core-rsa:
mongodb-data:
Terminal window
# 1) Pull images (optional; docker compose will pull on demand)
docker compose pull
# 2) Start in the background
docker compose up -d
# 3) Check logs (useful during first start)
docker compose logs -f perseus-core
docker compose logs -f perseus-frontend
Terminal window
docker compose pull
docker compose up -d
Terminal window
docker compose down

You can use any reverse proxy. Below are minimal configs that route BASEURL/ → frontend and BASEURL/api → core.

server {
listen 80;
server_name perseus.example.org;
# If you terminate TLS elsewhere, keep this on 80; otherwise use 'listen 443 ssl' and add certs.
location / {
proxy_pass http://127.0.0.1:8001/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /api/ {
proxy_pass http://127.0.0.1:8000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
perseus.example.org {
route /api* {
uri strip_prefix /api
reverse_proxy 127.0.0.1:8000
}
reverse_proxy 127.0.0.1:8001
}

You have two main options:

Option A — podman-compose (Compose-compatible)

Section titled “Option A — podman-compose (Compose-compatible)”

If you prefer to keep using the same docker-compose.yml:

Terminal window
# Install podman-compose (package name may vary by distro)
sudo dnf install podman-compose # Fedora
# or
sudo apt-get install podman-compose # Debian/Ubuntu (may require pipx/pip if not packaged)
# Start
podman-compose up -d
# Logs
podman-compose logs -f perseus-core
podman-compose logs -f perseus-frontend
# Stop
podman-compose down

SELinux tip (Fedora/RHEL): For bind mounts like ./custom-services:… add :Z to the end so Podman can relabel the content.

Option B — Native Podman + systemd (advanced)

Section titled “Option B — Native Podman + systemd (advanced)”

You can convert a running container set into systemd units for auto‑start:

Terminal window
# Start once with podman-compose up -d (or podman run ... per service)
# Then generate systemd units:
podman generate systemd --name --files --new --restart-policy=always perseus-core
podman generate systemd --name --files --new --restart-policy=always perseus-frontend
podman generate systemd --name --files --new --restart-policy=always mongodb
# Copy units to your user systemd dir and enable them
mkdir -p ~/.config/systemd/user
cp *.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now container-perseus-core.service container-perseus-frontend.service container-mongodb.service
  • CORE_URL mismatch: Ensure the frontend CORE_URL exactly matches your public API route (including /api), otherwise the browser will call the wrong origin.
  • CORS: Using a reverse proxy with BASEURL/ and BASEURL/api keeps everything on the same origin and avoids most CORS issues.
  • Firewall: Open inbound 80/443 on your host if you expect external access.
  • Updating images: Always pull and then up -d to apply new versions without losing volumes.
  • Backups: Backup the named volumes mongodb-data and core-rsa regularly. PERSEUS also creates daily backups of all data.