Install Mideye Server with Docker Compose
This guide covers running Mideye Server 6 as a container with Docker Compose, together with a MariaDB database container.
The image is pulled from the Mideye container registry, which requires a Mideye customer account. It is published for linux/amd64 and linux/arm64, and Docker selects the right architecture automatically.
Quick overview
Section titled “Quick overview”- Get your registry credentials from the Mideye Download Center
- Log in to the Mideye container registry
- Create
.envanddocker-compose.yml - Start the containers
- Complete the Configuration Wizard
Time required: 10–20 minutes
Before you begin
Section titled “Before you begin”Requirements:
- A Linux host with Docker Engine and the Docker Compose plugin (
docker compose) - 4 GB RAM minimum (8 GB recommended)
- Outbound HTTPS access to
acrdownloadsprodb5st.azurecr.ioto pull the image - A Mideye customer account for the Mideye Download Center
- Your customer TCP port for the Mideye Switch, assigned by Mideye Support
Step 1: Get registry credentials
Section titled “Step 1: Get registry credentials”The container registry uses the same username and password as the Mideye APT and RPM repositories.
-
Sign in to the Mideye Download Center with your Mideye customer account.
-
Open Repository access in the top menu, or go directly to downloads.mideye.com/repository. Your credentials are created the first time you open this page.
-
Copy the Username and Password. Click Reveal to show the password.
Step 2: Log in to the registry
Section titled “Step 2: Log in to the registry”On the Docker host, log in to the Mideye container registry. Read the password from standard input so it doesn’t end up in your shell history:
docker login acrdownloadsprodb5st.azurecr.io -u <username> --password-stdinPaste the password and press Enter, then Ctrl+D. Docker stores the login, so you only do this once per host (and again after rotating credentials).
Verify that you can pull the image:
docker pull acrdownloadsprodb5st.azurecr.io/mideyeserver:6.5Image tags
Section titled “Image tags”| Tag | Meaning |
|---|---|
6.5 | Latest release in the 6.5 line. Moves forward when a new 6.5.x patch is published. |
6.5.28 | One exact release. Never changes. |
There is no latest tag. Pin an exact version (for example 6.5.28) in production, so an image only changes when you choose to upgrade. The tag for each release is shown on its card on the Download Center page.
Step 3: Create the Compose files
Section titled “Step 3: Create the Compose files”-
Create a directory for the deployment:
Terminal window mkdir -p ~/mideyeserver && cd ~/mideyeserver -
Create a
.envfile with the image tag and database passwords:Terminal window MIDEYE_TAG=6.5MIDEYE_DB_PASSWORD=change-me-db-passwordMIDEYE_DB_ROOT_PASSWORD=change-me-root-passwordRestrict access to the file, since it holds passwords:
Terminal window chmod 600 .env -
Create
docker-compose.yml:services:mideyeserver:image: acrdownloadsprodb5st.azurecr.io/mideyeserver:${MIDEYE_TAG:?set MIDEYE_TAG in .env}restart: unless-stoppeddepends_on:mariadb:condition: service_healthyenvironment:SPRING_PROFILES_ACTIVE: prodSPRING_DATASOURCE_URL: jdbc:mariadb://mariadb:3306/MideyeServerSPRING_DATASOURCE_USERNAME: mideyeSPRING_DATASOURCE_PASSWORD: ${MIDEYE_DB_PASSWORD:?set MIDEYE_DB_PASSWORD in .env}# Serve the web interface over HTTPS on 8443, like the Linux and Windows packages.SERVER_PORT: "8443"SERVER_SSL_ENABLED: "true"ports:- "8443:8443/tcp"- "1812:1812/udp"volumes:# Holds keystore.p12 (TLS and database encryption key) and# application-prod.yml. Losing this volume makes encrypted data unreadable.- mideye-config:/home/mideye/config- mideye-logs:/home/mideye/logsecurity_opt:- no-new-privileges:truecap_drop:- ALLhealthcheck:test: ["CMD", "curl", "--fail", "--silent", "--insecure", "--max-time", "4","https://127.0.0.1:8443/management/health"]interval: 30stimeout: 5sretries: 3start_period: 180smariadb:image: mariadb:11.4restart: unless-stoppedenvironment:MARIADB_DATABASE: MideyeServerMARIADB_USER: mideyeMARIADB_PASSWORD: ${MIDEYE_DB_PASSWORD:?set MIDEYE_DB_PASSWORD in .env}MARIADB_ROOT_PASSWORD: ${MIDEYE_DB_ROOT_PASSWORD:?set MIDEYE_DB_ROOT_PASSWORD in .env}command:- mariadbd- --character-set-server=utf8mb4- --collation-server=utf8mb4_unicode_ci- --explicit_defaults_for_timestamp=ONvolumes:- mideye-db:/var/lib/mysqlhealthcheck:test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]interval: 10stimeout: 5sretries: 10start_period: 30svolumes:mideye-config:mideye-logs:mideye-db:
Step 4: Start Mideye Server
Section titled “Step 4: Start Mideye Server”docker compose up -dThe database starts first. Mideye Server starts once the database reports healthy. On first start the container:
- Generates a self-signed TLS certificate and keystore in the
mideye-configvolume - Creates the database schema
Check that both containers are running and report healthy:
docker compose psStep 5: Complete setup
Section titled “Step 5: Complete setup”-
Get the setup challenge from the logs:
Terminal window docker compose logs mideyeserver | grep "SETUP CHALLENGE" -
Open the web interface:
https://your-server-ip:8443Your browser will warn about the self-signed certificate. You can replace it later. See Certificate management.
-
Complete the Configuration Wizard:
- Setup challenge: paste the code from step 1
- Root password: create the administrator credentials
- Switch connection: enter your customer TCP port
RADIUS starts listening on UDP 1812 once the wizard is complete.
Configuration
Section titled “Configuration”Environment variables
Section titled “Environment variables”| Variable | Description | Value in this guide |
|---|---|---|
SPRING_PROFILES_ACTIVE | Application profile | prod |
SPRING_DATASOURCE_URL | JDBC connection string | jdbc:mariadb://mariadb:3306/MideyeServer |
SPRING_DATASOURCE_USERNAME | Database user | mideye |
SPRING_DATASOURCE_PASSWORD | Database password | From .env |
SERVER_PORT | Web interface port inside the container | 8443 (image default: 8080) |
SERVER_SSL_ENABLED | Serve the web interface over HTTPS | true (image default: false) |
JAVA_OPTS | Extra JVM options, for example -Xmx2g | Empty |
Volumes
Section titled “Volumes”| Volume | Path in container | Contents |
|---|---|---|
mideye-config | /home/mideye/config | keystore.p12 (TLS certificate and database encryption key) and application-prod.yml |
mideye-logs | /home/mideye/log | mideyeserver.log and mideyeserver.error |
mideye-db | /var/lib/mysql | MariaDB data |
| Port | Protocol | Purpose |
|---|---|---|
| 8443 | TCP | Web administration interface (HTTPS) |
| 1812 | UDP | RADIUS authentication |
If you add more RADIUS ports in the web interface, publish them in docker-compose.yml too and run docker compose up -d.
Container management
Section titled “Container management”# Status and healthdocker compose ps
# Follow Mideye Server logsdocker compose logs -f mideyeserver
# Restart Mideye Serverdocker compose restart mideyeserver
# Stop everything (volumes are kept)docker compose stopBackup
Section titled “Backup”Back up both the configuration volume and the database:
# Configuration (keystore.p12 and application-prod.yml)docker compose cp mideyeserver:/home/mideye/config ./backup-config
# Databasedocker compose exec -T mariadb sh -c \ 'mariadb-dump -u root -p"$MARIADB_ROOT_PASSWORD" --single-transaction MideyeServer' > backup.sqlStore the backups securely. backup-config contains the database encryption key. See also Backup.
Upgrade
Section titled “Upgrade”-
Read the Release Notes for the new version.
-
Back up the configuration and database (see Backup).
-
Set the new tag in
.env, for example:Terminal window MIDEYE_TAG=6.5.28If you use the moving
6.5tag, skip this step. -
Pull the new image and recreate the container:
Terminal window docker compose pull mideyeserverdocker compose up -d mideyeserver
The mideye-config volume is reused, so the existing keystore and configuration are kept. Database migrations run automatically on start.
Production considerations
Section titled “Production considerations”External database
Section titled “External database”To use an existing MariaDB or MySQL server, remove the mariadb service and its depends_on entry, and point the datasource at your server:
environment: SPRING_DATASOURCE_URL: jdbc:mariadb://db.example.com:3306/MideyeServer SPRING_DATASOURCE_USERNAME: mideye SPRING_DATASOURCE_PASSWORD: ${MIDEYE_DB_PASSWORD}See Database configuration for how to create the database and user.
High availability
Section titled “High availability”To run several Mideye Server instances against a shared database, configure one of them as Cluster Leader. See Shared database clusters.
Podman
Section titled “Podman”The image is a standard OCI image and also runs under Podman. Rootless Podman rewrites the source IP of RADIUS traffic in the same way as rootless Docker, so run it rootful or with host networking for production.
Troubleshooting
Section titled “Troubleshooting”Container keeps restarting or never becomes healthy
Section titled “Container keeps restarting or never becomes healthy”docker compose logs mideyeserverdocker compose exec mideyeserver cat /home/mideye/log/mideyeserver.errorFirst start can take a few minutes while the database schema is created. The health check allows 180 seconds before it counts failures.
Pulling the image fails
Section titled “Pulling the image fails”| Error | Cause and fix |
|---|---|
unauthorized: authentication required | Wrong or rotated credentials. Copy them again from Repository access and run docker login again. |
...mideyeserver:<tag>: not found | The tag doesn’t exist. Check the tag on the Download Center. A MAJOR.MINOR tag such as 6.6 only exists once that line has a stable release. |
pull access denied ... repository does not exist | Wrong image path. It is acrdownloadsprodb5st.azurecr.io/mideyeserver:<tag>, with nothing between the registry and mideyeserver. |
Database connection errors
Section titled “Database connection errors”Check that MIDEYE_DB_PASSWORD in .env hasn’t changed since the database volume was first created. MariaDB sets the user’s password only on first start.
docker compose logs mariadbRefusing to generate a new keystore
Section titled “Refusing to generate a new keystore”keystore.p12 is missing from the config volume, but application-prod.yml shows that a keystore was generated before. Restore keystore.p12 from your backup rather than generating a new one. A new keystore can’t decrypt existing data.
RADIUS clients all show the same IP
Section titled “RADIUS clients all show the same IP”The container isn’t seeing the real client address. See RADIUS needs the real client IP: use Docker Engine on Linux (rootful), or network_mode: host.

