Docker
Run HLE tunnels on any Docker host — Synology NAS, Unraid, bare metal servers, VMs, or cloud instances. Choose the full image with a web UI for managing tunnels visually, or the headless image for a lighter, API-and-CLI-only deployment.
Choose Your Mode
Full (With Web UI) — Includes the React dashboard for managing tunnels, access rules, PIN protection, and share links. Best for most users.
ghcr.io/hle-world/hle-docker:latestHeadless (API + CLI Only) — No web UI — manage tunnels via the hle CLI or REST API. Faster build, lighter footprint.
ghcr.io/hle-world/hle-docker:headlessQuick Start
Full image (with web UI)
docker run -d \ --name hle \ -p 8099:8099 \ -v hle-data:/data \ ghcr.io/hle-world/hle-docker:latestOpen http://your-host:8099 in a browser. Enter your API key in Settings, then add a tunnel.
Headless image (no UI)
docker run -d \ --name hle \ -p 8099:8099 \ -v hle-data:/data \ ghcr.io/hle-world/hle-docker:headlessThe API is available at http://your-host:8099/api/. Manage tunnels via CLI or API (see below).
Docker Compose
services: hle: image: ghcr.io/hle-world/hle-docker:latest # or :headless container_name: hle restart: unless-stopped ports: - "8099:8099" volumes: - hle-data:/data environment: - HLE_API_KEY= # optional: set here or via web UI/CLI
volumes: hle-data:# Startdocker compose up -d
# View logsdocker compose logs -f hleEnvironment Variables
| Variable | Default | Description |
|---|---|---|
HLE_API_KEY | (empty) | Your HLE API key. Can also be set via the web UI or hle config set-key. |
HLE_PORT | 8099 | Port the server listens on inside the container. |
Data Persistence
All configuration and tunnel state is stored in /data inside the container. Mount a Docker volume or host directory to persist data across container restarts and upgrades.
Contents: hle_config.json (API key, settings), tunnel definitions, and logs (/data/logs/).
Managing Tunnels via CLI
The hle CLI is available inside both images. Use docker exec to interact with it:
# Set your API keydocker exec hle hle config set-key YOUR_API_KEY
# Expose a local service (e.g. Home Assistant on the Docker host)docker exec hle hle expose --service http://host.docker.internal:8123 --label ha
# List active tunnelsdocker exec hle hle status
# Stop a tunneldocker exec hle hle stop ha
# See all CLI commandsdocker exec hle hle --helpManaging Tunnels via API
The REST API is available on both images at port 8099:
# List tunnelscurl http://localhost:8099/api/tunnels
# Get current configurationcurl http://localhost:8099/api/config
# Update API keycurl -X POST http://localhost:8099/api/config \ -H "Content-Type: application/json" \ -d '{"api_key": "hle_your_key_here"}'Updating
Pull the latest image and recreate the container. Your data is preserved in the volume.
# Pull latestdocker pull ghcr.io/hle-world/hle-docker:latest
# Recreatedocker compose up -d
# Or without compose:docker stop hle && docker rm hledocker run -d --name hle -p 8099:8099 -v hle-data:/data ghcr.io/hle-world/hle-docker:latestFor automatic updates, use Watchtower to monitor and auto-update the container.
Building from Source
git clone https://github.com/hle-world/hle-docker.gitcd hle-docker
# Full image (with web UI)docker build -t hle-docker:local .
# Headless (no UI)docker build -f Dockerfile.headless -t hle-docker:headless .Troubleshooting
Container starts but tunnels don’t connect
Check that your API key is set correctly. View logs with docker logs hle or check /data/logs/ inside the container.
Can’t reach services on the Docker host
Use host.docker.internal instead of localhost in service URLs. On Linux, you may need to add --add-host=host.docker.internal:host-gateway to your docker run command or add extra_hosts: ["host.docker.internal:host-gateway"] in Docker Compose.
Port conflict
If port 8099 is already in use, map to a different host port: -p 9099:8099.