Skip to content
Daniel Heinen edited this page May 9, 2026 · 1 revision

Docker

ankerctl ships as a Docker image (django01982/ankerctl) and a docker-compose.yaml that configures it correctly out of the box. This page covers the standard stack, host networking caveats, multi-architecture builds, the offline / self-hosted MQTT broker variant, and the Home Assistant Supervisor add-on.

Why host networking

services:
  ankerctl:
    network_mode: host

network_mode: host is mandatory. The PPPP protocol is asymmetric UDP — the printer sends LAN discovery responses to the broadcast address 255.255.255.255:32108, and Docker's bridge driver does not forward UDP broadcasts back into the container. Without host networking:

  • LAN discovery hangs at "Connecting"
  • the camera stream never starts
  • file uploads fail

This also means Docker installation works on Linux only. macOS and Windows hosts cannot use network_mode: host (Docker Desktop runs in a VM, isolating the network namespace).

Quick start

git clone https://github.com/Django1982/ankermake-m5-protocol.git
cd ankermake-m5-protocol
cp .env.example .env       # adjust as needed
docker compose up -d

Open http://localhost:4470 and complete account import.

Useful commands:

docker compose pull        # pull the latest image
docker compose up -d       # apply config changes / pull
docker compose down        # stop and remove
docker compose logs -f     # tail logs
docker compose restart     # restart without re-pull

docker-compose.yaml reference

The repo ships docker-compose.yaml. A typical customized version:

services:
  ankerctl:
    image: django01982/ankerctl:latest
    container_name: ankerctl
    network_mode: host
    restart: unless-stopped
    env_file: .env
    volumes:
      - ~/.config/ankerctl:/home/ankerctl/.config/ankerctl
      - ./logs:/logs
      - ./captures:/captures
    healthcheck:
      test: ["CMD", "curl", "-fsS", "http://127.0.0.1:4470/api/health"]
      interval: 30s
      timeout: 5s
      retries: 3

Volume layout:

Container path Purpose
/home/ankerctl/.config/ankerctl default.json, history.db, filament.db, bed_leveling/
/logs Log files (when ANKERCTL_LOG_DIR=/logs)
/captures Timelapse video output (when TIMELAPSE_CAPTURES_DIR=/captures)
/app/ssl Optional SSL certs

.env file

Copy and edit:

cp .env.example .env

Minimal example:

# Bind to all interfaces so the host firewall (or another machine) can reach it
FLASK_HOST=0.0.0.0
FLASK_PORT=4470

# Strongly recommended — write operations require this
ANKERCTL_API_KEY=replace-me-with-a-long-random-string

# Optional features
TIMELAPSE_ENABLED=true
TIMELAPSE_CAPTURES_DIR=/captures
ANKERCTL_LOG_DIR=/logs

See Configuration for every variable, defaults, and behavior.

Building a local image

# Build with current host UID/GID so volume files have correct ownership
docker build \
    --build-arg UID=$(id -u) \
    --build-arg GID=$(id -g) \
    -t django01982/ankerctl:local .

# Or via compose
docker compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g)

Tip After a local rebuild you usually need docker compose up -d --force-recreate for compose to pick up the new image instead of restarting the existing container.

Multi-architecture support

CI publishes images for:

  • linux/amd64
  • linux/arm64
  • linux/arm/v7 (Raspberry Pi 32-bit)

So docker pull django01982/ankerctl:latest works on a Pi 4, an x86 server, or an ARM64 NAS without further flags.

Health check

The container ships with HEALTHCHECK calling GET /api/health. The endpoint always returns {"status": "ok"} with HTTP 200 and requires no auth. The check resolves FLASK_HOST (0.0.0.0 / :: are mapped to 127.0.0.1).

If the container restarts in a loop and your FLASK_HOST is set to a specific IP that does not match 127.0.0.1, the health check fails — explicitly set FLASK_HOST=0.0.0.0 or remove the variable.

Firewall (host)

With network_mode: host the container shares the host's network namespace. The host firewall applies — not Docker's. If you run ufw, allow:

sudo ufw allow in proto udp to any port 32108     # PPPP LAN discovery + session
sudo ufw allow in proto tcp to any port 4470      # web UI / slicer upload

See Firewall ufw for the full background.

Offline / self-hosted MQTT broker

Since v1.10.9 there is a docker-compose_offline.yaml that bundles a local Mosquitto broker as a drop-in replacement for Anker's cloud MQTT. This lets you run ankerctl fully on-premises after the initial account import.

Key components:

  • docker-compose_offline.yaml — compose file with mosquitto and ankerctl services
  • offline/ — Mosquitto config, certificate generation script
  • documentation/offline-feasibility.md — design notes

Pin the local CA to ankerctl with either:

  • CLI flag: --mqtt-ca-cert /app/ssl/ca.crt
  • Env var: ANKERCTL_MQTT_CA_CERT=/app/ssl/ca.crt

This avoids having to disable TLS verification with -k.

Updating

cd /path/to/ankermake-m5-protocol
git pull                       # update compose / docs
docker compose pull            # pull new image
docker compose up -d           # apply

If you build locally:

git pull
docker compose build
docker compose up -d --force-recreate

Uninstalling

docker compose down
docker rmi django01982/ankerctl:latest
# Optional: remove persistent state
rm -rf ~/.config/ankerctl

Home Assistant Supervisor add-on

A separate add-on package lives in hassio-addon/. It builds a dedicated ankermake-m5-protocol-ha image with:

  • full_access: true so AppArmor does not block PPPP UDP discovery
  • Symlink /home/ankerctl/.config/ankerctl/data/.config/ankerctl for persistent state across add-on upgrades
  • run.sh entrypoint that translates HA add-on options into env vars

Add it in HA via Settings → Add-ons → Add-on Store → ⋮ → Repositories with the URL:

https://github.com/Django1982/ankermake-m5-protocol

Then install AnkerMake M5 Protocol from the store.

Troubleshooting

See the dedicated Troubleshooting page. The most common Docker-specific issues are:

  • Container restarts in a loop → check docker logs ankerctl and verify FLASK_HOST matches the health check assumption (use 0.0.0.0).
  • No printer found → host firewall is blocking UDP 32108, or network_mode: host is missing.
  • Permission denied on /home/ankerctl/.config/ankerctl → rebuild the image with the host UID/GID, or chown -R 1000:1000 ~/.config/ankerctl/.
  • Camera / video does not work on macOS or Windows → unsupported, use the Python install instead.

Clone this wiki locally