Setup Guide for Coder with Tailscale Tunneling
This guide provides a step-by-step setup for integrating Coder with Tailscale tunneling in a Docker environment. Ensure your Docker setup meets the outlined assumptions before proceeding.
Assumptions
- Your Docker setup is not using the
172.20/16
IP range. - Update the network configuration in
networks.tailnet.ipam.config.0
to an unused network if necessary. - Set the environment variable
TS_ROUTES=your-network/24
to adjust routing for the Tailscale network. - You are not running rootless Docker or Podman.
- Traefik is configured in your stack:
- Attached to a Docker network named servicenet.
- Consumes Docker container labels to build the service catalog.
- Has a TLS certificate resolver named default-le (set
TRAEFIK_TLS_RESOLVER=<your resolver name>
if different).
Required Environment Variables
Before you start, ensure you have the following environment variables defined:
FRONTEND_HOST=<HTTP host to listen on (e.g., code.example.org)>
CODER_ACCESS_URL=<full HTTPS URL (e.g., https://code.example.org/)>
TS_AUTHKEY=<get a Tailscale auth key>
CODER_VERSION=v0.23.7
Docker Compose Configuration
Create a docker-compose.yml
file with the following content:
version: "3.9"
networks:
backend: {}
outbound: {}
tailnet:
ipam:
driver: default
config:
- subnet: 172.20.0.0/16
ip_range: 172.20.0.0/24
gateway: 172.20.0.1
servicenet:
external: true
volumes:
coder-data:
external: true
tailscale-data: {}
services:
coder:
image: ghcr.io/coder/coder:${CODER_VERSION:-latest}
environment:
CODER_PG_CONNECTION_URL: "postgresql://${POSTGRES_USER:-username}:${POSTGRES_PASSWORD:-password}@database/${POSTGRES_DB:-coder}?sslmode=disable"
CODER_ADDRESS: "0.0.0.0:7080"
# You'll need to set CODER_ACCESS_URL to an IP or domain
# that workspaces can reach. This cannot be localhost
# or 127.0.0.1 for non-Docker templates!
CODER_ACCESS_URL: "${CODER_ACCESS_URL}"
# If the coder user does not have write permissions on
# the docker socket, you can uncomment the following
# lines and set the group ID to one that has write
# permissions on the docker socket.
group_add:
- "997" # docker group on host
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
database:
condition: service_healthy
networks:
- servicenet
- backend
labels:
- "appname=coder"
- "traefik.enable=true"
- "traefik.http.routers.coder.rule=Host(`${FRONTEND_HOST}`)"
- "traefik.http.routers.coder.entrypoints=web-secure"
- "traefik.http.routers.coder.service=coder"
- "traefik.http.routers.coder.tls=true"
- "traefik.http.routers.coder.tls.certResolver=${TRAEFIK_TLS_RESOLVER:-default-le}"
- "traefik.http.services.coder.loadbalancer.server.port=7080"
- "traefik.http.services.coder.loadbalancer.passhostheader=true"
database:
image: "postgres:14.2"
environment:
POSTGRES_USER: ${POSTGRES_USER:-username} # The PostgreSQL user (useful to connect to the database)
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-password} # The PostgreSQL password (useful to connect to the database)
POSTGRES_DB: ${POSTGRES_DB:-coder} # The PostgreSQL default database (automatically created at first launch)
volumes:
- coder-data:/var/lib/postgresql/data # Use "docker volume rm coder-data" to reset Coder
networks:
- backend
healthcheck:
test:
[
"CMD-SHELL",
"pg_isready -U ${POSTGRES_USER:-username} -d ${POSTGRES_DB:-coder}",
]
interval: 5s
timeout: 5s
retries: 5
tailscale:
image: "tailscale/tailscale:stable"
cap_add:
- NET_ADMIN
- NET_RAW
environment:
TS_AUTHKEY: "${TS_AUTHKEY}"
TS_ACCEPT_DNS: "${TS_ACCEPT_DNS:-true}"
TS_EXTRA_ARGS: "${TS_EXTRA_ARGS}"
TS_ROUTES: "${TS_ROUTES:-172.20.0.0/24}"
TS_USERSPACE: "${TS_USERSPACE:-false}"
volumes:
- tailscale-data:/var/lib
devices:
- /dev/net/tun:/dev/net/tun
sysctls:
net.ipv4.ip_forward: 1
net.ipv6.conf.all.forwarding: 1
networks:
- outbound
- tailnet
Steps to Deploy
-
Create the Docker Network:
Ensure that your Docker network named servicenet is created and configured properly. -
Run Docker Compose:
Execute the following command in the directory containing yourdocker-compose.yml
file:docker-compose up -d
-
Authenticate Tailscale:
After starting your services, you will need to authenticate your Tailscale container. You can find the authentication link in the logs of the Tailscale container:docker logs tailscaled
-
Enable Route Settings:
Log into your Tailscale admin console and enable the advertised routes corresponding to your Docker network. -
Access Coder:
You can now access Coder through the specified frontend host URL, which should be routed through Tailscale.
Additional Configuration
-
Traefik Configuration:
Ensure that Traefik is properly configured to utilize Docker labels for routing and that it listens on the correct ports specified in your environment variables. -
Testing Connectivity:
Use tools likecurl
or browser access to verify that you can reach your Coder instance via Tailscale.
Troubleshooting Tips
- If you encounter issues accessing services, check the logs of both the Coder and Tailscale containers for any errors.
- Ensure that your firewall settings allow traffic through the necessary ports.
- Verify that all environment variables are set correctly before running Docker Compose.
By following this guide, you should have a functional setup of Coder with Tailscale tunneling, allowing secure access to your development environment over a private network.