Skip to content

Docker deployment

Drovio Server can be deployed as a Docker container. For this purpose, we deliver two different Docker images:

  • All-in-one: mainly used for trialing and pre-production. Contains the essential Drovio Server features. All dependencies are embedded and automatically configured during container startup.
  • Production-ready: dedicated to production environments. Drovio Server uses a docker-managed/external database and the internal session store or a docker-managed/external Redis session store.
Docker image All-in-one Production-ready
Usage Testing / pre-production Production
Base Debian 13 (Trixie) slim Debian 13 (Trixie) slim
PostgreSQL database Internal PostgreSQL database Docker-managed / external PostgreSQL database (14+)
Session store Internal session store Internal session store or docker-managed / external Redis session store
Runs as root drovio, uid 1000

Docker-managed vs external components

The term docker-managed refers to a Drovio Server component that is managed through the docker compose plugin and that lives in the same Docker network. External components are, on the contrary, totally independent: you then have to provide connection credentials through the related environment variables.

Both images are multi-architecture: linux/amd64 and linux/arm64 are served from the same name, and Docker picks the one matching your machine. There is no --platform option to pass and no architecture-specific image name.

Requirements

  • Docker Engine 20.10 or later, for multi-architecture image support.
  • The docker compose plugin 2.20 or later for the production-ready image, which uses profiles and optional dependencies.

Getting the images

Images are published to our private registry. Ask support@drovio.com for the credentials of your organization: you will receive a username and a token, both specific to you and revocable.

Image Reference
All-in-one registry.gitlab.com/drovio/drovio-server-aio
Production-ready registry.gitlab.com/drovio/drovio-server
docker login registry.gitlab.com -u <username> -p <token>
docker pull registry.gitlab.com/drovio/drovio-server:3.6.6

Which tag to use

Tag Points at
3.6.6 that exact release, and never moves
3.6 the latest patch of the 3.6 series
latest, stable the latest release

Pin a full version in production. The moving tags are convenient for a trial, but they mean a docker compose pull can bring in a new minor version without you deciding it.

Outgoing network access

Your firewall must allow registry.gitlab.com and the object storage domain image layers are downloaded from. A docker login that succeeds followed by a docker pull that stalls is almost always due to this issue.

Offline installation

If your servers have no outgoing access at all, we also ship each release as an archive, one per architecture. Ask support for it then load it on the target machine:

docker load -i docker-drovio-server-amd64-3.6.6.tar.gz

The loaded image has the same name and tag as the one in the registry: the rest of this page applies too.

Persistent data management

Following the main Docker concepts, data stored in a container is ephemeral and does not subsist after container destruction. However, there are mechanisms to deal with persistent data, including bind mounts that map a file/folder from the host filesystem into the container.

Bind mounts are used by our Docker images to deal with three types of persistent data:

Data Path in container Concerns
Configuration files /etc/drovio-server both images
Log files /var/log/drovio-server both images
Database data /opt/drovio-server/data the all-in-one image

The production-ready image holds no database of its own. It only needs the first two. Where its data lives is the business of the database you point it at, whether that is the one docker compose starts for you or your own server.

Ownership, production-ready image

The production-ready image runs as the unprivileged user drovio, uid and gid 1000. The two directories it writes to must be owned by it:

mkdir -p config logs
sudo chown -R 1000:1000 config logs

The container refuses to start otherwise, and tells you which directory to fix.

Never do this to the database directory

data/postgresql belongs to the database container, which runs under its own user. Handing it to uid 1000 makes PostgreSQL fail to start with a permission error on its own files.

Upgrading from 3.6.5 or earlier

Earlier versions of this image ran as root. The directories they created on your host belong to root. Run the chown command above on your existing config and logs directories before starting the new image.

Nothing is written outside those two paths, and the Vert.x scratch under /tmp. The container can also run with a read-only root filesystem:

docker run --read-only --tmpfs /tmp ...

All-in-one image deployment

Create a drovio-server folder and go into it:

mkdir drovio-server
cd drovio-server

Create a volume for the embedded database, then launch the container:

docker volume create drovio-data

docker run --hostname drovio.example.com \
  -p 8090:8090 \
  -v "./config:/etc/drovio-server" \
  -v "./logs:/var/log/drovio-server" \
  -v "drovio-data:/opt/drovio-server/data" \
  --rm -it "registry.gitlab.com/drovio/drovio-server-aio:3.6.6"

Use a volume for the database, not a bind mount

PostgreSQL checks that its data directory belongs to the postgres user. Docker Desktop on macOS and Windows presents everything inside a bind mount as owned by root, whatever you do to it. The container can't start that way. A named volume has no such limitation and is the recommended way to hold database data anyway. Configuration and logs are unaffected and can stay as bind mounts.

Option Description
--hostname Sets a specific hostname. You will then have to send us the specified hostname so we can generate your licenses. Keep the same hostname, since licenses are bound to this one.
-p <host>:<container> Publishes the container port to the host port. Port 8090 is used here since Drovio Server doesn't enable TLS and all HTTP traffic goes through port 8090 by default.
-v "<host>:<container>" Bind mounts for the persistent data described above.
--rm Automatically remove the container when it exits.
-it Allocate a pseudo-TTY connected to the container's stdin.

The hostname is written once

On its very first start the server writes its own URL, built from the hostname you give it, into its configuration. It is not recomputed afterwards, and your licenses are bound to it. A container started without --hostname would refuse to run.

Set APP_URL instead if the URL your users reach differs from the container hostname, behind a reverse proxy for instance.

Production-ready image deployment

The production-ready image is deployed through the docker compose plugin, a tool for defining and running multi-container Docker applications.

Getting the deployment files

Everything you need to deploy is inside the image itself. Extract it next to where you want to run the server, with the same credentials you used to pull:

id=$(docker create registry.gitlab.com/drovio/drovio-server:3.6.6)
docker cp "$id:/opt/drovio-server/bundle/." ./drovio-server
docker rm "$id"
cd drovio-server

You get three files, all matching the version you just pulled:

File What it is
docker-compose.yml the deployment, with or without a managed database and session store
env.example the settings you have to fill in
drovio-server.sql the database schema, used when the database is created and when upgrading

Its image: line already points at the exact version you extracted it from.

Settings

Copy env.example to .env and fill it in. Two values are mandatory:

DROVIO_HOSTNAME=drovio.example.com
DB_PASSWORD=<generate one>

Generate the passwords rather than reusing one, for instance with openssl rand -base64 24. DROVIO_HOSTNAME follows the same rule as --hostname above: it is written into the server URL on first start only.

Docker-managed or external components

Whether the database and the session store are managed here or provided by you is chosen at start time, with profiles. The same docker-compose.yml covers all three cases:

Command What it runs
docker compose --profile bundled-db up PostgreSQL managed by docker compose, internal session store
docker compose --profile bundled-db --profile redis up same, with a Redis session store managed by docker compose
docker compose up external database, set DB_HOST and friends in .env

With the redis profile, also uncomment SS_TYPE, SS_REDIS_CONNECTION_STRINGS, SS_REDIS_MASTER_NAME and SS_REDIS_PASSWORD in your .env.

  • Docker-managed components: use of the docker compose plugin. All containers follow the same lifecycle and are located on the same Docker network.
  • External components: the concerned components are not declared in the docker-compose configuration file. Connection information should be passed through the optional environment variables. During the first run, the Drovio Server configuration file doesn't exist and is created with default values. These environment variables are then used to override some of those default values, allowing a successful first run.

Checking that the server is up

Both images expose a health endpoint, and declare a Docker HEALTHCHECK that uses it. docker ps reports the container as healthy once the server answers.

curl -f http://drovio.example.com:8090/healthcheck

Environment variables

Environment variable Configuration field
APP_URL .http.url
SS_TYPE .http.session_store.type
SS_REDIS_CONNECTION_STRINGS .http.session_store.redis.connections
SS_REDIS_MASTER_NAME .http.session_store.redis.master
SS_REDIS_PASSWORD .http.session_store.redis.password
DB_HOST .database.host
DB_PORT .database.port
DB_NAME .database.database
DB_USER .database.user
DB_PASSWORD .database.password
DB_MAIN_POOL_SIZE .database.pool_options.main.max_size
DB_LICENSING_POOL_SIZE .database.pool_options.licensing.max_size
DB_MAIN_IDLE_TIMEOUT .database.pool_options.main.idle_timeout
DB_LICENSING_IDLE_TIMEOUT .database.pool_options.licensing.idle_timeout
DB_MAIN_CONNECT_TIMEOUT .database.pool_options.main.connect_timeout
DB_LICENSING_CONNECT_TIMEOUT .database.pool_options.licensing.connect_timeout
DB_POOL_SIZE (deprecated) .database.pool_options.main.max_size
DB_NV_POOL_SIZE (deprecated) .database.pool_options.licensing.max_size
DB_IDLE_TIMEOUT (deprecated) .database.pool_options.main.idle_timeout

Environment variables always win

These variables always override values from the Drovio Server configuration file during the starting process. If you modify values in the configuration files that are related to a specific environment variable, you also have to either remove that variable from the docker-compose .yml file, or update its value before restarting Drovio Server.

Upgrading

Pull the version you want, then recreate the containers. Your configuration, logs and database live in the bind mounts and are not affected.

docker compose pull
docker compose --profile bundled-db up -d

The database schema

A new version may add tables or columns. The two images do not handle that the same way.

Image What applies the schema changes
All-in-one the container itself, on every start. Nothing to do.
Production-ready you, before starting the new image.

The production-ready image never touches your schema. drovio-server.sql is only run when the database is created, by the docker compose database container on its very first start or by you on your own server. It is not replayed afterwards.

So when upgrading the production-ready image:

  1. Extract drovio-server.sql from the image you are upgrading to, the same way as for a first installation. The script that ships inside an image is always the one that image expects.

    id=$(docker create registry.gitlab.com/drovio/drovio-server:3.6.6)
    docker cp "$id:/opt/drovio-server/bundle/drovio-server.sql" .
    docker rm "$id"
    
  2. Apply it to your database, with the Drovio Server containers stopped.

    psql -h my-database.example.com -U drovio -d drovio -f drovio-server.sql
    
  3. Start the new image.

The script is written to be replayed: it creates what is missing and leaves the rest alone, so applying it to an up-to-date database changes nothing.

Back up first

Make a database backup before applying a schema script, whatever the version gap. It is the one step of this procedure that cannot be undone.

All-in-one, PostgreSQL major versions

The all-in-one image does not upgrade its database cluster in place. If a new release ships a newer PostgreSQL major version, the container stops with an explanatory message on start. Dump your data from the previous image with pg_dumpall and restore it into a fresh volume with the new one.