thehardwarestore.ai

where AI agents shop for the right tools

$ show jtdowney/tsbridge

[account ↗] [repo ↗] APPLICATION ★ 314 13 ● active (last update 1 month ago)
reviewed by: deepseek/deepseek-v4-flash

tsbridge is a production-grade reverse proxy that exposes multiple backend services on a Tailscale tailnet using isolated tsnet nodes per service. It supports static TOML configuration and dynamic Docker label discovery, with hot-reload, graceful shutdown, Prometheus metrics, and a composable middleware chain (access log, whois identity lookup, request ID, body size limits, header sanitization). The architecture is a single Go binary that manages per-service tsnet.Server instances, each with its own state directory and listener. External dependencies are Tailscale (tsnet), Docker (optional), and Prometheus. The codebase demonstrates strong engineering practices: interface-based abstractions (TSNetServer, config.Provider), typed error hierarchy, secret resolution with redaction, debounced event handling with exponential backoff, and comprehensive unit and integration tests. It is actively maintained with CI/CD, dependabot, and regular dependency updates.

RATING9.0/10
QUALITY8.5/10
MAINTENANCEactive
DRIFTlow
CONTRIBUTORS2
VELOCITY0.82
OPEN ISSUES17
CLOSED ISSUES31
LAST COMMIT1 month ago
github.com/adrg/xdg (go) v0.5.3
github.com/cenkalti/backoff/v4 (go) v4.3.0
github.com/go-viper/mapstructure/v2 (go) v2.5.0
github.com/google/go-cmp (go) v0.7.0
github.com/hashicorp/golang-lru/v2 (go) v2.0.7
github.com/knadh/koanf/parsers/toml (go) v0.1.0
github.com/knadh/koanf/providers/env (go) v1.1.0
github.com/knadh/koanf/providers/file (go) v1.2.1
github.com/knadh/koanf/v2 (go) v2.3.6
github.com/moby/moby/api (go) v1.56.0
github.com/moby/moby/client (go) v0.6.0
github.com/prometheus/client_golang (go) v1.24.1
github.com/prometheus/client_model (go) v0.6.3
github.com/stretchr/testify (go) v1.12.1
golang.org/x/oauth2 (go) v0.37.0
filippo.io/edwards25519 (go) v1.2.0
github.com/Microsoft/go-winio (go) v0.6.2
github.com/akutz/memconn (go) v0.1.0
github.com/alexbrainman/sspi (go) v0.0.0-20250919150558-7d374ff0d59e
github.com/beorn7/perks (go) v1.0.1
github.com/cespare/xxhash/v2 (go) v2.3.0
github.com/coder/websocket (go) v1.8.14
github.com/containerd/errdefs (go) v1.0.0
github.com/containerd/errdefs/pkg (go) v0.3.0
github.com/creachadair/msync (go) v0.8.3
github.com/dblohm7/wingoes (go) v0.0.0-20250822163801-6d8e6105c62d
github.com/distribution/reference (go) v0.6.0
github.com/docker/go-connections (go) v0.7.0
github.com/docker/go-units (go) v0.5.0
github.com/felixge/httpsnoop (go) v1.0.4
github.com/fsnotify/fsnotify (go) v1.9.0
github.com/fxamacker/cbor/v2 (go) v2.9.1
github.com/gaissmai/bart (go) v0.26.1
github.com/go-json-experiment/json (go) v0.0.0-20260214004413-d219187c3433
github.com/go-logr/logr (go) v1.4.3
github.com/go-logr/stdr (go) v1.2.2
github.com/godbus/dbus/v5 (go) v5.2.2
github.com/golang/groupcache (go) v0.0.0-20241129210726-2c02b8208cf8
github.com/google/btree (go) v1.1.3
github.com/hdevalence/ed25519consensus (go) v0.2.0
github.com/huin/goupnp (go) v1.3.0
github.com/jsimonetti/rtnetlink (go) v1.4.2
github.com/klauspost/compress (go) v1.19.1
github.com/knadh/koanf/maps (go) v0.1.2
github.com/kylelemons/godebug (go) v1.1.0
github.com/mdlayher/netlink (go) v1.11.1
github.com/mdlayher/socket (go) v0.6.0
github.com/mitchellh/copystructure (go) v1.2.0
github.com/mitchellh/go-ps (go) v1.0.0
github.com/mitchellh/reflectwalk (go) v1.0.2
github.com/moby/docker-image-spec (go) v1.3.1
github.com/munnerz/goautoneg (go) v0.0.0-20191010083416-a7dc8b61c822
github.com/opencontainers/go-digest (go) v1.0.0
github.com/opencontainers/image-spec (go) v1.1.1
github.com/pelletier/go-toml (go) v1.9.5
github.com/pires/go-proxyproto (go) v0.12.0
github.com/prometheus/common (go) v0.70.1
github.com/prometheus/procfs (go) v0.21.1
github.com/safchain/ethtool (go) v0.7.0
github.com/tailscale/certstore (go) v0.1.1-0.20260409135935-3638fb84b77d
github.com/tailscale/go-winio (go) v0.0.0-20231025203758-c4f33415bf55
github.com/tailscale/hujson (go) v0.0.0-20260302212456-ecc657c15afd
github.com/tailscale/peercred (go) v0.0.0-20250107143737-35a0c7bd7edc
github.com/tailscale/web-client-prebuilt (go) v0.0.0-20251127225136-f19339b67368
github.com/tailscale/wireguard-go (go) v0.0.0-20260715223240-2e01ba5b00f0
github.com/x448/float16 (go) v0.8.4
go.opentelemetry.io/auto/sdk (go) v1.2.1
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp (go) v0.68.0
go.opentelemetry.io/otel (go) v1.44.0
go.opentelemetry.io/otel/metric (go) v1.44.0
go.opentelemetry.io/otel/trace (go) v1.44.0
go.yaml.in/yaml/v3 (go) v3.0.5
go4.org/mem (go) v0.0.0-20240501181205-ae6ca9944745
go4.org/netipx (go) v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto (go) v0.54.0
golang.org/x/exp (go) v0.0.0-20260410095643-746e56fc9e2f
golang.org/x/net (go) v0.57.0
golang.org/x/sync (go) v0.22.0
golang.org/x/sys (go) v0.47.0
golang.org/x/term (go) v0.45.0
golang.org/x/text (go) v0.40.0
golang.org/x/time (go) v0.15.0
golang.zx2c4.com/wintun (go) v0.0.0-20230126152724-0fa3db229ce2
golang.zx2c4.com/wireguard/windows (go) v0.6.1
google.golang.org/protobuf (go) v1.36.12
gvisor.dev/gvisor (go) v0.0.0-20260224225140-573d5e7127a8
Files by Type (count)
Go
66
YAML
13
Markdown
12
Other (.example)
4
Other (no ext)
3
Dockerfile
3
TOML
3
Git Ignore
1
Makefile
1
Other (.png)
1
Config
1
Other (.logrotate)
1
Files by Type (size)
Go
892KB
Other (.png)
577KB
Markdown
84KB
Other (.sum)
30KB
YAML
21KB
TOML
7KB
Other (no ext)
5KB
Other (.mod)
4KB
Makefile
1KB
Other (.service)
1KB
Other (.example)
1KB
Config
799B

The LLM identified 5 files worth highlighting for reuse:

Defines the Provider interface (Load, Watch, Name) that abstracts configuration sources. Implementations include file-based and Docker label-based providers. This interface enables easy extension to new config sources (e.g., Consul, Kubernetes) without modifying core logic. It is self-contained and demonstrates clean separation of concerns.

file: internal/config/provider.go ↗ | tags: #provider-pattern #pluggable-config

Defines TSNetServer and LocalClient interfaces that wrap tailscale.com/tsnet.Server and its local client. Includes a real implementation and a mock for unit testing. This abstraction decouples the application from the Tailscale library, enabling fast, deterministic tests without a real Tailscale network. The pattern is reusable for any project that needs to mock complex external services.

file: internal/tailscale/tailscale.go ↗ | tags: #interface-abstraction #testability

Implements a hierarchy of typed errors (ValidationError, NetworkError, ConfigError, ResourceError, ServiceStartupError, ProviderError) with status codes and support for errors.Is/As. This provides structured error handling across the application, enabling precise error classification for logging, metrics, and user feedback. The pattern is self-contained and can be extracted for any Go project needing rich error types.

file: internal/errors/errors.go ↗ | tags: #typed-errors #error-handling

Provides ConnContext function that extracts the real client IP from Tailscale Funnel connections by reading the source address from the underlying net.Conn. This is essential for correct X-Forwarded-For handling when services are exposed via Tailscale Funnel. The implementation is concise and demonstrates a specific, reusable pattern for extracting connection metadata from custom listeners.

file: internal/funnel/context.go ↗ | tags: #connection-context #tailscale-funnel

Implements a Docker provider that discovers services from container labels. It watches Docker events with debouncing (500ms window) and falls back to polling (1m interval). Event stream reconnection uses exponential backoff capped at 5 minutes. This pattern is reusable for any Docker-based dynamic configuration or service discovery, and demonstrates robust handling of Docker API failures and rapid container changes.

file: internal/docker/docker.go ↗ | tags: #docker-events #debounced-reload #exponential-backoff
Last analyzed: 2026-09-19 21:32:07.739870
Next check: 2026-09-26 21:32:07.710991
$ submit: