Skip to content

connect to services within your docker network without exposing any ports on the host. use socat and caddy to reach tcp endpoints and enable tls encryption for http servers via tailsacle.

License

Notifications You must be signed in to change notification settings

sudocarlos/tailrelay

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

106 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

tailrelay

A Docker container that exposes local services to your Tailscale network. Combines Tailscale VPN, Caddy reverse proxy, socat TCP relays, and a Web UI for browser-based management.

Docker Pulls GitHub Release License

Features

  • Web UI - Browser-based management on port 8021
  • Automatic TLS - Tailscale HTTPS certificates via Caddy
  • HTTP/HTTPS Proxies - Configure reverse proxies through the UI
  • TCP Relays - Forward non-HTTP protocols with socat
  • Backup & Restore - Save and restore configurations
  • Dual Authentication - Token or Tailscale network authentication
  • Multi-Platform - Docker images for amd64 and arm64

Table of Contents

Why tailrelay?

tailrelay provides secure remote access to self-hosted services:

  • Secure Access: Tailscale's VPN eliminates port forwarding requirements
  • Easy Configuration: Web UI handles setup without manual config files
  • Automatic TLS: Caddy obtains and renews certificates via Tailscale HTTPS
  • Protocol Support: HTTP/HTTPS proxies and TCP relays for any service
  • Backup & Restore: Save and restore configurations

Useful for accessing Start9 services like BTCPayServer, LND, electrs, and Mempool without Tor.

Technology Stack

Component Purpose Documentation
Tailscale VPN, MagicDNS, device authentication Tailscale docs
Caddy HTTP/2 reverse proxy, automatic HTTPS Caddy docs
socat TCP relay for non-HTTP services socat manual
Web UI Browser-based management (Go, HTML/CSS/JS) See Web UI section

Quick Start

# Pull the image
docker pull sudocarlos/tailrelay:latest

# Run the container
docker run -d --name tailrelay \
  -v /path/to/data:/var/lib/tailscale \
  -e TS_HOSTNAME=myserver \
  -p 8021:8021 \
  --net bridge \
  sudocarlos/tailrelay:latest

# Access the Web UI and follow the Tailscale login link
open http://localhost:8021

Web UI

The Web UI provides browser-based management on port 8021.

Features

  • Dashboard - Real-time Tailscale connection status and system health
  • Tailscale Management - Connect/disconnect and view network peers
  • Caddy Proxy Management - Add, edit, delete, and toggle HTTP/HTTPS reverse proxies
  • Socat Relay Management - Start, stop, and restart TCP relay processes
  • Backup & Restore - Create and restore compressed tar.gz backups

Authentication

The Web UI uses two authentication methods:

  1. Tailscale Network Authentication: Devices on your Tailscale network are automatically authenticated. If the container is not connected, the Web UI shows a Tailscale login link and polls until the device is connected.
  2. Token Authentication: A token is generated on first startup at /var/lib/tailscale/.webui_token for scripted access or legacy flows.

Access

The Web UI runs on port 8021:

# Via Tailscale hostname (if HTTPS is enabled)
https://your-hostname.your-tailnet.ts.net:8021

# Or via local IP
http://localhost:8021

Getting Started

Prerequisites

  1. A Tailscale account with an active Tailnet (tailscale.com)
  2. HTTPS certificates enabled in Tailscale Admin console
  3. Docker or Podman installed

Tailscale Setup

  1. Log into Tailscale Admin console and click DNS to enable MagicDNS.
  • Tailnets created on or after October 20, 2022 have MagicDNS enabled by default.
  1. Review MagicDNS to understand how it works.
  2. Verify or set your Tailnet name
  3. Scroll down and enable HTTPS under HTTPS Certificates

Start9 Deployment

Start9 Deployment

  1. SSH into your Start9 server:

    ssh start9@SERVER-HOSTNAME
  2. Create a directory for persistent data:

    mkdir -p /home/start9/tailscale
  3. Run the container:

    sudo podman run --name start9.tailscale \
      -v /home/start9/tailscale/:/var/lib/tailscale \
      -e TS_HOSTNAME=start9 \
      -p 8021:8021 \
      --net start9 \
      docker.io/sudocarlos/tailrelay:latest
  4. Access the Web UI at http://localhost:8021 and follow the login link

Environment Variables:

  • TS_HOSTNAME - Tailnet machine name
  • RELAY_LIST - (Optional, deprecated) Comma-separated relay definitions. Use Web UI instead.
  • MAX_LOG_BODY_SIZE - Max bytes for Caddy API request/response body logging (0 = full body)

Volume Mounts:

  • /var/lib/tailscale - Tailscale state, Web UI configs, backups

Network:

  • --net start9 - Required to access Start9 services

See Tailscale Docker docs for more options.

Development

Local WebUI Development

For rapid iteration without rebuilding the full Docker image:

1. Build the WebUI Assets + Binary

make frontend-build
make dev-build

This compiles ./data/tailrelay-webui with build metadata (version, commit, date) and embeds the SPA assets.

Dev asset override: Set WEBUI_DEV_DIR to a directory that contains templates/ and static/ (for example, webui/cmd/webui/web) to serve assets from disk instead of the embedded files.

Manual build:

cd webui
CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo \
  -ldflags="-w -s" \
  -o ../data/tailrelay-webui ./cmd/webui

2. Development Options

Option A: Mount Binary (Recommended)

Mount the local binary for instant updates:

# compose-test.yml
services:
  tailrelay:
    volumes:
      - ./data/tailrelay-webui:/usr/bin/tailrelay-webui:ro
      - ./tailscale/:/var/lib/tailscale

Then restart:

docker compose -f compose-test.yml restart tailrelay

Iteration workflow:

  1. Edit code in webui/ or webui/frontend/
  2. Run make frontend-build (if frontend changed)
  3. Run make dev-build
  4. Restart container
  5. Test changes

Option B: Build Development Image

make dev-docker-build

This builds a Docker image using the local binary.

Building

# Development build with local binary
make frontend-build
make dev-build
make dev-docker-build

# Production build (multi-stage)
docker buildx build -t sudocarlos/tailrelay:latest .

# Show available targets
make help

Testing

# Python test suite
python docker-compose-test.py

# Bash test suite
./docker-compose-test.sh

Setup:

  1. Copy .env.example to .env
  2. Edit variables (TAILRELAY_HOST, TAILNET_DOMAIN)
  3. Run tests

Build Metadata

The dev-build target injects build information:

var (
  version = "dev"      // Git describe output
  commit  = "none"     // Short commit hash
  date    = "unknown"  // Build timestamp (UTC)
  branch  = "unknown"  // Git branch
  builtBy = "local"    // System username
)

Access these in webui/cmd/webui/main.go.

Troubleshooting

Web UI Not Accessible

Check container status:

docker ps | grep tailrelay

Verify port mapping:

docker port tailrelay

Check logs:

docker logs tailrelay | grep -i webui

Verify listening port:

docker exec tailrelay netstat -tulnp | grep 8021

Cannot Log In

Retrieve token:

docker exec tailrelay cat /var/lib/tailscale/.webui_token

Ensure you're accessing from Tailscale network or clear browser cache.

Caddy Proxy Issues

Validate configuration:

docker exec tailrelay caddy validate --config /etc/caddy/Caddyfile

Check Caddy logs:

docker logs tailrelay | grep -i caddy

Socat Relay Issues

Check relay status:

docker exec tailrelay ps aux | grep socat

Verify listening ports:

docker exec tailrelay netstat -tulnp | grep socat

Test target connectivity:

docker exec tailrelay nc -zv target-host target-port

Contributing

Contributions welcome:

Development Setup

# Clone repository
git clone https://github.com/sudocarlos/tailscale-socaddy-proxy.git
cd tailscale-socaddy-proxy

# Build locally
docker build -t tailrelay:dev .

# Run tests
docker-compose -f compose-test.yml up

See Development section for WebUI development workflow.

Release Notes

  • v0.3.0 - Logging, custom CA certs, and proxy management improvements
  • v0.2.1 - Caddy API integration
  • v0.2.0 - Web UI release

License

Open source project. See repository for license details.

Acknowledgments

About

connect to services within your docker network without exposing any ports on the host. use socat and caddy to reach tcp endpoints and enable tls encryption for http servers via tailsacle.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Go 54.1%
  • HTML 25.3%
  • JavaScript 9.8%
  • Shell 4.3%
  • CSS 3.7%
  • Python 1.5%
  • Other 1.3%