Migration from Windows to Docker

This guide walks step by step through migrating an existing Relution installation on a Windows Server to a modern Docker-based installation on a Linux server.


What happens during this migration?

The current Relution installation runs on a Windows Server with a MariaDB database. The new setup runs on a Linux server in so-called “containers” (Docker). The difference that makes this migration necessary: Windows does not distinguish between uppercase and lowercase in file names and table names. Linux, on the other hand, does. That is why certain table names in the database must be converted to uppercase after the move – there is a ready-made script for this at the end.

The migration runs through these phases:

  1. Create a backup (dump) of the database on the Windows Server
  2. Prepare the new Linux server with Docker
  3. Import the backup into the new database
  4. Rename table names to uppercase
  5. Start Relution and verify

Prerequisites before starting

Make sure the following is available:

  • Access to the Windows Server (directly on site or via Remote Desktop / RDP)
  • The name of the Relution database – if unknown, ask the administrator or look it up in the existing Relution configuration file. Often the name is simply relution.
  • The password of the MariaDB database user (usually root or a dedicated Relution user)
  • A Linux server (Ubuntu 22.04 or 24.04 recommended) on which Docker and Docker Compose are already installed
  • Access to the Linux server via SSH (a terminal program such as PuTTY on Windows or the built-in terminal on macOS/Linux)
  • A file transfer program such as WinSCP → (free) to copy files from the Windows Server to the Linux server

Phase 1 – Create a backup on the Windows Server

In this step we create a complete backup copy of the Relution database as an SQL file. This file contains all the data and will be imported into the new environment later.

1.1 Open the Command Prompt as Administrator

  1. On the Windows Server, press the key combination Windows key + R
  2. Type cmd and press Ctrl + Shift + Enter (not just Enter) – this opens the Command Prompt with administrator privileges
  3. Confirm the security prompt with Yes

1.2 Create the target folder for the backup

Enter the following command and press Enter:

mkdir C:\backup

This command creates the folder C:\backup, in which we store the backup file. If the folder already exists, a harmless message appears – just continue.

1.3 Find the database path

mysqldump is the program that creates the backup. It is located in the MariaDB installation directory. Check which path is correct on the system:

dir "C:\Program Files\MariaDB"

A folder named MariaDB 10.6 or MariaDB 10.11 should then be visible. Make a note of the exact version number – it is needed in the next step.

1.4 Create the database dump

In the following command, replace 10.11 with the actual MariaDB version number and relution with the name of the database, if it differs:

"C:\Program Files\MariaDB\MariaDB 10.11\bin\mysqldump.exe" -u root -p --single-transaction --routines --triggers --default-character-set=utf8mb4 relution > C:\backup\relution_dump.sql

After pressing Enter, a prompt for the database password appears. Enter it (the input is invisible – this is normal) and press Enter.

If no error appears and the normal input prompt reappears, the export was successful.

Brief explanation of the options used:

OptionMeaning
-u rootLog in as database user root
-pPassword is prompted interactively
--single-transactionBackup without locking the database (ongoing operation remains possible)
--routinesStored procedures are backed up as well
--triggersTriggers are backed up as well
--default-character-set=utf8mb4Character set for special characters and emojis

1.5 Verify the backup

Check whether the file was created correctly:

dir C:\backup\relution_dump.sql

The file should appear with a size (typically several MB). If the file is 0 bytes, something went wrong – in that case run the command from 1.4 again and watch for error messages.

1.6 Transfer the backup file to the Linux server

Open WinSCP, connect to the Linux server (enter IP address, username and password) and copy the file:

  • Source (Windows): C:\backup\relution_dump.sql
  • Destination (Linux): /opt/relution/relution_dump.sql

If the folder /opt/relution/ does not yet exist on the Linux server, create it first (see Phase 2, step 2.1).


Phase 2 – Prepare the Linux server

All of the following commands are run on the Linux server in an SSH terminal.

2.1 Create the working directory

mkdir -p /opt/relution
cd /opt/relution

The command mkdir -p creates the folder and all parent folders if they do not yet exist. With cd we switch into this folder.

2.2 Create the Docker Compose file

Docker Compose is a method for starting and managing several related programs (here: database + Relution) together. The configuration is stored in a file named docker-compose.yml.

Create the file:

nano /opt/relution/docker-compose.yml

The command nano opens a simple text editor directly in the terminal. Copy the following content into it in full:

Show full configuration example
version: "3.8"

services:
mariadb:
  image: mariadb:10.11
  container_name: relution-db
  restart: unless-stopped
  environment:
    MYSQL_ROOT_PASSWORD: HIER_ROOT_PASSWORT_EINSETZEN
    MYSQL_DATABASE: relution
    MYSQL_USER: relution
    MYSQL_PASSWORD: HIER_RELUTION_PASSWORT_EINSETZEN
  volumes:
    - mariadb_data:/var/lib/mysql
  networks:
    - relution-net

relution:
  image: relution/relution:latest
  container_name: relution-app
  restart: unless-stopped
  depends_on:
    - mariadb
  ports:
    - "8080:8080"
    - "8443:8443"
  environment:
    DB_HOST: mariadb
    DB_PORT: 3306
    DB_NAME: relution
    DB_USER: relution
    DB_PASSWORD: HIER_RELUTION_PASSWORT_EINSETZEN
  volumes:
    - relution_data:/opt/relution/data
  networks:
    - relution-net

volumes:
mariadb_data:
relution_data:

networks:
relution-net:

Save and close the file: Ctrl + O (save), then Enter, then Ctrl + X (exit).

2.3 Start only the database

Now we first start only the database container – not Relution itself yet. This is important so that on its first start Relution does not encounter an empty database and begin creating its own (incorrect) tables.

cd /opt/relution
docker compose up -d mariadb

The option -d stands for “detached” – the container runs in the background and does not block the terminal.

2.4 Wait until the database is ready

docker logs -f relution-db

This command displays the logs (log messages) of the database container in real time. Wait until the following message appears:

[Note] mariadbd: ready for connections.

As soon as this message is visible, press Ctrl + C to stop the display. The database continues running in the background.


Phase 3 – Import the backup

If the dump file has not yet been transferred to the server, do so now (see Phase 1, step 1.6).

3.1 Import the dump into the database

docker exec -i relution-db mariadb \
  -u root -pHIER_ROOT_PASSWORT_EINSETZEN \
  relution < /opt/relution/relution_dump.sql

A brief explanation of what happens here: docker exec -i relution-db means that we run a command inside the running database container. mariadb ... < file.sql imports the SQL file into the database.

The import may take a few minutes depending on the amount of data. If no error appears and the normal prompt reappears, the import was successful.

3.2 Verify the import

docker exec -it relution-db mariadb \
  -u root -pHIER_ROOT_PASSWORT_EINSETZEN \
  relution -e "SHOW TABLES;" | head -30

This command lists the first 30 tables of the database. Familiar table names should appear (e.g. databasechangelog, qrtz_triggers, etc.). If the list is empty or an error message appears, please repeat Phase 3.


Phase 4 – Rename table names to uppercase

As explained at the outset: Linux distinguishes between uppercase and lowercase, Windows does not. On Linux, Relution expects table names in uppercase. This step renames all affected tables.

Since a table cannot be renamed directly from beispiel to BEISPIEL (Linux sees this as the same name), the renaming runs in two rounds: first to temporary names (with _tmp), then to the final uppercase names.

4.1 Create the script file

nano /opt/relution/rename_tables.sql

Copy the following content into the editor in full:

Show full configuration example
-- ============================================================
-- Step 1: Rename to temporary names (_tmp)
-- ============================================================
RENAME TABLE
`databasechangelog`         TO `databasechangelog_tmp`,
`databasechangeloglock`     TO `databasechangeloglock_tmp`,
`jgroupsping`               TO `jgroupsping_tmp`,
`qrtz_blob_triggers`        TO `qrtz_blob_triggers_tmp`,
`qrtz_calendars`            TO `qrtz_calendars_tmp`,
`qrtz_cron_triggers`        TO `qrtz_cron_triggers_tmp`,
`qrtz_fired_triggers`       TO `qrtz_fired_triggers_tmp`,
`qrtz_job_details`          TO `qrtz_job_details_tmp`,
`qrtz_locks`                TO `qrtz_locks_tmp`,
`qrtz_paused_trigger_grps`  TO `qrtz_paused_trigger_grps_tmp`,
`qrtz_scheduler_state`      TO `qrtz_scheduler_state_tmp`,
`qrtz_simple_triggers`      TO `qrtz_simple_triggers_tmp`,
`qrtz_simprop_triggers`     TO `qrtz_simprop_triggers_tmp`,
`qrtz_triggers`             TO `qrtz_triggers_tmp`,
`scheduler_lock`            TO `scheduler_lock_tmp`;

-- ============================================================
-- Step 2: Rename to final uppercase names
-- ============================================================
RENAME TABLE
`databasechangelog_tmp`         TO `DATABASECHANGELOG`,
`databasechangeloglock_tmp`     TO `DATABASECHANGELOGLOCK`,
`jgroupsping_tmp`               TO `JGROUPSPING`,
`qrtz_blob_triggers_tmp`        TO `QRTZ_BLOB_TRIGGERS`,
`qrtz_calendars_tmp`            TO `QRTZ_CALENDARS`,
`qrtz_cron_triggers_tmp`        TO `QRTZ_CRON_TRIGGERS`,
`qrtz_fired_triggers_tmp`       TO `QRTZ_FIRED_TRIGGERS`,
`qrtz_job_details_tmp`          TO `QRTZ_JOB_DETAILS`,
`qrtz_locks_tmp`                TO `QRTZ_LOCKS`,
`qrtz_paused_trigger_grps_tmp`  TO `QRTZ_PAUSED_TRIGGER_GRPS`,
`qrtz_scheduler_state_tmp`      TO `QRTZ_SCHEDULER_STATE`,
`qrtz_simple_triggers_tmp`      TO `QRTZ_SIMPLE_TRIGGERS`,
`qrtz_simprop_triggers_tmp`     TO `QRTZ_SIMPROP_TRIGGERS`,
`qrtz_triggers_tmp`             TO `QRTZ_TRIGGERS`,
`scheduler_lock_tmp`            TO `SCHEDULER_LOCK`;

Save and exit: Ctrl + O, Enter, Ctrl + X.

4.2 Run the script

docker exec -i relution-db mariadb \
  -u root -pHIER_ROOT_PASSWORT_EINSETZEN \
  relution < /opt/relution/rename_tables.sql

If no error message appears, the renaming was successful.

4.3 Verify the result

docker exec -it relution-db mariadb \
  -u root -pHIER_ROOT_PASSWORT_EINSETZEN \
  relution -e "SHOW TABLES;"

The output should now show table names in uppercase, for example:

DATABASECHANGELOG
DATABASECHANGELOGLOCK
JGROUPSPING
QRTZ_BLOB_TRIGGERS
...

Phase 5 – Start Relution

Now that the database is correctly populated and prepared, we start the full stack including Relution:

cd /opt/relution
docker compose up -d

5.1 Monitor the startup

docker logs -f relution-app

Follow the output. On its first start, Relution performs various database checks – this can take 1–3 minutes. The startup was successful when a message like the following appears:

Started Relution in XX seconds

Exit the log view with Ctrl + C.

5.2 Open Relution in the browser

Open a browser and access Relution:

http://IP-ADRESSE-DES-SERVERS:8080

Replace IP-ADRESSE-DES-SERVERS with the actual IP address of the Linux server.


Common problems and solutions

“Table doesn’t exist” when running the rename script This means the dump import was not complete. Use SHOW TABLES; to check which tables are missing and repeat Phase 3.

Relution does not start / gets stuck in a loop Check the logs: docker logs relution-app. The most common causes are an incorrect database password in the docker-compose.yml or tables that have not yet been renamed correctly.

The dump file is 0 bytes The export command did not work. Check the path to mysqldump.exe and the database password.

Port 8080 is already in use Another program is using port 8080. In the docker-compose.yml, change the line "8080:8080" to e.g. "8181:8080" and then access Relution on port 8181.

WinSCP does not connect Make sure that the SSH service is running on the Linux server (sudo systemctl status ssh) and that the firewall allows port 22.


Summary of the most important file paths

FilePath on the Linux server
Docker Compose configuration/opt/relution/docker-compose.yml
Database dump/opt/relution/relution_dump.sql
Rename script/opt/relution/rename_tables.sql

Next steps after a successful migration

Once Relution is running and login succeeds:

  • Check whether all devices, users and settings were transferred correctly
  • Set up an SSL certificate (HTTPS) if not already present – guide: SSL certificate setup →
  • Make sure that regular backups of the Docker volumes are set up
  • Only shut down the old Windows Server once the new environment has run stably for several days
Top