Skip to content

OpenProject

OpenProject covers work packages, Gantt charts, boards, time tracking and wikis. Six containers — the application server, a background worker, a scheduler, a one-shot seeder, memcached and PostgreSQL.

Last run on a host 8 Nov 2026 · data restored from a backup

Pinned at 17.9.6-slim (released 30 Oct 2026) · upstream has released 17.9.7-slim on 9 Nov 2026

In the upstream images: 3 CRITICAL · 53 HIGH with a published fix — per image

To try it: Docker, nothing else. See Try it locally.

To deploy it behind the proxy: Traefik running and a domain.

On your own machine, with no proxy, domain or certificate. From business/openproject/:

Terminal window
cp .env.local.example .env.local
# The secrets ship empty; generate the ones this stack needs
{
echo "DB_PASSWORD=$(openssl rand -hex 32)"
echo "SECRET_KEY_BASE=$(openssl rand -base64 64 | tr -d '\n')"
} >> .env.local
docker compose -f docker-compose.local.yml --env-file .env.local up -d

Then open http://localhost:8080. Stop it again with the same command and down.

The Community Edition has local accounts only — no OIDC and no single sign-on, so it cannot use Authentik.

From business/openproject/:

  1. Copy the environment file and set APP_TRAEFIK_HOST, TZ and OPENPROJECT_DEFAULT_LANGUAGE:

    Terminal window
    cp .env.example .env
  2. Generate the secrets:

    Terminal window
    mkdir -p .secrets
    openssl rand -base64 64 | tr -d '\n' > .secrets/secret_key_base.txt
    openssl rand -base64 32 | tr -d '\n' > .secrets/db_pwd.txt
  3. Start it. The seeder runs first, applies the migrations and seeds initial data, then exits — the other services wait for it:

    Terminal window
    docker compose up -d
    docker compose logs seeder --follow

    Around two minutes on first start.

  4. Open https://<APP_TRAEFIK_HOST> and log in with the default administrator account, then change the password.

Terminal window
docker compose ps # the seeder has exited; five services running

A seeder still running or restarting means the migrations did not complete, and the application will not work regardless of what the web container reports.

Then create a project and a work package with an attachment. The attachment goes to a separate volume from the database.

This stack stores data in Docker named volumes, not in volumes/ under the stack directory. Their host paths are /var/lib/docker/volumes/openproject_<name>/_data, which is what a backup has to name.

The stack names tls-compatible on the router’s tls.options label (APP_TRAEFIK_TLS_OPTION=tls-compatible in .env) — a documented exception kept from before the model, with no reason recorded. The profile exists for older clients that must still connect, and OpenProject is reached by whatever browsers a team already has. Verify on a host whether tls-standard, the deployment default, serves them, then remove the variable and the label.

The security badge requests releases.openproject.com/v1/check.svg with a uuid, the installation type and the version. It is on by default.

Turn it off in Administration → System settings → General, or set security_badge_display=false. It is stored in the database, so it is a step after the first login.

Database PostgreSQL, container openproject-db, database openproject, user openproject
Password .secrets/db_pwd.txt
State db_data (database) · op_assets (work-package attachments)
Quiescing Not needed for the dump. Attachments are written during use and each file is independent.

For borgmatic:

postgresql_databases:
- name: openproject
username: openproject
# The server's own client, inside its container
pg_dump_command: docker exec openproject-db pg_dump
pg_restore_command: docker exec -i openproject-db pg_restore
psql_command: docker exec -i openproject-db psql

The attachment volume belongs in source_directories by its host path. A database-only restore gives work packages whose attachments are gone.

Restore order: database, then the application.

  1. Read the release notes. OpenProject ships migrations with most releases.

  2. Back up the database and the attachment volume together.

  3. Raise APP_TAG in .env, then:

    Terminal window
    docker compose pull && docker compose up -d
    docker compose logs seeder --follow

    The seeder runs the migrations again on the new version.

  4. Open a project once the seeder has exited.

The seeder keeps restarting. Migrations are failing. Read docker compose logs seeder — the web container is not the place to look.

Attachments are missing after a restore. The op_assets volume was not part of the backup. Its host path is under /var/lib/docker/volumes/.

Single sign-on cannot be configured. The Community Edition does not have it.