Skip to content
Login

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.

View on GitHub

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:latest

Headless (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:headless

Quick Start

Full image (with web UI)

Terminal window
docker run -d \
--name hle \
-p 8099:8099 \
-v hle-data:/data \
ghcr.io/hle-world/hle-docker:latest

Open http://your-host:8099 in a browser. Enter your API key in Settings, then add a tunnel.

Headless image (no UI)

Terminal window
docker run -d \
--name hle \
-p 8099:8099 \
-v hle-data:/data \
ghcr.io/hle-world/hle-docker:headless

The 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:
Terminal window
# Start
docker compose up -d
# View logs
docker compose logs -f hle

Environment Variables

VariableDefaultDescription
HLE_API_KEY(empty)Your HLE API key. Can also be set via the web UI or hle config set-key.
HLE_PORT8099Port 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:

Terminal window
# Set your API key
docker 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 tunnels
docker exec hle hle status
# Stop a tunnel
docker exec hle hle stop ha
# See all CLI commands
docker exec hle hle --help

Managing Tunnels via API

The REST API is available on both images at port 8099:

Terminal window
# List tunnels
curl http://localhost:8099/api/tunnels
# Get current configuration
curl http://localhost:8099/api/config
# Update API key
curl -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.

Terminal window
# Pull latest
docker pull ghcr.io/hle-world/hle-docker:latest
# Recreate
docker compose up -d
# Or without compose:
docker stop hle && docker rm hle
docker run -d --name hle -p 8099:8099 -v hle-data:/data ghcr.io/hle-world/hle-docker:latest

For automatic updates, use Watchtower to monitor and auto-update the container.

Building from Source

Terminal window
git clone https://github.com/hle-world/hle-docker.git
cd 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.