### Start tsbridge First Source: https://github.com/jtdowney/tsbridge/blob/main/example/multi-compose/README.md This is the recommended approach to start the example. It first starts tsbridge, which creates the shared Docker network, and then starts the application services, which utilize the existing network. ```bash # Start tsbridge (creates the network) docker compose -f tsbridge-compose.yml up -d # Start services (uses existing network) docker compose -f services-compose.yml up -d ``` -------------------------------- ### Create Network Manually First Source: https://github.com/jtdowney/tsbridge/blob/main/example/multi-compose/README.md An alternative method to start the example is by manually creating the shared Docker network before starting the compose services. This allows the compose files to be started in any order. ```bash # Create network manually docker network create tsbridge-shared-network # Start both (any order) docker compose -f tsbridge-compose.yml up -d docker compose -f services-compose.yml up -d ``` -------------------------------- ### Copy Example Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Copy the example TOML configuration file to the tsbridge configuration directory and customize it. ```bash cp /path/to/tsbridge/deployments/freebsd/config.example.toml /usr/local/etc/tsbridge/config.toml ``` -------------------------------- ### Run Headscale Self-Hosted Setup Source: https://github.com/jtdowney/tsbridge/blob/main/example/README.md Navigate to the 'headscale' directory, start Docker Compose, create a user and pre-authentication key, set the TS_AUTHKEY environment variable, and restart services. ```bash cd headscale docker compose up -d # Create user and auth key docker compose exec headscale headscale users create testuser docker compose exec headscale headscale --user 1 preauthkeys create --reusable --expiration 90d # Set auth key and restart export TS_AUTHKEY="" docker compose up -d tsbridge tailscale-client ``` -------------------------------- ### Run Multi-Compose Setup Source: https://github.com/jtdowney/tsbridge/blob/main/example/README.md Navigate to the 'multi-compose' directory, set OAuth credentials, start tsbridge with its compose file, and then start services with their compose file to use shared networking. ```bash cd multi-compose export TS_OAUTH_CLIENT_ID="your-client-id" export TS_OAUTH_CLIENT_SECRET="your-client-secret" # Start tsbridge first (creates shared network) docker compose -f tsbridge-compose.yml up -d # Start services (uses external network) docker compose -f services-compose.yml up -d ``` -------------------------------- ### Install tsbridge Systemd Service Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/systemd/README.md Steps to create a user, install the binary, set up configuration directories, and install the systemd service file. ```bash sudo useradd --system --shell /bin/false --home-dir /var/lib/tsbridge --create-home tsbridge sudo install -o root -g root -m 755 tsbridge /usr/local/bin/ sudo install -d -o tsbridge -g tsbridge -m 755 /etc/tsbridge sudo install -o tsbridge -g tsbridge -m 640 config.toml /etc/tsbridge/ sudo install -o tsbridge -g tsbridge -m 600 tsbridge.env.example /etc/tsbridge/tsbridge.env sudo install -m 644 tsbridge.service /etc/systemd/system/ sudo systemctl daemon-reload sudo systemctl start tsbridge sudo systemctl enable tsbridge ``` -------------------------------- ### Complete tsbridge Docker Compose Example Source: https://github.com/jtdowney/tsbridge/blob/main/docs/docker-labels.md A comprehensive example of a Docker Compose setup for tsbridge, including service definitions, networks, volumes, and environment variables. ```yaml services: tsbridge: image: ghcr.io/jtdowney/tsbridge:latest command: ["--provider", "docker", "--verbose"] volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - tsbridge-state:/var/lib/tsbridge networks: - app-network environment: - TS_OAUTH_CLIENT_ID=${TS_OAUTH_CLIENT_ID} - TS_OAUTH_CLIENT_SECRET=${TS_OAUTH_CLIENT_SECRET} labels: - "tsbridge.tailscale.oauth_client_id_env=TS_OAUTH_CLIENT_ID" - "tsbridge.tailscale.oauth_client_secret_env=TS_OAUTH_CLIENT_SECRET" - "tsbridge.tailscale.state_dir=/var/lib/tsbridge" - "tsbridge.global.metrics_addr=:9090" ports: - "9090:9090" # Metrics api: image: myapp/api:latest networks: - app-network labels: - "tsbridge.enabled=true" - "tsbridge.service.name=api" - "tsbridge.service.port=8080" - "tsbridge.service.whois_enabled=true" web: image: myapp/web:latest networks: - app-network labels: - "tsbridge.enabled=true" - "tsbridge.service.name=web" - "tsbridge.service.port=3000" - "tsbridge.service.access_log=false" volumes: tsbridge-state: networks: app-network: ``` -------------------------------- ### Run Basic TOML Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/example/README.md Navigate to the 'simple' directory and set OAuth credentials before starting the services with Docker Compose. ```bash cd simple export TS_OAUTH_CLIENT_ID="your-client-id" export TS_OAUTH_CLIENT_SECRET="your-client-secret" docker compose up ``` -------------------------------- ### Build tsbridge from Source Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Clone the tsbridge repository, navigate into the directory, build the binary, and install it to /usr/local/bin. ```bash git clone https://github.com/jtdowney/tsbridge.git cd tsbridge make build install -m 755 tsbridge /usr/local/bin/ ``` -------------------------------- ### Download and Install tsbridge Binary (amd64) Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Download the latest tsbridge binary for amd64 architecture, extract it, and install it to /usr/local/bin. ```bash # For amd64 fetch https://github.com/jtdowney/tsbridge/releases/latest/download/tsbridge_VERSION_freebsd_amd64.tar.gz tar -xzf tsbridge_VERSION_freebsd_amd64.tar.gz install -m 755 tsbridge /usr/local/bin/ ``` -------------------------------- ### Start Services with Multiple Compose Files Source: https://github.com/jtdowney/tsbridge/blob/main/docs/docker-labels.md Use the docker compose command with the -f flag to start services defined in separate compose files. ```bash # Start tsbridge docker compose -f tsbridge-compose.yml up -d # Start services (in any order) docker compose -f services-compose.yml up -d ``` -------------------------------- ### Download and Install tsbridge Binary (arm64) Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Download the latest tsbridge binary for arm64 architecture, extract it, and install it to /usr/local/bin. ```bash # For arm64 fetch https://github.com/jtdowney/tsbridge/releases/latest/download/tsbridge_VERSION_freebsd_arm64.tar.gz tar -xzf tsbridge_VERSION_freebsd_arm64.tar.gz install -m 755 tsbridge /usr/local/bin/ ``` -------------------------------- ### Install tsbridge using Go Source: https://github.com/jtdowney/tsbridge/blob/main/README.md Installs the latest version of tsbridge using the Go toolchain. Ensure Go is installed and configured on your system. ```bash go install github.com/jtdowney/tsbridge/cmd/tsbridge@latest ``` -------------------------------- ### Configuration Structure Example Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Basic TOML structure for tsbridge configuration, showing sections for Tailscale, global settings, and service definitions. ```toml [tailscale] # Tailscale authentication and settings [global] # Default settings for all services [[services]] # Service definitions (multiple allowed) ``` -------------------------------- ### Backend Address Configuration Example Source: https://github.com/jtdowney/tsbridge/blob/main/docs/docker-labels.md Illustrates the correct way to specify a backend address using the service port, emphasizing the use of container names over 'localhost'. ```yaml # Good - uses container name - "tsbridge.service.port=8080" # Bad - localhost is the tsbridge container! - "tsbridge.service.backend_addr=localhost:8080" ``` -------------------------------- ### Basic tsbridge Configuration Example Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md A minimal TOML configuration for tsbridge, specifying Tailscale authentication details and a sample service. ```toml # Tailscale authentication (required) [tailscale] oauth_client_id_file = "/usr/local/etc/tsbridge/oauth_client_id" oauth_client_secret_file = "/usr/local/etc/tsbridge/oauth_client_secret" state_dir = "/var/db/tsbridge" default_tags = ["tag:server", "tag:tsbridge"] # Global defaults (optional) [global] access_log = true metrics_addr = ":9100" whois_timeout = "1s" # Services (at least one required) [[services]] name = "wiki" backend_addr = "127.0.0.1:8080" whois_enabled = true ``` -------------------------------- ### Install tsbridge rc.d Script Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Copy the tsbridge rc.d script to the system's service directory to enable management via the init system. ```bash # Copy the rc.d script install -m 755 tsbridge /usr/local/etc/rc.d/tsbridge ``` -------------------------------- ### Run Docker Labels Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/example/README.md Navigate to the 'docker-labels' directory and set OAuth credentials before starting the services with Docker Compose for dynamic service discovery. ```bash cd docker-labels export TS_OAUTH_CLIENT_ID="your-client-id" export TS_OAUTH_CLIENT_SECRET="your-client-secret" docker compose up ``` -------------------------------- ### tsbridge Environment Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/systemd/README.md Example environment variables for tsbridge OAuth credentials. ```bash TS_OAUTH_CLIENT_ID=your-client-id TS_OAUTH_CLIENT_SECRET=your-client-secret ``` -------------------------------- ### Complete tsbridge TOML Configuration Example Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md A comprehensive TOML configuration file for tsbridge, demonstrating settings for Tailscale integration, global timeouts, backend connections, observability, security, limits, and service definitions. ```toml [tailscale] oauth_client_id_env = "TS_OAUTH_CLIENT_ID" oauth_client_secret_file = "/etc/tsbridge/oauth-secret" state_dir = "/var/lib/tsbridge" default_tags = ["tag:server", "tag:proxy"] [global] # Timeouts read_header_timeout = "30s" write_timeout = "30s" idle_timeout = "120s" shutdown_timeout = "30s" # Backend connection dial_timeout = "10s" response_header_timeout = "0s" # Observability metrics_addr = ":9090" access_log = true # Security trusted_proxies = ["10.0.0.0/8"] # Limits max_request_body_size = "50MB" [[services]] name = "api" backend_addr = "api.internal:8080" tags = ["tag:api", "tag:prod"] whois_enabled = true downstream_headers = { "Strict-Transport-Security" = "max-age=63072000" } [[services]] name = "streaming" backend_addr = "localhost:4000" write_timeout = "0s" flush_interval = "-1ms" max_request_body_size = "-1" [[services]] name = "admin" backend_addr = "unix:///var/run/admin.sock" whois_enabled = true funnel_enabled = false access_log = true ``` -------------------------------- ### Validate tsbridge Configuration Syntax Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Check the syntax of the tsbridge configuration file before starting the service. ```bash /usr/local/bin/tsbridge -config /usr/local/etc/tsbridge/config.toml -validate ``` -------------------------------- ### tsbridge TOML Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/systemd/README.md Example TOML configuration for tsbridge, including Tailscale and service settings. ```toml [tailscale] # OAuth credentials come from environment state_dir = "/var/lib/tsbridge" # Or omit - systemd sets STATE_DIRECTORY default_tags = ["tag:server"] # oauth_preauthorized = false # Require manual device approval (default: true) [global] metrics_addr = ":9090" [[services]] name = "your-service" backend_addr = "localhost:8080" ``` -------------------------------- ### Enable tsbridge Service in rc.conf Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Configure tsbridge to start automatically on boot by adding entries to /etc/rc.conf. This includes basic enablement, custom configuration file paths, user/group settings, and environment variables. ```bash # Basic configuration tsbridge_enable="YES" # Optional: Custom configuration file location tsbridge_config="/usr/local/etc/tsbridge/config.toml" # Optional: Run as different user/group tsbridge_user="tsbridge" tsbridge_group="tsbridge" # Optional: Additional command line flags tsbridge_flags="" # Optional: Environment variables tsbridge_env="GOMAXPROCS=4" # Optional: Process limits (see limits(1)) tsbridge_limits="-n 65535" # Max file descriptors ``` -------------------------------- ### Troubleshoot Network Not Found Errors Source: https://github.com/jtdowney/tsbridge/blob/main/example/multi-compose/README.md If you receive 'network not found' errors, ensure that tsbridge is started first to create the network, or manually create the network using 'docker network create tsbridge-shared-network' before starting the compose files. ```bash # Option 1: Start tsbridge first # Option 2: docker network create tsbridge-shared-network ``` -------------------------------- ### tsbridge Service Commands Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Common commands to manage the tsbridge service lifecycle. Use these to start, stop, check status, reload configuration, and enable/disable the service from starting at boot. ```bash # Start the service service tsbridge start # Stop the service service tsbridge stop # Check service status service tsbridge status # Reload configuration (if supported by tsbridge) service tsbridge reload # Enable service to start at boot sysrc tsbridge_enable="YES" # Disable service from starting at boot sysrc tsbridge_enable="NO" ``` -------------------------------- ### tsbridge Configuration with Tag Hierarchies Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Example TOML configuration for tsbridge demonstrating the use of tag hierarchies with OAuth, specifying environment variables for credentials and service-specific tags. ```toml [tailscale] oauth_client_id_env = "TS_OAUTH_CLIENT_ID" oauth_client_secret_env = "TS_OAUTH_CLIENT_SECRET" # These tags must be owned by tag:tsbridge in your ACL default_tags = ["tag:server", "tag:proxy"] [[services]] name = "api" backend_addr = "localhost:8080" tags = ["tag:server", "tag:prod"] # Both owned by tag:tsbridge ``` -------------------------------- ### Running tsbridge with Environment Variables Source: https://github.com/jtdowney/tsbridge/blob/main/docs/quickstart.md This command exports your OAuth client ID and secret as environment variables and then starts the tsbridge service using the specified configuration file. Make sure to replace 'your-client-id' and 'your-client-secret' with your actual credentials. ```bash export TS_OAUTH_CLIENT_ID=your-client-id export TS_OAUTH_CLIENT_SECRET=your-client-secret tsbridge -config tsbridge.toml ``` -------------------------------- ### Export OAuth Credentials Source: https://github.com/jtdowney/tsbridge/blob/main/example/multi-compose/README.md Before running the example, export your Tailscale OAuth credentials as environment variables. These are required for tsbridge authentication. ```bash export TS_OAUTH_CLIENT_ID="your-client-id" export TS_OAUTH_CLIENT_SECRET="your-client-secret" ``` -------------------------------- ### Clean Up Network and Volumes Source: https://github.com/jtdowney/tsbridge/blob/main/example/multi-compose/README.md Completely remove all containers, networks, and volumes associated with both tsbridge and the application services. Use this to fully reset the example environment. ```bash docker compose -f tsbridge-compose.yml down -v docker compose -f services-compose.yml down -v ``` -------------------------------- ### Stop Application Services Source: https://github.com/jtdowney/tsbridge/blob/main/example/multi-compose/README.md Stop and remove the containers defined in the services compose file. This is part of the shutdown procedure for the example. ```bash docker compose -f services-compose.yml down ``` -------------------------------- ### FreeBSD Jail Configuration for tsbridge Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Example configuration for a FreeBSD jail named 'tsbridge' in `/etc/jail.conf`. Ensure Tailscale connectivity and backend service accessibility from the jail network. ```freebsd tsbridge { host.hostname = tsbridge.local; ip4.addr = "lo0|10.0.0.10/32"; ip6 = "new"; exec.start = "/bin/sh /etc/rc"; exec.stop = "/bin/sh /etc/rc.shutdown"; mount.devfs; persist; } ``` -------------------------------- ### Build and Run with Config Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Builds the application and runs it, specifying a configuration file. ```makefile make run ARGS="-config example.toml" ``` -------------------------------- ### Auth Key Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Illustrates the configuration options for an auth key, supporting direct value, file path, and environment variable. ```toml # Auth key - choose one method: auth_key = "tskey-auth-..." # Direct value (highest priority) auth_key_file = "/etc/tsbridge/authkey" # From file (second priority) auth_key_env = "TS_AUTHKEY" # From environment variable (third priority) # Will fallback to TS_AUTHKEY env var if none of the above are specified ``` -------------------------------- ### Stop tsbridge Source: https://github.com/jtdowney/tsbridge/blob/main/example/multi-compose/README.md Stop and remove the tsbridge container defined in its compose file. This is part of the shutdown procedure for the example. ```bash docker compose -f tsbridge-compose.yml down ``` -------------------------------- ### Format Code Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Applies standard Go code formatting to the project. ```makefile make fmt ``` -------------------------------- ### Create tsbridge Directories Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Create necessary directories for tsbridge configuration, runtime data, logs, and database, setting appropriate ownership and permissions. ```bash # Configuration directory install -d -o root -g wheel -m 755 /usr/local/etc/tsbridge # Runtime directories (will be created by rc script, but can be pre-created) install -d -o tsbridge -g tsbridge -m 750 /var/run/tsbridge install -d -o tsbridge -g tsbridge -m 750 /var/log/tsbridge install -d -o tsbridge -g tsbridge -m 750 /var/db/tsbridge ``` -------------------------------- ### Run All Tests Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Executes all unit tests within the project using Go's testing framework. ```makefile make test ``` -------------------------------- ### Build and Push Docker Images Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Builds multi-architecture Docker images and pushes them with a SHA tag. ```makefile make docker-push-sha ``` -------------------------------- ### Build Release Binaries Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Creates release binaries using goreleaser, typically involving tagging. ```makefile make release ``` -------------------------------- ### Run Tests with Coverage Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Executes all tests and generates a code coverage report. ```go go test -cover ./... ``` -------------------------------- ### Run Integration Tests Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Executes the integration test suite, requiring the 'integration' build tag. ```makefile make integration ``` -------------------------------- ### Tailscale ACL Policy for Tag Ownership Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Example JSONC configuration for Tailscale ACLs to define tag ownership, specifying parent tags and their owned service tags. ```jsonc { "tagOwners": { "tag:tsbridge": [], // Parent tag for OAuth client "tag:server": ["tag:tsbridge"], "tag:proxy": ["tag:tsbridge"], "tag:prod": ["tag:tsbridge"], "tag:dev": ["tag:tsbridge"] } } ``` -------------------------------- ### Other Tailscale Options Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Configuration for state directory, default tags, control server URL, and OAuth preauthorization. ```toml # State directory for tsnet data state_dir = "/var/lib/tsbridge" # Direct path state_dir_env = "CUSTOM_STATE_DIR" # From environment variable # Default tags for all services (required when using OAuth) default_tags = ["tag:server", "tag:proxy"] # Control server URL (for Headscale or custom servers) control_url = "https://headscale.example.com" # Preauthorize OAuth-generated auth keys (optional - defaults to true) # Set to false to require manual approval of devices in the admin console # Can be overridden per-service: set [[services]].oauth_preauthorized = false # Breaking change: Default is now true; set to false if you require manual approval. oauth_preauthorized = false ``` -------------------------------- ### Build Release Snapshot Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Builds release binaries without creating a git tag. ```makefile make release-snapshot ``` -------------------------------- ### Configure Docker Socket via Environment Variable Source: https://github.com/jtdowney/tsbridge/blob/main/docs/docker-labels.md Configure tsbridge to connect to the Docker daemon using the DOCKER_HOST environment variable, commonly used in Docker Compose setups. ```yaml services: tsbridge: image: ghcr.io/jtdowney/tsbridge:latest command: ["--provider", "docker"] environment: - DOCKER_HOST=unix:///var/run/docker.sock - TS_OAUTH_CLIENT_ID=${TS_OAUTH_CLIENT_ID} - TS_OAUTH_CLIENT_SECRET=${TS_OAUTH_CLIENT_SECRET} # ... ``` -------------------------------- ### Validating tsbridge Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/docs/quickstart.md This command validates the tsbridge configuration file without starting the service. It's a useful step for ensuring your TOML file is correctly formatted and all required fields are present. ```bash tsbridge -config tsbridge.toml -validate ``` -------------------------------- ### Server and Backend Timeouts Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Configure various server and backend connection timeouts using Go duration format. Set to '0s' to disable timeouts. ```toml # Server timeouts read_header_timeout = "30s" # Time to read request headers (default: 30s) write_timeout = "30s" # Time to write response (default: 30s) idle_timeout = "120s" # Keep-alive timeout (default: 120s) shutdown_timeout = "15s" # Graceful shutdown timeout (default: 15s) startup_timeout = "30s" # Tailscale server startup timeout (default: 30s) # Backend connection timeouts dial_timeout = "30s" # Time to establish connection (default: 30s) response_header_timeout = "0s" # Time to wait for backend headers (default: 0s = no timeout) keep_alive_timeout = "30s" # Keep-alive probe interval (default: 30s) idle_conn_timeout = "90s" # Idle connection timeout (default: 90s) tls_handshake_timeout = "10s" # TLS handshake timeout (default: 10s) expect_continue_timeout = "1s" # 100-continue timeout (default: 1s) # Metrics endpoint timeout metrics_read_header_timeout = "5s" # Header read timeout for metrics (default: 5s) ``` -------------------------------- ### Lint Code Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Runs golangci-lint to check for code style and potential issues. ```makefile make lint ``` -------------------------------- ### Basic Service Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Defines a service with its name and backend address. Service tags can override default tags. ```toml [[services]] name = "api" # Required: becomes api..ts.net backend_addr = "localhost:8080" # Required: where to proxy to tags = ["tag:api", "tag:prod"] # Service tags (overrides default_tags) ``` -------------------------------- ### Service Overview Queries Source: https://github.com/jtdowney/tsbridge/blob/main/docs/metrics.md A collection of PromQL queries for monitoring service overview metrics, including request rate, error rate, P95 latency, and active services. ```promql # Request rate sum(rate(tsbridge_requests_total[5m])) by (service) ``` ```promql # Error rate sum(rate(tsbridge_requests_total{status!~"2.."}[5m])) by (service) ``` ```promql # P95 latency histogram_quantile(0.95, sum by (service, le)(rate(tsbridge_request_duration_seconds_bucket[5m]))) ``` ```promql # Active services tsbridge_services_active ``` -------------------------------- ### Backend Address Formats Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Illustrates various formats for specifying backend addresses, including TCP, HTTPS, and Unix sockets. ```toml # TCP addresses backend_addr = "localhost:8080" # backend_addr = "10.0.0.5:3000" # backend_addr = "backend.internal:80" # HTTPS backends # backend_addr = "https://api.example.com:443" # backend_addr = "https://self-signed.internal" # insecure_skip_verify = true # Skip TLS certificate verification (default: false) # Unix sockets # backend_addr = "unix:///var/run/app.sock" ``` -------------------------------- ### OAuth Client ID Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Demonstrates different methods for configuring the OAuth client ID, including direct value, file path, and environment variable. ```toml # Client ID - choose one method: oauth_client_id = "k12...89" # Direct value (highest priority) oauth_client_id_file = "/etc/tsbridge/oauth-id" # From file (second priority) oauth_client_id_env = "TS_OAUTH_CLIENT_ID" # From environment variable (third priority) # Will fallback to TS_OAUTH_CLIENT_ID env var if none of the above are specified ``` -------------------------------- ### Vet Code Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Runs go vet to statically analyze the code for suspicious constructs. ```makefile make vet ``` -------------------------------- ### Configuring Streaming and SSE Support Source: https://github.com/jtdowney/tsbridge/blob/main/docs/quickstart.md To enable streaming or Server-Sent Events (SSE) support, set `write_timeout` to `"0s"` to disable timeouts and `flush_interval` to `"-1ms"` to disable buffering. This ensures data is sent immediately without delay. ```toml [[services]] name = "events" backend_addr = "localhost:3000" write_timeout = "0s" # No timeout flush_interval = "-1ms" # No buffering ``` -------------------------------- ### Build tsbridge Binary Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Builds the main application binary, incorporating the git SHA for versioning. ```makefile make build ``` -------------------------------- ### Run tsbridge with Static Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/README.md Execute tsbridge using a Docker container, mounting a local configuration file and setting environment variables for OAuth credentials. ```bash docker run -v /path/to/config:/config \ -e TS_OAUTH_CLIENT_ID=... \ -e TS_OAUTH_CLIENT_SECRET=... \ ghcr.io/jtdowney/tsbridge:latest -config /config/tsbridge.toml ``` -------------------------------- ### Service-Specific Overrides Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Demonstrates overriding global settings like timeouts and request body size for a specific service. ```toml [[services]] name = "streaming" backend_addr = "localhost:8080" # Override timeouts startup_timeout = "60s" # More time for Tailscale startup write_timeout = "0s" # No timeout for streaming response_header_timeout = "30s" # Different from global flush_interval = "-1ms" # Immediate flushing # Override other settings access_log = false # Disable for this service max_request_body_size = "100MB" # Larger uploads allowed ``` -------------------------------- ### Create External Docker Network Source: https://github.com/jtdowney/tsbridge/blob/main/docs/docker-labels.md Before using multiple compose files, create a shared Docker network using the docker network create command. ```bash docker network create tsbridge-network ``` -------------------------------- ### Troubleshoot Network Connection Refused Source: https://github.com/jtdowney/tsbridge/blob/main/example/multi-compose/README.md If you encounter 'connection refused' errors, ensure the service is listening on the correct port, test direct container-to-container connectivity, and check if the service containers are running. ```bash # Verify service port # Test connectivity: docker exec tsbridge-container ping service-container # Check service status: docker compose -f services-compose.yml ps ``` -------------------------------- ### Response Handling Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Configure response buffering and request body size limits. Choose between default buffering, immediate flushing for streaming, or periodic flushing. The body size can be set in bytes, human-readable format, or unlimited. ```toml # Flush interval for response buffering - choose one: flush_interval = "0s" # Default buffering (default) # flush_interval = "-1ms" # Immediate flushing (for streaming) # flush_interval = "100ms" # Flush every 100ms # Request body size limit - choose one: max_request_body_size = "52428800" # In bytes (default: 50MB) # max_request_body_size = "10MB" # Human readable format # max_request_body_size = "-1" # No limit ``` -------------------------------- ### OAuth Client Secret Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Shows how to configure the OAuth client secret using direct value, file path, or environment variable. ```toml # Client Secret - choose one method: oauth_client_secret = "tskey-client-..." # Direct value (highest priority) oauth_client_secret_file = "/etc/tsbridge/oauth-secret" # From file (second priority) oauth_client_secret_env = "TS_OAUTH_CLIENT_SECRET" # From environment variable (third priority) # Will fallback to TS_OAUTH_CLIENT_SECRET env var if none of the above are specified ``` -------------------------------- ### Development Commands Source: https://github.com/jtdowney/tsbridge/blob/main/README.md Common development commands for building, testing, and linting the tsbridge project. These are typically run from the project's root directory. ```bash make build # Build binary make test # Run tests make lint # Run linters ``` -------------------------------- ### Verify tsbridge Directory Permissions Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md List the details of tsbridge-related directories to verify permissions. ```bash ls -la /usr/local/etc/tsbridge/ ls -la /var/run/tsbridge/ ls -la /var/log/tsbridge/ ``` -------------------------------- ### Tidy Go Modules Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Ensures the go.mod file is clean and all dependencies are accounted for. ```makefile make tidy ``` -------------------------------- ### Enable Docker Provider and Set Poll Interval Source: https://github.com/jtdowney/tsbridge/blob/main/docs/docker-labels.md Use this command to enable the Docker provider and set a custom polling interval for configuration updates. ```bash tsbridge --provider docker --docker-poll-interval 30s ``` -------------------------------- ### Run Tests with Race Detection Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Executes all tests with the race detector enabled to find data races. ```go go test -race ./... ``` -------------------------------- ### Run Specific Test Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Executes a single Go test case identified by its name within a specific package. ```go go test -run TestName ./path/to/package ``` -------------------------------- ### Running tsbridge with Environment Variables Source: https://github.com/jtdowney/tsbridge/blob/main/README.md Command to set OAuth environment variables and run the tsbridge application with a specified configuration file. ```bash export TS_OAUTH_CLIENT_ID=your-id export TS_OAUTH_CLIENT_SECRET=your-secret tsbridge -config tsbridge.toml ``` -------------------------------- ### Calculate Request Rate per Service Source: https://github.com/jtdowney/tsbridge/blob/main/docs/metrics.md Use PromQL to calculate the rate of HTTP requests processed per service over a 5-minute interval. ```promql # Request rate per service rate(tsbridge_requests_total[5m]) ``` -------------------------------- ### Configuring Service with Unix Socket Source: https://github.com/jtdowney/tsbridge/blob/main/docs/quickstart.md This TOML configuration shows how to direct a service's traffic to a Unix socket instead of a TCP address. This is useful for inter-process communication on the same host. ```toml [[services]] name = "app" backend_addr = "unix:///var/run/app.sock" ``` -------------------------------- ### View tsbridge Logs Source: https://github.com/jtdowney/tsbridge/blob/main/example/README.md Follow the logs of the tsbridge service in real-time using Docker Compose. ```bash docker compose logs -f tsbridge ``` -------------------------------- ### Create Docker Network Manually Source: https://github.com/jtdowney/tsbridge/blob/main/docs/docker-labels.md Use this command to manually create a Docker network if it's not defined or accessible between compose files. Ensure the network name matches across your compose configurations. ```bash docker network create ``` -------------------------------- ### Clean Build Artifacts Source: https://github.com/jtdowney/tsbridge/blob/main/CLAUDE.md Removes any previously built binaries from the project. ```makefile make clean ``` -------------------------------- ### Check System-wide File Descriptor Limits Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md View the current system-wide limit for the maximum number of open files. ```bash sysctl kern.maxfiles ``` -------------------------------- ### Define Network in One Compose File, Use as External in Another Source: https://github.com/jtdowney/tsbridge/blob/main/docs/docker-labels.md Define a network in one compose file and reference it as external with a specific name in another compose file for cross-file networking. ```yaml tsbridge-compose.yml (defines network): services: tsbridge: # ... config networks: - shared-network networks: shared-network: name: tsbridge-shared services-compose.yml (uses external network): services: myapp: # ... config networks: - shared-network networks: shared-network: external: true name: tsbridge-shared ``` -------------------------------- ### Enabling Identity Headers for a Service Source: https://github.com/jtdowney/tsbridge/blob/main/docs/quickstart.md Set `whois_enabled = true` in the service configuration to automatically add `X-Tailscale-User` headers to requests forwarded to the backend. This provides information about the authenticated user. ```toml [[services]] name = "internal-api" backend_addr = "localhost:8080" whois_enabled = true # Adds X-Tailscale-User headers ``` -------------------------------- ### Monitor Whois Lookup Latency Source: https://github.com/jtdowney/tsbridge/blob/main/docs/metrics.md Use PromQL to calculate the 99th percentile of time taken for Tailscale whois lookups over a 5-minute interval. ```promql # Whois lookup latency histogram_quantile(0.99, rate(tsbridge_whois_duration_seconds_bucket[5m])) ``` -------------------------------- ### Basic tsbridge Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/docs/quickstart.md This TOML file configures tsbridge with OAuth credentials from environment variables and defines a single service. Ensure the default tags match your OAuth client's configuration. ```toml [tailscale] oauth_client_id_env = "TS_OAUTH_CLIENT_ID" ``` ```toml oauth_client_secret_env = "TS_OAUTH_CLIENT_SECRET" ``` ```toml default_tags = ["tag:server"] # Must match or be owned by your OAuth client's tag ``` ```toml [[services]] name = "app" backend_addr = "localhost:8080" ``` -------------------------------- ### Service Compose File with External Network Source: https://github.com/jtdowney/tsbridge/blob/main/docs/docker-labels.md Configure service containers to use the same externally defined network. Mark the network as external and specify the name. ```yaml services: api: image: myapi:latest labels: - "tsbridge.enabled=true" - "tsbridge.service.name=api" - "tsbridge.service.port=8080" networks: - tsbridge-network web: image: myweb:latest labels: - "tsbridge.enabled=true" - "tsbridge.service.name=web" - "tsbridge.service.port=3000" networks: - tsbridge-network networks: tsbridge-network: external: true ``` -------------------------------- ### Set File Permissions for tsbridge Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Configure appropriate file permissions for tsbridge configuration and runtime files to enhance security. ```bash # Configuration files chmod 644 /usr/local/etc/tsbridge/config.toml chmod 600 /usr/local/etc/tsbridge/oauth_client_* # Directories chmod 750 /var/run/tsbridge chmod 750 /var/log/tsbridge chmod 750 /var/db/tsbridge ``` -------------------------------- ### Create tsbridge User and Group Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Create a dedicated user and group named 'tsbridge' for running the tsbridge daemon with restricted permissions. ```bash # Create tsbridge user and group pw groupadd tsbridge pw useradd tsbridge -g tsbridge -d /nonexistent -s /usr/sbin/nologin -c "tsbridge daemon" ``` -------------------------------- ### Verify Docker Network Connectivity Source: https://github.com/jtdowney/tsbridge/blob/main/docs/docker-labels.md Use docker commands to inspect networks and containers, and execute commands within containers to diagnose connectivity issues. ```bash docker network ls docker inspect docker exec tsbridge-container ping service-container ``` -------------------------------- ### Troubleshoot Services Not Appearing Source: https://github.com/jtdowney/tsbridge/blob/main/example/multi-compose/README.md If services are not appearing in tsbridge, verify that the containers have the correct 'tsbridge.enabled=true' label, are on the same network, and check tsbridge logs for errors. ```bash # Check labels in docker-compose.yml # Verify network: docker network inspect tsbridge-shared-network # Check logs: docker compose -f tsbridge-compose.yml logs tsbridge ``` -------------------------------- ### Observability Settings Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Configure Prometheus metrics endpoint and access logging. The metrics address can be set to a specific port or left empty to disable. Access logging is enabled by default. ```toml # Prometheus metrics endpoint metrics_addr = ":9090" # Listen address (empty to disable) # Access logging access_log = true # Enable/disable (default: true) ``` -------------------------------- ### Track Error Rate by Type Source: https://github.com/jtdowney/tsbridge/blob/main/docs/metrics.md Use PromQL to calculate the rate of errors categorized by type over a 5-minute interval. ```promql # Error rate by type rate(tsbridge_errors_total[5m]) ``` -------------------------------- ### Enable Metrics Endpoint Source: https://github.com/jtdowney/tsbridge/blob/main/docs/metrics.md Configure the global metrics address in your TOML configuration file to enable Prometheus metrics exposure. ```toml [global] metrics_addr = ":9090" # Listen on all interfaces, port 9090 ``` -------------------------------- ### Check for Conflicting Services Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Use sockstat to identify services using a specific port. ```bash sockstat -4 -6 | grep :PORT ``` -------------------------------- ### Track Service Operation Failure Rate Source: https://github.com/jtdowney/tsbridge/blob/main/docs/metrics.md Use PromQL to calculate the rate of failed service lifecycle operations over a 5-minute interval. ```promql # Service operation failure rate rate(tsbridge_service_operations_total{status="failure"}[5m]) ``` -------------------------------- ### Tailscale Features Configuration Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Enables Tailscale-specific features like Whois identity headers, Funnel for public access, and ephemeral nodes. ```toml # Whois identity headers whois_enabled = true # Add X-Tailscale-User headers (default: false) whois_timeout = "1s" # Whois lookup timeout (default: from global or 1s) # Funnel (public access) funnel_enabled = true # Expose to internet via Funnel (default: false) # Ephemeral nodes ephemeral = true # Don't persist node state (default: false) ``` -------------------------------- ### Cleanup Docker Resources Source: https://github.com/jtdowney/tsbridge/blob/main/example/README.md Stop and remove all containers, networks, and volumes associated with the Docker Compose project. ```bash docker compose down -v ``` -------------------------------- ### Docker Compose Configuration for tsbridge and Service Source: https://github.com/jtdowney/tsbridge/blob/main/docs/quickstart.md This Docker Compose file sets up tsbridge and a sample application container. It configures tsbridge to use Docker as a provider and mounts necessary volumes and environment variables. The application container is labeled to be managed by tsbridge. ```yaml services: tsbridge: image: ghcr.io/jtdowney/tsbridge:latest command: ["--provider", "docker"] volumes: - /var/run/docker.sock:/var/run/docker.sock - tsbridge-state:/var/lib/tsbridge environment: - TS_OAUTH_CLIENT_ID=${TS_OAUTH_CLIENT_ID} - TS_OAUTH_CLIENT_SECRET=${TS_OAUTH_CLIENT_SECRET} labels: - "tsbridge.tailscale.oauth_client_id_env=TS_OAUTH_CLIENT_ID" - "tsbridge.tailscale.oauth_client_secret_env=TS_OAUTH_CLIENT_SECRET" - "tsbridge.tailscale.state_dir=/var/lib/tsbridge" - "tsbridge.tailscale.default_tags=tag:server" # Must match or be owned by your OAuth client's tag myapp: image: myapp:latest labels: - "tsbridge.enabled=true" - "tsbridge.service.name=myapp" - "tsbridge.service.port=8080" # Optional: Override default tags for this service # - "tsbridge.service.tags=tag:api,tag:prod" volumes: tsbridge-state: ``` -------------------------------- ### Service with Self-Signed Certificate Source: https://github.com/jtdowney/tsbridge/blob/main/docs/configuration-reference.md Configures a service to use a backend with a self-signed certificate, disabling TLS verification. Use with caution. ```toml [[services]] name = "self-signed-api" backend_addr = "https://internal-service.lan:8443" insecure_skip_verify = true # Skip TLS certificate verification ``` -------------------------------- ### Configure tsbridge Resource Limits Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Set custom resource limits for tsbridge, such as maximum open files and processes, in /etc/rc.conf. ```bash # Example: Set custom limits tsbridge_limits="-n 100000 -u 512" # Max files: 100k, Max processes: 512 ``` -------------------------------- ### View tsbridge Service Logs Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Monitor the tsbridge service logs in real-time using tail. Ensure the log directory and file exist and are writable by the service user. ```bash # Service logs tail -f /var/log/tsbridge/tsbridge.log # Or use newsyslog for log rotation ``` -------------------------------- ### Configure tsbridge Log Rotation Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/freebsd/README.md Set up daily log rotation for tsbridge using newsyslog. This ensures log files do not grow indefinitely and are compressed for storage. ```bash # Copy the newsyslog configuration install -m 644 tsbridge-newsyslog.conf /usr/local/etc/newsyslog.conf.d/tsbridge.conf # Or if using /etc/newsyslog.conf directly, append the configuration: cat tsbridge-newsyslog.conf >> /etc/newsyslog.conf ``` -------------------------------- ### Calculate Average Request Duration Source: https://github.com/jtdowney/tsbridge/blob/main/docs/metrics.md Use PromQL to calculate the average request processing time by dividing the sum of durations by the count of requests over a 5-minute interval. ```promql # Average request duration rate(tsbridge_request_duration_seconds_sum[5m]) / rate(tsbridge_request_duration_seconds_count[5m]) ``` -------------------------------- ### Troubleshooting tsbridge Systemd Service Source: https://github.com/jtdowney/tsbridge/blob/main/deployments/systemd/README.md Commands to view logs, validate configuration, and restart the tsbridge service. ```bash # View logs sudo journalctl -u tsbridge -f # Validate config sudo -u tsbridge /usr/local/bin/tsbridge -config /etc/tsbridge/config.toml -validate # Restart sudo systemctl restart tsbridge ```