Deploy Management with Docker or Podman
Running the Management image with Docker or rootful Podman on an operator workstation or an operator-created Linux VM is a supported deployment option. It runs the same Management web application as the Management ISO. You manage the host operating system, container runtime, networking, time synchronization, TLS and persistent storage yourself.
The commands below start a fresh instance. They do not install the appliance nodes or change an existing Management instance.
Runtime Versions
Use these minimum versions for this guide. Install a maintained patch release that meets or exceeds them.
| Component | Minimum version | Requirement |
|---|---|---|
Docker Engine and CLI |
28.0 |
Run Linux containers. Enable the containerd image store when exporting release or update bundles for Management. |
Docker Desktop on Windows or macOS |
4.39.0 |
Use its Linux engine. This Desktop release includes Docker Engine 28 and supports the archive-export commands. |
Docker Compose plugin |
2.17.0 |
Required for the Compose option, which uses |
Podman |
5.0 |
Use rootful Podman on Linux. This is the Podman baseline for the examples in this guide. |
Check Docker’s client and server versions with docker version, the Compose plugin with docker compose version, or Podman with podman version.
Docker’s platform-specific image export requires Engine API 1.48 or later. See the Docker Desktop 4.39 release notes, Compose 2.17 release notes and Podman 5.0 command reference for the corresponding tool capabilities.
Prepare the Host
-
Reserve 2 CPUs, 4 GiB RAM and 100 GB of persistent storage for Management, in addition to the host’s own needs. On Docker Desktop, allocate these resources to its Linux engine.
-
Use a rootful Linux Docker Engine, including Docker Desktop on Windows and macOS, or rootful Podman on Linux. Use a Management image built for the engine’s native AMD64 or ARM64 architecture. The Podman example below targets Linux AMD64, matching the ISO runtime. Rootless runtimes are outside these examples.
-
Check that the container can reach the appliance nodes, DNS, NTP and any required registries. Keep the workstation and its container engine awake during installation, updates, backups and recovery.
-
Choose a Management DNS name and a host IP address reachable by its operators. Reserve host ports
80and443, or choose another HTTPS port before first start. -
Choose an unused private internal node IP, default
10.41.0.1. It must not overlap host destinations, the container bridge, or the K3s pod and service networks10.42.0.0/16and10.43.0.0/16.
Management runs K3s inside a privileged container. Use a trusted workstation or dedicated VM whose administrators may access Management credentials. Do not mount the container engine socket or the host root filesystem into Management.
On a Linux host, load bridge netfilter before starting the container. Configure the host to load it again after reboot:
sudo modprobe br_netfilter
For Docker Desktop, kernel configuration belongs to its Linux engine, not the Windows or macOS host.
Start with Docker Compose
Docker Compose starts Management from a configuration file. Use this instead of the direct Docker or Podman commands below. The files use MTG’s Management Compose configuration and default to image tag 1.0.0. Supply the administrator password through the shell.
Download compose.yaml and template.env into a new directory for this Management instance, or copy the following blocks into files with those names.
name: mtg-ers-vapp
services:
management:
image: repo.mtg.de/releases/ers/vapp/management:${MTG_MANAGEMENT_VERSION:-1.0.0}
hostname: management
pull_policy: ${MTG_MANAGEMENT_PULL_POLICY}
privileged: true
restart: unless-stopped
environment:
- APPLIANCE_HOSTNAME=${MTG_MANAGEMENT_HOSTNAME}
- APPLIANCE_NODE_IP=${MTG_MANAGEMENT_NODE_IP-10.41.0.1}
- APPLIANCE_HTTPS_PORT=${MTG_MANAGEMENT_HTTPS_PORT}
- APPLIANCE_ACME_DIRECTORY_URL=${MTG_MANAGEMENT_ACME_DIRECTORY_URL:-}
- APPLIANCE_ACME_EMAIL=${MTG_MANAGEMENT_ACME_EMAIL:-}
- APPLIANCE_DNS_FORWARDER_ENABLED=${MTG_MANAGEMENT_DNS_FORWARDER_ENABLED:-true}
- INITIAL_GITEA_ADMIN_PASSWORD=${INITIAL_GITEA_ADMIN_PASSWORD:?Export the initial Management password before running Compose}
ports:
- "${MTG_MANAGEMENT_BIND_ADDRESS}:${MTG_MANAGEMENT_HTTP_PORT}:30080/tcp"
- "${MTG_MANAGEMENT_BIND_ADDRESS}:${MTG_MANAGEMENT_HTTPS_PORT}:30443/tcp"
volumes:
- management-data:/var
- type: bind
source: ${MTG_MANAGEMENT_TLS_DIRECTORY:-./tls}
target: /run/management-appliance/tls
read_only: true
volumes:
management-data:
# Review the tag and network values before the first start.
MTG_MANAGEMENT_VERSION=1.0.0
# Use never after loading the image on a disconnected Docker host.
MTG_MANAGEMENT_PULL_POLICY=missing
MTG_MANAGEMENT_BIND_ADDRESS=127.0.0.1
MTG_MANAGEMENT_HTTP_PORT=80
MTG_MANAGEMENT_HTTPS_PORT=443
MTG_MANAGEMENT_HOSTNAME=management-appliance.localhost
# Choose a nonconflicting private IPv4 address; keep it fixed for this volume.
MTG_MANAGEMENT_NODE_IP=10.41.0.1
MTG_MANAGEMENT_TLS_DIRECTORY=./tls
MTG_MANAGEMENT_DNS_FORWARDER_ENABLED=true
# Leave empty when supplying tls/tls.crt and tls/tls.key.
MTG_MANAGEMENT_ACME_DIRECTORY_URL=
MTG_MANAGEMENT_ACME_EMAIL=
# Supply INITIAL_GITEA_ADMIN_PASSWORD from the shell, not this file.
Install the Docker Compose plugin and sign in with MTG repository credentials. In the directory containing the two files, prepare the configuration:
cp template.env .env
chmod 600 .env
mkdir -p tls
Review .env before starting. If MTG supplied a different Management tag for your deployment, set MTG_MANAGEMENT_VERSION to that tag. The default address and hostname allow browser access on the same workstation. For an operator-created VM, set MTG_MANAGEMENT_BIND_ADDRESS to the VM’s reachable IP and MTG_MANAGEMENT_HOSTNAME to its DNS name. Keep the hostname, HTTPS port and private node IP fixed after initialization.
Place the hostname certificate and key in tls/tls.crt and tls/tls.key. Allow container UID/GID 65532 to read the pair and traverse the directory. On Linux, a dedicated TLS directory can use group 65532, mode 0750 for the directory and 0640 for the files. Protect the key from other host users.
Alternatively, set the ACME directory URL and email in .env and leave tls/ empty. ACME HTTP-01 requires the CA to reach the Management hostname on port 80. A complete supplied pair takes precedence over ACME. Verify the certificate after startup; internal health does not prove certificate issuance.
In Bash, read the initial password, validate the configuration without printing its contents, and start Management:
read -r -s -p 'Initial Management administrator password: ' INITIAL_GITEA_ADMIN_PASSWORD
printf '\n'
export INITIAL_GITEA_ADMIN_PASSWORD
# The password must contain at least 12 characters.
docker compose --env-file .env --file compose.yaml config --quiet
docker compose --env-file .env --file compose.yaml up --detach --wait --wait-timeout 900
unset INITIAL_GITEA_ADMIN_PASSWORD
The named volume is mtg-ers-vapp_management-data by default. Compose’s project name prefixes it, so it is separate from the direct docker run example’s management-data volume. Preserve the Compose project name, volume and TLS directory when resuming the same instance. Do not add --volumes to docker compose down; that would delete Management data.
Open the configured Management HTTPS URL and sign in as mtg-admin. Continue with bundle setup and appliance installation.
For later Compose commands, export the password again to supply the required environment field. It does not reset the administrator password in existing state. These commands inspect, stop and resume this deployment:
docker compose --env-file .env --file compose.yaml ps
docker compose --env-file .env --file compose.yaml logs --tail 100 --follow management
# Stop after active operations finish; retain the data volume.
docker compose --env-file .env --file compose.yaml stop --timeout 120
# Resume using the same files, project and volume.
docker compose --env-file .env --file compose.yaml up --detach --wait --wait-timeout 900
Compose sets restart: unless-stopped. Management resumes when the Docker engine restarts unless you stopped it explicitly. Keep the host available during operations and manage Docker startup with the host operating system.
Select the Image and Settings for a Direct Launch
Follow Download images and bundles to sign in to repo.mtg.de with MTG-provided credentials and pull the Management image. Use the image tag supplied for your deployment; the Management image and appliance release need not have identical version numbers.
Run the following in Bash. Replace each example value. For the Podman workflow, use a root shell on the Linux container host for login, pull and the commands below so they share the same image store and credentials.
MANAGEMENT_TAG='REPLACE_WITH_MTG_MANAGEMENT_TAG'
MANAGEMENT_IMAGE="repo.mtg.de/releases/ers/vapp/management:${MANAGEMENT_TAG}"
MANAGEMENT_DNS='management.example.com'
MANAGEMENT_BIND_IP='192.0.2.10'
MANAGEMENT_HTTPS_PORT='443'
MANAGEMENT_NODE_IP='10.41.0.1'
TLS_DIRECTORY="$PWD/management-tls"
MANAGEMENT_BIND_IP must be an address assigned to the container host. Configure MANAGEMENT_DNS to resolve to it. For access only from the workstation running Docker, use 127.0.0.1 and a hostname resolving to that address. Remote operators need a routable address and matching firewall rules. The public hostname, HTTPS port and internal node IP are fixed after the data volume is initialized.
Prepare TLS and the Administrator Password
Create management-tls on the container host. Place a PEM certificate chain for MANAGEMENT_DNS in tls.crt and its matching unencrypted private key in tls.key. Keep this directory access-controlled and allow container UID/GID 65532, used by Traefik, to traverse it and read both files. For a private CA, establish trust on operator workstations before sign-in.
The examples mount this directory read-only. The ISO console’s certificate staging workflow does not apply to a container on your own host. Without a supplied pair or ACME configuration, Management falls back to an ephemeral, non-hostname TLS certificate; do not use that fallback as the deployment’s persistent TLS identity.
Read the initial administrator password without putting its value in shell history. Use at least 12 characters. Keep shell tracing disabled:
read -r -s -p 'Initial Management administrator password: ' INITIAL_GITEA_ADMIN_PASSWORD
printf '\n'
export INITIAL_GITEA_ADMIN_PASSWORD
The runtime receives the password through the environment. Container-host administrators can inspect that environment and the persisted bootstrap data. Protect both the host and the data volume.
Start the Container
Run this after pulling the selected image and preparing the settings above:
docker volume create management-data
docker run -d \
--name management-appliance \
--hostname management-appliance \
--privileged \
--pull=never \
-e "APPLIANCE_HOSTNAME=$MANAGEMENT_DNS" \
-e "APPLIANCE_HTTPS_PORT=$MANAGEMENT_HTTPS_PORT" \
-e "APPLIANCE_NODE_IP=$MANAGEMENT_NODE_IP" \
-e INITIAL_GITEA_ADMIN_PASSWORD \
-p "$MANAGEMENT_BIND_IP:80:30080" \
-p "$MANAGEMENT_BIND_IP:$MANAGEMENT_HTTPS_PORT:30443" \
--mount "type=bind,source=$TLS_DIRECTORY,target=/run/management-appliance/tls,readonly" \
-v management-data:/var \
"$MANAGEMENT_IMAGE"
unset INITIAL_GITEA_ADMIN_PASSWORD
docker logs --tail 100 --follow management-appliance
Exit the log view with Ctrl+C; the container continues running. Check readiness with the image’s health probe:
docker exec management-appliance /opt/management-appliance/scripts/healthcheck.sh
Use rootful Podman on the Linux host. Run the settings and password commands in the same root shell as these commands. Choose either this workflow or Docker for an instance.
podman volume create management-data
podman network create mtg-management
podman run -d \
--name management-appliance \
--hostname management-appliance \
--privileged \
--cgroupns=private \
--network mtg-management \
--pull=never \
-e "APPLIANCE_HOSTNAME=$MANAGEMENT_DNS" \
-e "APPLIANCE_HTTPS_PORT=$MANAGEMENT_HTTPS_PORT" \
-e "APPLIANCE_NODE_IP=$MANAGEMENT_NODE_IP" \
-e INITIAL_GITEA_ADMIN_PASSWORD \
-p "$MANAGEMENT_BIND_IP:80:30080" \
-p "$MANAGEMENT_BIND_IP:$MANAGEMENT_HTTPS_PORT:30443" \
--mount "type=bind,source=$TLS_DIRECTORY,target=/run/management-appliance/tls,readonly" \
-v management-data:/var \
"$MANAGEMENT_IMAGE"
unset INITIAL_GITEA_ADMIN_PASSWORD
podman logs --tail 100 --follow management-appliance
Exit the log view with Ctrl+C, then check readiness directly. This also works when an image import has not retained container health-check metadata:
podman exec management-appliance /opt/management-appliance/scripts/healthcheck.sh
Sign in and install the Appliance
First startup can take several minutes while Management imports its internal images. Wait for the health probe to succeed. Open management.example.com/, using your chosen hostname and adding the HTTPS port if it is not 443. Verify the expected certificate and sign in as mtg-admin with the initial password.
A healthy internal probe does not prove that DNS, the host firewall or the browser’s certificate trust is correct. Check those separately if the page is unreachable.
Continue with Make bundles available, then Install the appliance. Docker or Podman registry login does not configure registry credentials inside Management.
Stop, resume and retain State
Complete active operations and retain the generated artifact bundle outside Management before stopping it. Use the command for your runtime:
docker stop --time 120 management-appliance
docker start management-appliance
podman stop --time 120 management-appliance
podman start management-appliance
The direct Docker and Podman launch commands require an explicit start after a host reboot. For an always-on operator VM, configure startup and graceful shutdown through your host’s service manager after verifying the deployment.
The named volume mounted at /var retains Management’s application state, repositories, registry credentials, images and logs. Keep it across container recreation and keep the same public hostname, HTTPS port and internal node IP. Do not share one volume between two running instances. The TLS directory is retained separately. Saving the Management image to a tar file does not preserve the data volume or TLS directory.
A restart ends Management’s in-memory appliance access. Reconnect with the retained artifact bundle when needed. The appliance continues running when Management stops. Consult Security and hardening for host access, network restrictions and storage protection.