TCP/UDP gateway with encrypted tunnels, one-time pairing and Docker Compose configuration.
446
Expose TCP and UDP services on another machine through an encrypted tunnel. Tunlivo combines the original WireGuard tools with nginx stream forwarding in one gateway container.
Internet → Public server → Encrypted tunnel → Client gateway → Your service
The client initiates the tunnel, so it needs no static public IP or router port forwarding. Configure forwarding rules with Docker Compose environment variables. Use one-time-code pairing for a server/client pair, or manual keys for multiple peers.
oliverweinrich/tunlivo:1.0.4 — versioned runtime imageoliverweinrich/tunlivo:latest — latest runtime releaseoliverweinrich/tunlivo:1.0.4-sources — matching source archives, licenses, package inventory and checksums; extraction onlyRuntime platforms: linux/amd64 and linux/arm64.
Use Docker Compose and a Linux host or Docker Desktop Linux VM with WireGuard kernel support.
Allow UDP 51820, TCP 51821 for initial pairing, and the application ports on the public server.
Save this as compose.yaml on your public server:
name: tunlivo-server
services:
gateway:
image: oliverweinrich/tunlivo:1.0.4
restart: unless-stopped
cap_drop: [ALL]
cap_add: [NET_ADMIN, NET_RAW, NET_BIND_SERVICE, SETUID, SETGID]
security_opt: [no-new-privileges:true]
read_only: true
tmpfs: [/run, /tmp]
environment:
PAIR_MODE: server
WG_ADDRESS: '10.66.66.1/24'
PAIR_PEER_ADDRESS: '10.66.66.2/32'
PROXY_ROUTES: |
tcp 8080 10.66.66.2:8080
volumes:
- gateway-state:/data
ports:
- '51820:51820/udp'
- '51821:51821/tcp'
- '8080:8080/tcp'
logging:
driver: json-file
options:
max-size: '10m'
max-file: '3'
volumes:
gateway-state:
Start it and copy the complete invitation beginning with wg1.:
docker compose up -d
docker compose logs gateway
Save this as compose.yaml on the machine hosting your services.
Replace vpn-server.example.com and COMPLETE_INVITATION_FROM_SERVER before starting:
name: tunlivo-client
services:
gateway:
image: oliverweinrich/tunlivo:1.0.4
restart: unless-stopped
cap_drop: [ALL]
cap_add: [NET_ADMIN, NET_RAW, NET_BIND_SERVICE, SETUID, SETGID]
security_opt: [no-new-privileges:true]
read_only: true
tmpfs: [/run, /tmp]
environment:
PAIR_MODE: client
WG_ADDRESS: '10.66.66.2/32'
PAIR_PEER_ADDRESS: '10.66.66.1/32'
PAIR_SERVER: 'vpn-server.example.com:51821'
WG_ENDPOINT: 'vpn-server.example.com:51820'
# Replace with the complete server invitation before the first start.
# Remove after pairing; the association is retained in the volume.
PAIR_CODE: 'COMPLETE_INVITATION_FROM_SERVER'
PROXY_ROUTES: |
tcp 8080 hello:80
volumes:
- gateway-state:/data
logging:
driver: json-file
options:
max-size: '10m'
max-file: '3'
hello:
image: nginx:stable-alpine@sha256:970364228b1e4f932abc22d321932816782cca8a20b85a77552a7cfe9acfb3b5
restart: unless-stopped
volumes:
gateway-state:
docker compose up -d
Open http://YOUR_SERVER:8080: the nginx welcome page is served from the client through the tunnel.
Replace the hello service and PROXY_ROUTES destinations with your own TCP/UDP services.
Each route has the format tcp|udp LISTEN_PORT TARGET_HOST:TARGET_PORT.
Invitations expire after ten minutes. After pairing, remove PAIR_CODE, apply with docker compose up -d, and close public TCP 51821 if desired.
Keep both gateway volumes: they store the keys and association. Do not use docker compose down -v unless you intend to reset pairing.
docker compose stop
docker compose up -d
docker compose logs --tail=30 gateway
docker compose exec gateway wg show
Forwarding supports IPv4, TCP and UDP. Original visitor IPs are not preserved. The health check confirms local gateway operation; it does not prove that a remote service is reachable.
The complete release source and license archives are publicly available in this repository under oliverweinrich/tunlivo:1.0.4-sources.
This is a source-only image with no executable application. Extract it without starting it:
mkdir -p tunlivo-sources
docker create --name tunlivo-source-copy oliverweinrich/tunlivo:1.0.4-sources
docker cp tunlivo-source-copy:/sources/. ./tunlivo-sources/
docker rm tunlivo-source-copy
The directory contains tunlivo-1.0.4-sources.tar.gz, tunlivo-1.0.4-licenses.tar.gz, packages.tsv and SHA256SUMS.
Runtime notices are also included at /usr/share/licenses/tunlivo/.
Tunlivo's original code is licensed under Apache-2.0. Copyright 2026 Oliver Weinrich. Bundled components retain their own licenses.
Tunlivo is an independent project, not an official WireGuard product and not endorsed by or affiliated with its developers. "WireGuard" and the "WireGuard" logo are registered trademarks of Jason A. Donenfeld.
Source code · Configuration reference · Manual-key examples · Third-party notices
Content type
Image
Digest
sha256:96c07852a…
Size
314.2 MB
Last updated
1 day ago
docker pull oliverweinrich/tunlivo