Install Karnak with Docker Compose
Karnak is distributed as a container image on Docker Hub: nroduit/karnak (multi-arch, linux/amd64 and linux/arm64). It requires two third-party services:
- PostgreSQL for the persistence of the Karnak configuration (sources, destinations, projects, profiles, monitoring)
- Redis for the cache (pseudonym mappings, API call results)
The recommended way to run Karnak in production is Docker Compose. This page describes how to write the docker-compose.yml file and the associated configuration from scratch.
Info
Karnak is also available as a portable distribution that runs without Docker, with an embedded database and an in-memory cache. It is intended for a single machine and local use.
Prerequisites
- Docker Engine 20.10 or later with the Compose plugin (
docker composev2). See the Docker installation guide. - The commands below target Linux. On Windows or macOS, use Docker Desktop and adapt the shell commands.
1. Create the project layout
Create a folder (for example /opt/karnak) with the following structure:
2. Generate the secrets
Karnak reads sensitive values from files through the environment variables ending with _FILE, which is compatible with Docker secrets. Three secrets are required:
| Secret file | Purpose |
|---|---|
karnak_login_password |
Password of the web portal administrator (login defined by KARNAK_LOGIN_ADMIN, admin by default) |
karnak_postgres_password |
Password of the PostgreSQL user, shared by the database container and Karnak |
karnak_db_encryption_key |
Key used by PostgreSQL (pgcrypto) to encrypt sensitive columns such as the client secrets of the API authentication configurations |
Warning
Back up karnak_db_encryption_key together with the database. The key must stay identical for the whole life of the database: if it is lost or changed, the encrypted values stored in PostgreSQL can no longer be decrypted.
3. Write the docker-compose.yml file
Notes:
- Pin the Karnak image to a release tag (
v2.0.0). Thelatesttag follows the most recent release and themastertag is the development build. - Only the ports of the
karnakservice are published. The database and the cache are reachable from Karnak only, through the internal Compose network. DB_PORTis the port inside the Compose network (the default PostgreSQL port), not a port published on the host.- Karnak does not need a writable volume: the configuration is stored in PostgreSQL and the logs are written to the standard output (see Configuring Logs).
4. Write the karnak.env file
This file holds the gateway options. All variables are optional; the values below are the defaults. Uncomment and adapt what you need.
5. Start Karnak
Run the commands from the folder containing docker-compose.yml:
| Action | Command |
|---|---|
| Download or update the images | docker compose pull |
| Start in the background | docker compose up -d |
| Follow the logs | docker compose logs -f |
| Stop | docker compose down |
| Stop and delete the data (reset the database) | docker compose down -v |
On the first start, Karnak creates the database schema automatically. The database schema is also migrated automatically when you upgrade to a newer image.
Once started, with the configuration above:
- Web portal: http://localhost:8080, login
adminwith the password stored insecrets/karnak_login_password - DICOM listener: AE Title
KARNAK-GATEWAY, port11112on the Docker host
The next steps are described in the user guide: create a forward node with its sources and destinations, a project and a de-identification profile.
Environment variables
Web portal and database
| Variable | Default | Description |
|---|---|---|
KARNAK_WEB_PORT |
8080 |
Port of the web portal inside the container (the portable package uses 8081) |
KARNAK_LOGIN_ADMIN |
admin |
Login of the built-in administrator account |
KARNAK_LOGIN_PASSWORD / KARNAK_LOGIN_PASSWORD_FILE |
undefined |
Password of the administrator account, as a value or as a file (Docker secret). |
DB_HOST |
localhost |
Hostname of the PostgreSQL server |
DB_PORT |
5432 |
Port of the PostgreSQL server |
DB_NAME / DB_NAME_FILE |
karnak |
Name of the database |
DB_USER / DB_USER_FILE |
karnak |
Database user |
DB_PASSWORD / DB_PASSWORD_FILE |
karnak |
Database password |
DB_ENCRYPTION_KEY / DB_ENCRYPTION_KEY_FILE |
undefined |
Key used to encrypt sensitive columns in PostgreSQL. Required in production. |
REDIS_HOST |
localhost |
Hostname of the Redis server |
REDIS_PORT |
6379 |
Port of the Redis server |
JAVA_OPTS |
Additional options passed to the Java virtual machine |
A variable and its _FILE counterpart are exclusive: setting both makes the container exit with an error.
DICOM listener
| Variable | Default | Description |
|---|---|---|
DICOM_LISTENER_AET |
KARNAK-GATEWAY |
AE Title of the DICOM listener (calling AE Title used by Karnak toward the destinations) |
DICOM_LISTENER_PORT |
11119 |
Listening port inside the container |
DICOM_LISTENER_TLS |
false |
Accept only DICOM TLS associations |
TLS_KEYSTORE_PATH / TLS_KEYSTORE_SECRET |
Keystore and its password, required when TLS is enabled | |
TLS_TRUSTSTORE_PATH / TLS_TRUSTSTORE_SECRET |
Truststore and its password, required when TLS is enabled |
Email is used by the destination notifications and by the conformance reports.
| Variable | Description |
|---|---|
MAIL_SMTP_HOST |
SMTP server hostname |
MAIL_SMTP_PORT |
SMTP server port |
MAIL_SMTP_SENDER |
Sender address of the emails |
MAIL_SMTP_TYPE |
SSL or STARTTLS to enable authentication. Leave empty for a server without authentication. |
MAIL_SMTP_USER / MAIL_SMTP_SECRET |
Credentials used when MAIL_SMTP_TYPE is set |
Identity provider
By default, Karnak uses the built-in administrator account. Set IDP=oidc to delegate the authentication to an OpenID Connect provider such as Keycloak, and configure it with OIDC_CLIENT_ID, OIDC_CLIENT_SECRET (or OIDC_CLIENT_SECRET_FILE) and OIDC_ISSUER_URI.
Karnak reads the user’s roles from the resource_access.karnak.roles claim of the access token, so the provider must be configured to put the roles of the karnak client in the access token (in Keycloak: client scope roles, with the Add to access token mapper enabled). Three roles are recognized; any other role is ignored and logged as a warning:
| Role | Access |
|---|---|
admin |
Every page of the web portal |
user |
The External pseudonym and Help pages only |
investigator |
Accepted and mapped, but currently gives access to no page; reserved for future use |
The Authentication Config page is unrelated to the portal login: it stores OAuth 2.0 credentials for the API calls made by profiles.
Other services
| Variable | Default | Description |
|---|---|---|
OCR_URL |
http://localhost:8000 |
Base URL of the de-identification image API used by the automatic mask generation and by the burned-in text check of the conformance report. Deploy this service separately (its repository provides a Docker Compose file) and point OCR_URL to it, for example http://image-ocr-identifier:8000 when it runs on the same Docker network. |
LOGBACK_CONFIGURATION_FILE |
Path of a custom Logback configuration, see Configuring Logs |
Run Karnak as a systemd service
To start Karnak automatically at boot, create a systemd unit that drives Docker Compose. The example below assumes the files are in /opt/karnak.
Then enable and start it:
Reverse proxy
The web portal can be served behind a reverse proxy (HTTPS termination). Karnak honors the X-Forwarded-* headers, so make sure the proxy forwards them (X-Forwarded-Proto, X-Forwarded-Host, X-Forwarded-For) and that WebSocket connections are allowed, as the user interface relies on server push.
Upgrade
- Back up the database volume (
docker compose exec karnak-db pg_dump -U karnak karnak > karnak.sql) and thesecrets/folder. - Change the image tag in
docker-compose.ymlto the new release. - Run
docker compose pullthendocker compose up -d. The database schema is migrated automatically at startup.
Build the image yourself
To build the image from the source code instead of using Docker Hub, run from the root of the repository:
Then replace image: nroduit/karnak:v2.0.0 by image: local/karnak:latest in docker-compose.yml.
Other installation pages
-
Inject your own Logback configuration to control log levels, format, rotation and where Karnak writes application and DICOM transfer logs.