Docker
Run honk from the ghcr.io/daeuniverse/honk image on GitHub Container Registry. The image contains the musl full release binary and the GeoIP and Geosite files pinned by the repository; the build checks every download against its SHA-256 checksum.
Each release is tagged with its version without the v, for example ghcr.io/daeuniverse/honk:0.1.0-beta.4. latest follows formal releases only, never pre-releases. Images are published for linux/amd64 and linux/arm64, and pulling needs no login.
Use the sudo tab if sudo is configured for your account. Use the root tab when already in a root shell.
1. Check the host
The container runs privileged in the host's network and PID namespaces, because honk loads and attaches eBPF programs, creates dae0 and the daens namespace, changes sysctls and pins maps on the host's bpffs. It therefore changes the host exactly as a native installation does and provides no isolation.
The host must meet the kernel requirements, including Linux 6.12+ and a mounted bpffs.
The steps also need Docker Engine with the Compose plugin, and curl. Check Compose with the command below; it prints the Compose version when the plugin is installed.
sudo docker compose versiondocker compose version2. Prepare the configuration
Prepare /etc/honk/config.dae and /var/lib/honk as described in Minimal configuration.
The image embeds doona. To enable it, add this block to your configuration, or merge it into an existing experimental block:
experimental {
native_api {
enabled: true
listen: '127.0.0.1:9527'
password_auth: true
config_write: true
ui: 'embedded'
}
}3. Start the container
Before starting the container, stop and disable each native service that is installed. Run the dae command only if dae is installed, and the honk command only if native honk is installed.
sudo systemctl disable --now dae.service
sudo systemctl disable --now honk.servicesystemctl disable --now dae.service
systemctl disable --now honk.serviceDownload the repository's docker-compose.yml and write the release version to .env:
curl -fLO https://raw.githubusercontent.com/daeuniverse/honk/main/docker-compose.yml
echo 'HONK_VERSION=<version>' > .env # for example 0.1.0-beta.4If the host uses an external BTF file, set it up as described in step 5 first. Create the lock file, then start the container and follow its logs:
sudo touch /run/honk-core.lock
sudo docker compose up -d
sudo docker compose logs -ftouch /run/honk-core.lock
docker compose up -d
docker compose logs -fThe compose file mounts /sys, /etc/honk and /var/lib/honk from the host. The configuration mount replaces the image's direct-only default, and /var/lib/honk keeps the runtime state, such as the native API administrator account, across restarts and upgrades.
The container uses the host network, so the web UI listens on the host’s loopback address.
On the honk host, open http://127.0.0.1:9527/ui/ and create the administrator account on first access.
4. Keep the lock file across reboots
The lock-file bind shares the native instance's /run/honk-core.lock, preventing containers from taking over an active datapath. Leave this file in place after stopping; never delete, replace or truncate an active lock.
It must exist before automatic container startup on every boot. On systemd hosts, arrange non-truncating boot-time creation:
echo 'f /run/honk-core.lock 0600 root root -' | sudo tee /etc/tmpfiles.d/honk-container.conf
sudo systemd-tmpfiles --create /etc/tmpfiles.d/honk-container.confecho 'f /run/honk-core.lock 0600 root root -' > /etc/tmpfiles.d/honk-container.conf
systemd-tmpfiles --create /etc/tmpfiles.d/honk-container.confOn other init systems, create the file without truncation before the container's boot-time start. Direct docker run or podman run deployments must bind the same lock file too.
5. Use an external BTF file (optional)
If the host uses an external raw BTF file instead of /sys/kernel/btf/vmlinux, save this as docker-compose.override.yml beside docker-compose.yml. Compose loads it for every command, including upgrades. Adjust source to the host's raw BTF file; the environment variable names the mounted path inside the container:
services:
honk:
environment:
HONK_VMLINUX_BTF: /run/honk-vmlinux
volumes:
- type: bind
source: /usr/lib/debug/boot/vmlinux
target: /run/honk-vmlinux
read_only: true
bind:
create_host_path: false6. Reload and inspect
Reload the configuration:
sudo docker compose exec honk honk-core reloaddocker compose exec honk honk-core reloadThe image ships iproute2 and nftables, and the container shares the host's network namespace, so these commands show the host's state:
sudo docker compose exec honk ip rule
sudo docker compose exec honk ip route show table all
sudo docker compose exec honk tc filter show dev <interface> ingress
sudo docker compose exec honk nft list rulesetdocker compose exec honk ip rule
docker compose exec honk ip route show table all
docker compose exec honk tc filter show dev <interface> ingress
docker compose exec honk nft list rulesetNext steps
- First sign-in: open http://127.0.0.1:9527/ui/ and create the administrator account.
- Manage nodes, groups and rules: add nodes or subscriptions and routing rules; until then all traffic goes direct.
- Troubleshooting: what to check when something does not work.
7. Upgrade
Change HONK_VERSION in .env and recreate the container:
sudo docker compose pull
sudo docker compose up -ddocker compose pull
docker compose up -dIn a repository checkout, docker compose build (sudo docker compose build with sudo) builds the same image from the published release instead of pulling it.
8. Uninstall
From the directory containing docker-compose.yml, stop and remove the container:
sudo docker compose downdocker compose downThe host directories /etc/honk and /var/lib/honk, the Compose files and .env, and /etc/tmpfiles.d/honk-container.conf remain. The downloaded image and /run/honk-core.lock also remain; do not delete or replace a lock that another instance may hold.
