Running Repertoire 2024 Server in Docker

This guide covers building and running a local Repertoire 2024 Server Docker image on Linux (Ubuntu/Debian) or Windows 11 with Docker Desktop and WSL 2. It walks through the build, container lifecycle, persistent data, fonts, timezone, and common troubleshooting.

Download the working folder (14.3 KB) here containing the following, refer to the enclosed README for details on each file:

What you need

  • Docker Desktop (Windows/macOS) or Docker Engine (Linux)
  • Docker Buildx (included with current Docker installations)
  • unzip and curl
  • A Repertoire 2024.0 archive (Repertoire-2024.0*.zip)

On Ubuntu or Debian, install the required tools:

sudo apt-get update
sudo apt-get install -y docker.io unzip curl
sudo systemctl enable --now docker
sudo usermod -aG docker "$USER"

Sign out and back in after adding yourself to the Docker group.
Do not run the helper scripts with sudo; that creates root-owned persistent data.

Quick start

1. Place the archive: Put the Repertoire ZIP in the download/ folder. If it is stored elsewhere, set REPERTOIRE_DOWNLOADS_DIR to that path.

2. Create host paths: Create the following paths in the working directory containing the shell scripts and carry out the following:

  • local/repertoire/etc: deploy the ElixirRepertoire.licence, logback.xml, JDBC pool properties and application.conf configured for your environment
  • local/repertoire/ext: deploy the JDBC driver files required to connect to your database
  • local/repertoire/fonts: deploy the necessary fonts required for report template rendering
  • local/repertoire/repository: deploy the file system containing your rml templates and ds files

3. Build and test. Run the single beginner command from the repository root:

./build-all.sh

This builds the repertoire:local image and runs a smoke test against /alive. The underlying commands are also available separately (./build-image.sh and ./test-image.sh).

4. Start the container.

./start-container.sh

The script binds port 1730 to 127.0.0.1, creates all persistent directories, and waits up to two minutes for Repertoire to pass its readiness check. Set HOST_PORT and BIND_ADDRESS if the defaults do not suit your environment.

5. Open Repertoire at http://127.0.0.1:1730.

6. Stop and remove. When finished:

./stop-container.sh
./remove-container.sh

Stopping keeps both the container and its persistent data. Removing the container deletes only the container; the data under local/repertoire/ is kept. The removal helper refuses to remove a running container.

Persistent data

start-container.sh creates and mounts these directories under ./local/repertoire/ if they don’t exist:

Directory Contents
data/ Application data (codex, in, out, web-store, codex-temp)
log/ Application logs
git-repos/ Git repositories managed by Repertoire
etc/ Configuration files, including ElixirRepertoire.licence
ext/ JDBC drivers and custom jar libraries
repository/ Report file systems
fonts/ Additional fonts (mounted read-only)

All of these survive stopping and removing the container. Run ./start-container.sh again to create a new container using the same data. The local/ directory is ignored by Git.

Back up local/repertoire/ to preserve all persistent state. Do not use docker rm -v unless you also intend to remove named volumes.

First-start seeding

On first start, etc/, ext/, and repository/ are empty on the host if not already created. The start script copies the image’s shipped content into them automatically (if not already there), so the bind mount never hides the shipped configuration. After that initial copy, edits you make on the host are preserved across container restarts; the image content is only copied once.

Licence

The licence from the archive is seeded into local/repertoire/etc/ElixirRepertoire.licence on first start and persists there. To replace it, overwrite the file on the host; the change takes effect next time the container starts.

To override the licence without modifying the persistent copy:

REPERTOIRE_LICENCE_FILE=/path/to/ElixirRepertoire.licence ./start-container.sh

Do not copy licence files into the Docker build context or commit them to Git.

Restart policy

The container starts with --restart no. Once Repertoire passes its /alive health check, the policy is upgraded to unless-stopped, so Docker restarts the container automatically after a host reboot or a crash.

Timezone

The container defaults to Asia/Singapore. Override it with:

REPERTOIRE_TZ=America/New_York ./start-container.sh

Fonts

The Docker image includes fontconfig and the DejaVu font family so Java AWT can render text. Without these, reports that use AWT fail with “Fontconfig head is null”.

To supply additional fonts (for example, Windows core fonts such as Arial or Times New Roman), place the .ttf or .otf files in a directory and point to it:

REPERTOIRE_FONTS_DIR=/path/to/fonts ./start-container.sh

The default location is ./local/repertoire/fonts/. The directory is mounted read-only at /usr/share/fonts/repertoire inside the container.

Graceful shutdown

The build script patches bin/run-server to launch Java with exec, making Java PID 1 in the container. This allows Docker to deliver SIGTERM directly to the JVM for a clean shutdown (exit code 143 instead of 137).

Configuration Note: the stop timeout defaults to 30 seconds. If Repertoire needs more time, increase it: STOP_TIMEOUT=60 ./stop-container.sh.

Environment variables

Variable Default Description
IMAGE_TAG repertoire:local Docker image to build or run
HOST_PORT 1730 Host port bound to the container
BIND_ADDRESS 127.0.0.1 Bind address; use 0.0.0.0 to expose beyond localhost
CONTAINER_NAME repertoire Docker container name
REPERTOIRE_LICENCE_FILE (unset) Path to an external licence file
REPERTOIRE_DATA_DIR ./local/repertoire Root directory for all persistent data
REPERTOIRE_UID / REPERTOIRE_GID Current user UID/GID for persistent data ownership
REPERTOIRE_TZ Asia/Singapore Container timezone (TZ environment variable)
REPERTOIRE_FONTS_DIR $REPERTOIRE_DATA_DIR/fonts Additional fonts directory, mounted read-only
REPERTOIRE_DOWNLOADS_DIR ./download Directory to search for archives
STOP_TIMEOUT 30 Seconds to wait for graceful stop before force-killing

Deployment to Target Machine

1.Confirm the image exists (from the Ubuntu/WSL terminal), you should see repertoire with tag local (or whatever IMAGE_TAG was set to) e.g.:

docker images repertoire

2.Export the image to a file, e.g.:

docker save repertoire:local | gzip > ~/repertoire-image.tar.gz

3.Copy over to target machine.

4.Load in target machine, e.g.:

gunzip -c repertoire-image.tar.gz | docker load

5.Ensure scripts, host path local/repertoire and its subdirectories are present in working directory on target machine.

6.Execute ./start-container.sh on target machine.

Troubleshooting

1. “Fontconfig head is null” or blank report output

The image includes fontconfig and ttf-dejavu. If reports still fail, the report likely requires fonts not present in the DejaVu family. Copy the needed font files into a directory and set REPERTOIRE_FONTS_DIR:

mkdir -p local/repertoire/fonts
cp /path/to/arial.ttf /path/to/times.ttf local/repertoire/fonts/
./start-container.sh

2. Container exits with code 137

Exit code 137 means Docker killed the process with SIGKILL (out of memory or stop timeout exceeded). Check two things:

  • Verify Docker has enough memory allocated (Docker Desktop: Settings > Resources).
  • Increase STOP_TIMEOUT if the server needs more time to shut down: STOP_TIMEOUT=60 ./stop-container.sh.

3. Container exits with code 143

This is normal graceful shutdown. Java received SIGTERM and exited cleanly. No action needed.

4. “Container is stopped. Run ./remove-container.sh before starting a replacement.”

A previous container exists but is not running. Remove it first, then start a new one:

./remove-container.sh
./start-container.sh

Your persistent data in local/repertoire/ is kept.

5. “Container exists but is not managed by this project.”

An older repertoire container was created outside these scripts. Inspect it with docker inspect repertoire, then remove it manually with docker rm repertoire if it is no longer needed.

6. Port 1730 is already in use

Another process is using the port. Either stop that process or choose a different port:

HOST_PORT=1731 ./start-container.sh

Then access Repertoire at http://127.0.0.1:1731.

7. Permission denied on persistent directories

The start script sets ownership to your UID/GID. If you previously ran a script with sudo, the directories may be owned by root. Fix ownership:

sudo chown -R "$(id -u):$(id -g)" local/repertoire/

8. Database or MongoDB connection fails inside the container

JDBC connection strings and MongoDB URIs that use localhost or 127.0.0.1 as the host refer to the container itself, not the host machine. Replace localhost with host.docker.internal so the container can reach databases running on the host:

  • JDBC connection pool properties file (local/repertoire/etc/): change the connection URL, e.g. jdbc:sqlserver://host.docker.internal:1433;databaseName=...
  • MongoDB connection string in application.conf: change the host, e.g. mongodb://host.docker.internal:27017/...

Configuration Note: host.docker.internal is supported by Docker Desktop on Windows and macOS. On Linux, add --add-host=host.docker.internal:host-gateway to the docker run options in start-container.sh if it does not resolve automatically.

9. Container did not become ready

The start script waits up to two minutes for /alive to respond. Check the container logs for details:

docker logs repertoire

Common causes: insufficient memory, missing or invalid licence, or a port conflict inside the container.