Migration from Windows to Docker

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

Please read each section in full before running any command.


What happens during this migration?

Your 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

What you need before you start

Make sure the following is available:

  • Access to the Windows Server (directly on site or via Remote Desktop / RDP)
  • The name of your Relution database – if unknown, ask your 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 your Relution database as an SQL file. This file contains all your 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 your system:

dir "C:\Program Files\MariaDB"

You will then see, for example, a folder named MariaDB 10.6 or MariaDB 10.11. Make a note of the exact version number – you will need it in the next step.

1.4 Create the database dump

In the following command, replace 10.11 with your actual MariaDB version number and relution with the name of your 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, you will be prompted for the database password. Enter it (the input is invisible – this is normal) and press Enter.

If no error appears and you see the normal input prompt again, 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

You should see the file 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:

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:

Important: Replace the three placeholders with secure passwords of your choice:

  • HIER_ROOT_PASSWORT_EINSETZEN → e.g. Tr0mmelFeuer!92
  • HIER_RELUTION_PASSWORT_EINSETZEN → e.g. Rel@ution#2024 (both occurrences must be identical!)

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 you have not yet transferred the dump file 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

Caution: There is no space between -p and the password. Replace HIER_ROOT_PASSWORT_EINSETZEN with the root password you assigned in the docker-compose.yml.

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 you see the normal prompt again, 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. You should see familiar table names (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:

-- ============================================================
-- 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;"

In the output you should now see 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 you see a message like:

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 your 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 you can log in successfully:

  • Check whether all devices, users and settings were transferred correctly
  • Set up an SSL certificate (HTTPS) if not already present – guide: https://hub.relution.io/en/docs/installation/installation/certificate/
  • 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