# Setup Guide for Coder with Tailscale Tunneling

**URL:** <https://forum.hhf.technology/t/setup-guide-for-coder-with-tailscale-tunneling/274>\
**Category:** Self-hosted Applications\
**Tags:** tailscale, coder\
**Created:** [October 20, 2024, 10:35am UTC](https://forum.hhf.technology/t/setup-guide-for-coder-with-tailscale-tunneling/274 "2024-10-20T10:35:33Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![hhf.technoloy](https://forum.hhf.technology/user_avatar/forum.hhf.technology/hhf.technoloy/32/68_2.png) [@hhf.technoloy](https://forum.hhf.technology/u/hhf.technoloy)\
**Post date:** [October 20, 2024, 10:35am UTC](https://forum.hhf.technology/t/setup-guide-for-coder-with-tailscale-tunneling/274/1 "2024-10-20T10:35:33Z")

</div>

## 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:

```yaml
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

1. **Create the Docker Network** :  
Ensure that your Docker network named **servicenet** is created and configured properly.

2. **Run Docker Compose** :  
Execute the following command in the directory containing your `docker-compose.yml` file:

3. **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:

4. **Enable Route Settings** :  
Log into your Tailscale admin console and enable the advertised routes corresponding to your Docker network.

5. **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 like `curl` 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.
