tetherd

tetherd

Docker app from PhilBarker's Repository

Overview

Keeps containers attached to the network of the container they route through, such as apps using --network container:gluetun. When the VPN container restarts, those apps stay running but go offline; Tetherd repairs that with a restart where possible, and only rebuilds when the VPN container was recreated. Clean-room successor to Rebuild-DNDC: it reads live Docker config, not Unraid XML. Stop Rebuild-DNDC before installing. Needs the Docker socket, same trade-off as Watchtower. After install, docker exec tetherd tetherd doctor. Set restart policy to Unless Stopped.
Tetherd

Tetherd

Keeps containers attached to the network of the container they route through.

If you run apps through a VPN sidecar with --network container:gluetun, those apps lose their networking whenever the VPN container restarts or is recreated. Tetherd watches for that and repairs it — preferring a plain restart, and only rebuilding a container when it genuinely has to.

Status: v0.1.1. Public, still early. The image is on Docker Hub; Community Applications listing is next.

Why another one of these

Tetherd is a clean-room successor to Rebuild-DNDC, which is no longer actively maintained. It is not a fork and shares no code. It exists to fix two design problems that caused most of the bugs in the original:

It reads container config from Docker, not from Unraid XML templates. The original rebuilt containers by locating an Unraid template file, guessing its name from the container name, and re-parsing the XML. That picked the wrong template for similarly named containers, silently dropped volumes and ports whenever Unraid changed its template format, and tied the whole tool to Unraid. Tetherd snapshots each managed container's actual configuration from the Docker API, so a rebuild reproduces exactly what was there — labels, mounts, resource limits and all — and works on any Docker host.

It repairs without destroying wherever possible. The original always did stop, rm, then recreate. When the recreate failed, your container was gone. Tetherd distinguishes the two ways networking breaks:

  • The provider was restarted, so its network namespace was replaced. The dependent still looks healthy by every obvious measure but has no network. A plain docker restart fixes it completely. This case is undetectable by comparing container IDs, which is why the original never handled it.
  • The provider was recreated, so it has a new container ID and the dependent cannot start at all. Only here is a rebuild necessary — and Tetherd validates the replacement configuration before touching the existing container, then renames it aside rather than deleting it, so a failure is recoverable.

Deliberately stopped containers also stay stopped.

Running it

The image talks to the host Docker socket. It runs as root for the same reason Watchtower does: that socket is typically root:docker mode 660, and Unraid will not set --group-add for you.

docker run -d \
  --name tetherd \
  --restart unless-stopped \
  -e TZ=Europe/London \
  -e TETHERD_PROVIDER=gluetun \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /path/to/appdata/tetherd:/config \
  philbarker79/tetherd

Published images live on Docker Hub as philbarker79/tetherd and on GHCR as ghcr.io/phil-barker/tetherd. tetherd:local is the tag this repo's Dockerfile builds for development.

On Unraid, also mount notifications, the webGui marker, and the user templates if you want the notification bell and a template audit from tetherd doctor:

-v /tmp/notifications:/tmp/notifications
-v /usr/local/emhttp:/usr/local/emhttp:ro
-v /boot/config/plugins/dockerMan/templates-user:/config/docker-templates:ro

compose.yaml in this repo is the same thing, for a generic Docker host.

Coming from Rebuild-DNDC, stop that container first, then tetherd import-rdndc --env-file old.env. Details in docs/migration.md.

Useful commands, from another shell against a running container:

docker exec tetherd tetherd status
docker exec tetherd tetherd doctor
docker exec tetherd tetherd rebuild qbittorrent --dry-run

More in docs/quick-start.md.

Documentation

Requirements

  • Docker Engine 20.10 or newer
  • Access to the Docker socket
  • Works on Unraid, plain Docker, and Compose-managed containers

Development

uv sync
uv run pytest -m 'not integration'    # unit tests
uv run pytest -m integration          # needs a live daemon
uv run ruff check .
uv run mypy
docker build -t tetherd:local .

scripts/spike-netns.sh verifies the Docker behaviours the design relies on against your local daemon. The findings are written up in docs/design-notes.md.

Release, Docker Hub, and Community Applications steps are in docs/maintainer/publishing.md.

Transparency

I'm Phil Barker. I've been a software engineer for thirty years. This repository is co-developed with Cursor, an AI coding assistant.

I'm putting that in the README because a lot of people in open source and homelab are, reasonably, tired of unreviewed generated code landing on GitHub. I designed the behaviour this tool has to have, I review every change, and the tests encode failure modes that were found the hard way on real Unraid boxes — including mine. Cursor is a faster pair-programmer. It is not an unsupervised author, and it does not get a commit I have not read.

If that still makes this the wrong project for you, that is a fair call. I'd rather you knew how it was made than find out from a git blame later.

Credits

Inspired by Rebuild-DNDC by elmerfds, and by the users who documented its failure modes in that project's issue tracker over the years.

License

MIT

Install Tetherd on Unraid in a few clicks.

Find Tetherd in Community Apps on your Unraid server, review the template, and click Install. Unraid handles the Docker app or plugin setup from the published template.

Open the Apps tab on your Unraid server Search Community Apps for Tetherd Review the template variables and paths Click Install

Requirements

A container whose network others borrow (typically a VPN sidecar such as gluetun). Host access to the Docker socket. Stop Rebuild-DNDC first if it is still running.

Download Statistics

217
Total Downloads

Related apps

Explore more like this

Explore all

Details

Repository
philbarker79/tetherd:latest
Last Updated2026-08-22
First Seen2026-09-01

Runtime arguments

Network
bridge
Shell
bash
Privileged
false

Template configuration

ProviderVariable

Exact name of the VPN/network-provider container (e.g. GluetunVPN). Case-sensitive; match docker ps.

Target
TETHERD_PROVIDER
AppdataPathrw

Snapshots and provider ID history.

Target
/config
Default
/mnt/user/appdata/tetherd
Value
/mnt/user/appdata/tetherd
Docker SocketPathrw

Host Docker socket. Required, same as Watchtower.

Target
/var/run/docker.sock
Default
/var/run/docker.sock
Value
/var/run/docker.sock
Unraid webGuiPathro

Unraid marker and template audit. Not used for notifications.

Target
/usr/local/emhttp
Default
/usr/local/emhttp
Value
/usr/local/emhttp
Unraid notificationsPathrw

Unraid's .notify directory. Required for the notification bell. The host PHP notify script cannot run in this image.

Target
/tmp/notifications
Default
/tmp/notifications
Value
/tmp/notifications
Docker templatesPathro

User templates, read-only, for tetherd doctor. Tetherd never rebuilds from these files.

Target
/config/docker-templates
Default
/boot/config/plugins/dockerMan/templates-user
Value
/boot/config/plugins/dockerMan/templates-user
TimezoneVariable

Container timezone.

Target
TZ
Default
UTC
Value
UTC
IncludeVariable

If set, only these dependents are managed. Exact names, space or comma separated.

Target
TETHERD_INCLUDE
ExcludeVariable

Dependents to leave alone. Exact names, space or comma separated.

Target
TETHERD_EXCLUDE
Probe providerVariable

Actively test that the VPN container can route. Leave false if the image already has a healthcheck (gluetun does).

Target
TETHERD_PROBE__ENABLED
Default
false
Value
false
Notify URLsVariable

Apprise URLs (Discord, Telegram, Gotify, ntfy, …). Unraid's own bell is used when /tmp/notifications is mounted.

Target
TETHERD_NOTIFY__URLS
Log levelVariable

DEBUG, INFO, WARNING or ERROR.

Target
TETHERD_LOG_LEVEL
Default
INFO
Value
INFO