Sign inSign up

oliverweinrich/tunlivo

By oliverweinrich

•Updated 1 day ago

TCP/UDP gateway with encrypted tunnels, one-time pairing and Docker Compose configuration.

Image
Networking
0

446

oliverweinrich/tunlivo repository overview

⁠Tunlivo

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.

⁠Images

  • oliverweinrich/tunlivo:1.0.4 — versioned runtime image
  • oliverweinrich/tunlivo:latest — latest runtime release
  • oliverweinrich/tunlivo:1.0.4-sources — matching source archives, licenses, package inventory and checksums; extraction only

Runtime platforms: linux/amd64 and linux/arm64.

⁠Requirements

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.

⁠Example: 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

⁠Example: client

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.

⁠Operation

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.

⁠Matching sources and licenses

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⁠

Tag summary

Content type

Image

Digest

sha256:96c07852a…

Size

314.2 MB

Last updated

1 day ago

docker pull oliverweinrich/tunlivo