Skip to content

Latest commit

 

History

History
353 lines (248 loc) · 9.46 KB

File metadata and controls

353 lines (248 loc) · 9.46 KB

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

StartOS Deployment

tailrelay is available as a StartOS package via sudocarlos/tailrelay-startos.

Sideloading:

  1. Download the latest tailrelay.s9pk from the tailrelay-startos releases page, or clone the repo and run make to build it yourself.
  2. In the StartOS web UI menu, navigate to System → Sideload Service.
  3. Drag and drop or select the tailrelay.s9pk file to install.
  4. Once installed, navigate to Services → Tailrelay and click Start.

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/tailrelay.git
cd tailrelay

# 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