DICOM gateway for de-identification or tag morphing
See the codeKarnak is an open-source DICOM gateway for de-identification, tag morphing and DICOM conformance checks. It sits between the imaging network and the archives: it receives studies from modalities, PACS and workstations through a DICOM listener, transforms them according to configurable YAML profiles, and forwards the result to one or more destinations over DICOM (C-STORE) or DICOMweb (STOW-RS). Everything is configured and monitored from a web portal.
For detailed usage instructions, refer to the Karnak User Guide.
A typical deployment feeds a research repository that lives outside the hospital or imaging center: another institution, a research network or the cloud.
The forward node addressed by the called AE Title checks the calling source, then routes each accepted instance to one or more destinations, where it goes through the following pipeline once per destination. Every step is configured on the destination.
The pipeline is illustrated step by step in the user guide: How Karnak works, processing pipeline.
You don't need to build Karnak from source to use it. Pick the option that fits your needs:
| I want to… | Use | Details |
|---|---|---|
| Run Karnak in production | Docker | Installation guide — Docker Compose with Postgres + Redis, the recommended setup |
| Try Karnak quickly on a single machine | Portable package | Self-contained, embedded database, no external services — see Run portable package |
| Contribute to / develop Karnak | Build from source | See Build Karnak and Debug Karnak |
Once Karnak is running, with the default configuration:
admin, password karnak (change these in production: KARNAK_LOGIN_ADMIN / KARNAK_LOGIN_PASSWORD_FILE with docker, KARNAK_ADMIN / KARNAK_PASSWORD otherwise)KARNAK-GATEWAY, port 11119 (the portable package uses 11112) — point your modality or PACS here to send studies to KarnakThe web port (KARNAK_WEB_PORT), the listener AE Title (DICOM_LISTENER_AET) and port (DICOM_LISTENER_PORT), as well as the sources and destinations, are all configurable; see the Karnak User Guide.
Prerequisites:
Execute the maven command mvn clean install -P production in the root directory of the project. The "production" profile builds the Vaadin frontend via pnpm and produces a deployable jar.
Execute the maven command mvn clean install -Pportable in the root directory of the project.
Note: on Windows the bash.exe must be specified: mvn clean install -Pportable -Dbash.executable=${env.LOCALAPPDATA}\Programs\Git\bin\bash.exe
To configure and run Karnak with docker compose (Karnak + Postgres + Redis), follow the installation guide. This is the recommended setup for production.
After building the portable package (see Build for portable package), go into the generated folder build-portable/target/karnak-<os>-jdk<version>-<karnak-version> (for example karnak-linux-x86-64-jdk25-...) and launch run.bat (Windows) or ./run.sh from a terminal (Linux or macOS). On macOS there is no double-clickable launcher: Gatekeeper refuses to open a script downloaded from the Internet, so open a Terminal in the folder and run ./run.sh.
Settings such as the web port and the DICOM listener can be adjusted in the run.cfg file located next to the executable. On the first launch the script proposes to download the optional OCR service used by the automatic pixel de-identification (release pinned by OCR_VERSION in run.cfg), then opens the web portal in the default browser (KARNAK_OPEN_BROWSER=false disables this).
Then open http://localhost:8081 and log in (see Accessing Karnak).
Note: this portable package runs an embedded database (H2) in file mode, and the Redis server is replaced by an in-memory cache. For intensive use, it's recommended to run Karnak with docker and a Postgres database.
mvn clean install once before the first debug session. Besides building the project, this copies
the native OpenCV library into target/classes/lib/<os>-<cpu>/ — it is loaded at startup by the DICOM
gateway, and the application fails with "Cannot register DICOM native librairies" if it is missing.KarnakApplication.java
pom.xml)-Djava.library.path="/tmp/dicom-opencv". Note: the tmp folder must be adapted according to your system and dicom-opencv is mandatory as the last folder.-Dvaadin.productionMode=true to enable production modeDB_ENCRYPTION_KEY=fsGuSZRIEr$HwlTDPglZg*Vl7WtJCZz6RLvqoMKWSA!DB_PASSWORD=karnakDB_PORT=5433DB_USER=karnakDB_NAME=karnakDB_HOST=localhostKARNAK_ADMIN=adminKARNAK_PASSWORD=karnakIDP=undefinedOIDC_CLIENT_ID=undefinedOIDC_CLIENT_SECRET=undefinedOIDC_ISSUER_URI=undefinedThe portable build has no external dependencies: it runs an embedded H2 database (file mode) and an
in-memory cache instead of Postgres + Redis. To debug it in IntelliJ you don't need the docker
components — you only need to activate the portable Spring profile and, optionally, configure a
local DICOM node so received studies are written to disk.
Reuse the Spring Boot launcher from Debug in IntelliJ with the same VM options
(-Djava.library.path=...), then in Environment variables:
application-portable.yml). Either set it in the
launcher's Active profiles field (portable), or add the environment variable:
SPRING_PROFILES_ACTIVE=portableLOCAL_NODE_PORT and
LOCAL_NODE_STORAGE_PATH are both set, Karnak starts an additional DICOM listener that stores
received objects on disk:
LOCAL_NODE_STORAGE_PATH=./dicomLOCAL_NODE_AE_TITLE=KARNAK-LOCALLOCAL_NODE_PORT=11115LOCAL_NODE_FILEPATH_PATTERN={00100010}/{00080060}/{0020000E}/{00080018}.dcmThe H2 database file is created under ./data in the working directory, so no docker services are
required. Then open http://localhost:8081 and log in (see Accessing Karnak).
docker folder located in the root project folder..env.example into .env and modify it)docker compose up -ddocker compose logs -fdocker compose downTwo formatting plugins are bound to the Maven build and run automatically during mvn install:
import x.y.*;) — it leaves them untouched.CI and Sonar flag any style violation, so make sure your changes are formatted before pushing. You can apply both formatters locally with:
mvn spring-javaformat:apply spotless:apply
Neither plugin expands an existing wildcard import into explicit single-class imports. Configure IntelliJ so it never produces wildcards in the first place:
999999Minimum docker version: 20.10
Go on the root folder and launch the following command:
docker build -t local/karnak:latest -f Dockerfile .mvn clean install -P productiondocker build -t local/karnak:latest -f src/main/docker/Dockerfile .The image is published as nroduit/karnak (linux/amd64 and linux/arm64). The container listens on port 8080 for the web portal (KARNAK_WEB_PORT changes it) and 11119 for the DICOM listener. See the installation guide for a complete docker compose setup.
See the environment variables section of the installation guide.
This project is divided in two parts:
An OpenID Connect identity provider can be configured by using the environment variables:
IDP: when this environment variable has the value 'oidc', the following environment
variables will configure the OpenID Connect identity provider. Any other value will load the in
memory user configuration.OIDC_CLIENT_ID: client id of the identity providerOIDC_CLIENT_SECRET: client secret of the identity providerOIDC_ISSUER_URI: issuer URI of the identity providerKarnak exposes a small REST API in addition to the web interface. An OpenAPI (Swagger) description is generated by springdoc and the C-ECHO endpoint is available at /api/echo. For the full list of endpoints and their usage, refer to the Karnak User Guide.
Java
97.0%
HTML
1.0%
DICOM gateway for de-identification or tag morphing
See the codeKarnak is an open-source DICOM gateway for de-identification, tag morphing and DICOM conformance checks. It sits between the imaging network and the archives: it receives studies from modalities, PACS and workstations through a DICOM listener, transforms them according to configurable YAML profiles, and forwards the result to one or more destinations over DICOM (C-STORE) or DICOMweb (STOW-RS). Everything is configured and monitored from a web portal.
For detailed usage instructions, refer to the Karnak User Guide.
A typical deployment feeds a research repository that lives outside the hospital or imaging center: another institution, a research network or the cloud.
The forward node addressed by the called AE Title checks the calling source, then routes each accepted instance to one or more destinations, where it goes through the following pipeline once per destination. Every step is configured on the destination.
The pipeline is illustrated step by step in the user guide: How Karnak works, processing pipeline.
You don't need to build Karnak from source to use it. Pick the option that fits your needs:
| I want to… | Use | Details |
|---|---|---|
| Run Karnak in production | Docker | Installation guide — Docker Compose with Postgres + Redis, the recommended setup |
| Try Karnak quickly on a single machine | Portable package | Self-contained, embedded database, no external services — see Run portable package |
| Contribute to / develop Karnak | Build from source | See Build Karnak and Debug Karnak |
Once Karnak is running, with the default configuration:
admin, password karnak (change these in production: KARNAK_LOGIN_ADMIN / KARNAK_LOGIN_PASSWORD_FILE with docker, KARNAK_ADMIN / KARNAK_PASSWORD otherwise)KARNAK-GATEWAY, port 11119 (the portable package uses 11112) — point your modality or PACS here to send studies to KarnakThe web port (KARNAK_WEB_PORT), the listener AE Title (DICOM_LISTENER_AET) and port (DICOM_LISTENER_PORT), as well as the sources and destinations, are all configurable; see the Karnak User Guide.
Prerequisites:
Execute the maven command mvn clean install -P production in the root directory of the project. The "production" profile builds the Vaadin frontend via pnpm and produces a deployable jar.
Execute the maven command mvn clean install -Pportable in the root directory of the project.
Note: on Windows the bash.exe must be specified: mvn clean install -Pportable -Dbash.executable=${env.LOCALAPPDATA}\Programs\Git\bin\bash.exe
To configure and run Karnak with docker compose (Karnak + Postgres + Redis), follow the installation guide. This is the recommended setup for production.
After building the portable package (see Build for portable package), go into the generated folder build-portable/target/karnak-<os>-jdk<version>-<karnak-version> (for example karnak-linux-x86-64-jdk25-...) and launch run.bat (Windows) or ./run.sh from a terminal (Linux or macOS). On macOS there is no double-clickable launcher: Gatekeeper refuses to open a script downloaded from the Internet, so open a Terminal in the folder and run ./run.sh.
Settings such as the web port and the DICOM listener can be adjusted in the run.cfg file located next to the executable. On the first launch the script proposes to download the optional OCR service used by the automatic pixel de-identification (release pinned by OCR_VERSION in run.cfg), then opens the web portal in the default browser (KARNAK_OPEN_BROWSER=false disables this).
Then open http://localhost:8081 and log in (see Accessing Karnak).
Note: this portable package runs an embedded database (H2) in file mode, and the Redis server is replaced by an in-memory cache. For intensive use, it's recommended to run Karnak with docker and a Postgres database.
mvn clean install once before the first debug session. Besides building the project, this copies
the native OpenCV library into target/classes/lib/<os>-<cpu>/ — it is loaded at startup by the DICOM
gateway, and the application fails with "Cannot register DICOM native librairies" if it is missing.KarnakApplication.java
pom.xml)-Djava.library.path="/tmp/dicom-opencv". Note: the tmp folder must be adapted according to your system and dicom-opencv is mandatory as the last folder.-Dvaadin.productionMode=true to enable production modeDB_ENCRYPTION_KEY=fsGuSZRIEr$HwlTDPglZg*Vl7WtJCZz6RLvqoMKWSA!DB_PASSWORD=karnakDB_PORT=5433DB_USER=karnakDB_NAME=karnakDB_HOST=localhostKARNAK_ADMIN=adminKARNAK_PASSWORD=karnakIDP=undefinedOIDC_CLIENT_ID=undefinedOIDC_CLIENT_SECRET=undefinedOIDC_ISSUER_URI=undefinedThe portable build has no external dependencies: it runs an embedded H2 database (file mode) and an
in-memory cache instead of Postgres + Redis. To debug it in IntelliJ you don't need the docker
components — you only need to activate the portable Spring profile and, optionally, configure a
local DICOM node so received studies are written to disk.
Reuse the Spring Boot launcher from Debug in IntelliJ with the same VM options
(-Djava.library.path=...), then in Environment variables:
application-portable.yml). Either set it in the
launcher's Active profiles field (portable), or add the environment variable:
SPRING_PROFILES_ACTIVE=portableLOCAL_NODE_PORT and
LOCAL_NODE_STORAGE_PATH are both set, Karnak starts an additional DICOM listener that stores
received objects on disk:
LOCAL_NODE_STORAGE_PATH=./dicomLOCAL_NODE_AE_TITLE=KARNAK-LOCALLOCAL_NODE_PORT=11115LOCAL_NODE_FILEPATH_PATTERN={00100010}/{00080060}/{0020000E}/{00080018}.dcmThe H2 database file is created under ./data in the working directory, so no docker services are
required. Then open http://localhost:8081 and log in (see Accessing Karnak).
docker folder located in the root project folder..env.example into .env and modify it)docker compose up -ddocker compose logs -fdocker compose downTwo formatting plugins are bound to the Maven build and run automatically during mvn install:
import x.y.*;) — it leaves them untouched.CI and Sonar flag any style violation, so make sure your changes are formatted before pushing. You can apply both formatters locally with:
mvn spring-javaformat:apply spotless:apply
Neither plugin expands an existing wildcard import into explicit single-class imports. Configure IntelliJ so it never produces wildcards in the first place:
999999Minimum docker version: 20.10
Go on the root folder and launch the following command:
docker build -t local/karnak:latest -f Dockerfile .mvn clean install -P productiondocker build -t local/karnak:latest -f src/main/docker/Dockerfile .The image is published as nroduit/karnak (linux/amd64 and linux/arm64). The container listens on port 8080 for the web portal (KARNAK_WEB_PORT changes it) and 11119 for the DICOM listener. See the installation guide for a complete docker compose setup.
See the environment variables section of the installation guide.
This project is divided in two parts:
An OpenID Connect identity provider can be configured by using the environment variables:
IDP: when this environment variable has the value 'oidc', the following environment
variables will configure the OpenID Connect identity provider. Any other value will load the in
memory user configuration.OIDC_CLIENT_ID: client id of the identity providerOIDC_CLIENT_SECRET: client secret of the identity providerOIDC_ISSUER_URI: issuer URI of the identity providerKarnak exposes a small REST API in addition to the web interface. An OpenAPI (Swagger) description is generated by springdoc and the C-ECHO endpoint is available at /api/echo. For the full list of endpoints and their usage, refer to the Karnak User Guide.
Java
97.0%
HTML
1.0%