A container image designed to run on Start9 that exposes local services to your Tailscale network, using Caddy as an HTTP reverse proxy and socat for other non‑HTTP protocols.
Accessing Start9 services such as BTCPayServer and electrs RPC requires Tor today.
Tailscale lets you privately and securely expose your services, while
Caddy takes care of obtaining and renewing TLS certificates.
socat relays the non-HTTP ports Caddy can’t reverse‑proxy.
This container image combines them
| Component | Purpose | Docs |
|---|---|---|
| Start9 | Local container orchestration & file persistence | Start9 docs |
| Tailscale | Zero‑configuration VPN, MagicDNS, and device authentication | Tailscale docs |
| Caddy | Modern HTTP/2 reverse proxy, automatic Let's Encrypt integration | Caddy docs |
| socat | One‑shot TCP relay for non‑HTTP services | socat manual |
- A Start9 server
- A Tailscale with an active Tailnet
- HTTPS certificates enabled in Tailscale Admin console > DNS
- Log into the Tailscale Admin console and click DNS
- Verify or set your Tailnet name
- Scroll down and Enable HTTPS under HTTPS Certificates
-
Login to your Start9, see https://docs.start9.com/0.3.5.x/user-manual/ssh
ssh start9@SERVER-HOSTNAME -
Create a directory to persist Tailscale and Caddy files
mkdir -p /home/start9/tailscale -
Create the Caddyfile below or
Caddyfile.examplenano /home/start9/tailscale/Caddyfile -
⚠️ Files are removed by Start9 on reboot. Back up/home/start9/tailscale⚠️
# Caddyfile
start9.your-tailnet.ts.net:21000 {
reverse_proxy https://lnd.embassy:8080 {
header_up Host {upstream_hostport}
transport http {
tls_trust_pool file /var/lib/tailscale/tls.cert
}
}
}
start9.your-tailnet.ts.net:21001 {
reverse_proxy http://mempool.embassy:8080 {
header_up Host {upstream_hostport}
}
}
start9.your-tailnet.ts.net:21002 {
reverse_proxy http://btcpayserver.embassy:80 {
header_up Host {upstream_hostport}
trusted_proxies private_ranges
}
}
start9.your-tailnet.ts.net:21003 {
reverse_proxy http://jam.embassy:80 {
header_up Host {upstream_hostport}
}
}
- Replace
start9with the Tailscale machine name you want, this must match-e TS_HOSTNAME=inpodman run - Replace
your-tailnet.ts.netwith your Tailnet name - This example lists some common services. Feel free to discover and add more
- See https://caddyserver.com/docs/caddyfile/patterns#reverse-proxy for more info
/home/start9/tailscale
- Finally, run the container
sudo podman run --name start9.tailscale \
-v /home/start9/tailscale/:/var/lib/tailscale \
-v /home/start9/tailscale/Caddyfile:/etc/caddy/Caddyfile \
-e TS_HOSTNAME=start9 \
-e RELAY_LIST=50001:electrs.embassy:50001,21004:lnd.embassy:10009 \
--net start9 \
docker.io/sudocarlos/tailrelay:latest
TS_HOSTNAME- your desired Tailnet machine name. This should match in your CaddyfileRELAY_LIST- optional, comma‑separatedlistener_port:target_host:target_portpairs for socat listeners
Example:50001:electrs.embassy:50001,21004:lnd.embassy:10009-v- volume mounts. Only change values on the left of:if you decide to place files in your Start9 in a different directory- See https://tailscale.com/kb/1282/docker for more info
The repository includes two helper scripts that build the image, launch a test
environment with docker‑compose, run a series of health checks, and then shut
down the containers again.
.env.example
This file contains the environment variables required for the test container
to connect to a running Tailscale network.
Copy it to a local .env file and edit the values as needed, e.g.:
cp .env.example .env
# Edit variables (TAILRELAY_HOST, TAILNET_DOMAIN, COMPOSE_FILE)Once the .env file is set, any of the following scripts will pick it up:
docker-compose-test.py– pure Python implementation (requiresdockeranddocker‑composePython packages).docker-compose-test.sh– Bash wrapper that reads the same environment variables.
# From the repository root
# 1. Test with Python script
python docker-compose-test.py
# 2. Test with Bash script
./docker-compose-test.sh