From 159baf9337dfdc2747f957cbbfa3fac2d7d31633 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 13:43:49 -0400 Subject: [PATCH 01/46] feat: migrate tailscale configuration to YAML and update proxy settings --- config.tailscale.yaml | 24 ++++++++++++ docker-compose.tailscale-router.yaml | 37 ------------------- .../config/tailscale-private.json | 2 +- tailscale-router/config/tailscale-public.json | 2 +- 4 files changed, 26 insertions(+), 39 deletions(-) create mode 100644 config.tailscale.yaml delete mode 100644 docker-compose.tailscale-router.yaml diff --git a/config.tailscale.yaml b/config.tailscale.yaml new file mode 100644 index 0000000..8a56923 --- /dev/null +++ b/config.tailscale.yaml @@ -0,0 +1,24 @@ +#ddev-generated +webimage_extra_packages: + - tailscale + +web_extra_daemons: + - name: "tailscale-router" + command: > + sh -c "tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock & + sleep 2; + tailscale up --authkey=${TS_AUTHKEY:-} --hostname=${DDEV_SITENAME} --accept-routes --ssh --state=/var/lib/tailscale/tailscaled.state --userspace --serve-config=/config/tailscale-${TS_PRIVACY:-private}.json" + directory: /var/www/html + +web_extra_exposed_ports: + - 80 + - 443 + +web_extra_volumes: + - type: volume + source: tailscale-router-state + target: /var/lib/tailscale + - type: bind + source: ./tailscale-router/config + target: /config + read_only: true diff --git a/docker-compose.tailscale-router.yaml b/docker-compose.tailscale-router.yaml deleted file mode 100644 index ea7f545..0000000 --- a/docker-compose.tailscale-router.yaml +++ /dev/null @@ -1,37 +0,0 @@ -#ddev-generated -services: - tailscale-router: - image: ${TS_DOCKER_IMAGE:-tailscale/tailscale:latest}-${DDEV_SITENAME}-built - build: - dockerfile_inline: | - ARG TS_DOCKER_IMAGE=scratch - FROM $$TS_DOCKER_IMAGE - RUN apk add --no-cache socat - args: - TS_DOCKER_IMAGE: ${TS_DOCKER_IMAGE:-tailscale/tailscale:latest} - hostname: ${DDEV_SITENAME} - container_name: ddev-${DDEV_SITENAME}-tailscale-router - environment: - TS_AUTHKEY: ${TS_AUTHKEY:-} - TS_HOSTNAME: ${DDEV_SITENAME} - TS_EXTRA_ARGS: --accept-routes --ssh - TS_STATE_DIR: /var/lib/tailscale - TS_USERSPACE: "true" - TS_PRIVACY: ${TS_PRIVACY:-private} - TS_SERVE_CONFIG: /config/tailscale-${TS_PRIVACY:-private}.json - volumes: - - tailscale-router-state:/var/lib/tailscale - - ./tailscale-router/config:/config:ro - - .:/mnt/ddev_config - - ddev-global-cache:/mnt/ddev-global-cache - restart: "no" - labels: - com.ddev.site-name: ${DDEV_SITENAME} - com.ddev.approot: ${DDEV_APPROOT} - depends_on: - - web - post_start: - - command: ["sh", "-c", "socat TCP-LISTEN:8080,reuseaddr,fork TCP:web:${DDEV_ROUTER_HTTP_PORT} >> /var/log/ddev.log 2>&1 &"] - -volumes: - tailscale-router-state: diff --git a/tailscale-router/config/tailscale-private.json b/tailscale-router/config/tailscale-private.json index ae11cc2..6147ba0 100644 --- a/tailscale-router/config/tailscale-private.json +++ b/tailscale-router/config/tailscale-private.json @@ -9,7 +9,7 @@ "${TS_CERT_DOMAIN}:443": { "Handlers": { "/": { - "Proxy": "http://127.0.0.1:8080" + "Proxy": "http://127.0.0.1:${DDEV_ROUTER_HTTP_PORT}" } } } diff --git a/tailscale-router/config/tailscale-public.json b/tailscale-router/config/tailscale-public.json index 2681ae6..9f5bc1f 100644 --- a/tailscale-router/config/tailscale-public.json +++ b/tailscale-router/config/tailscale-public.json @@ -9,7 +9,7 @@ "${TS_CERT_DOMAIN}:443": { "Handlers": { "/": { - "Proxy": "http://127.0.0.1:8080" + "Proxy": "http://127.0.0.1:${DDEV_ROUTER_HTTP_PORT}" } } } From 993579238a00a84c3164c0bbd5defbbea24851de Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 13:49:18 -0400 Subject: [PATCH 02/46] fix: update project_files to reference correct configuration file --- install.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.yaml b/install.yaml index 908c34b..5bfcd67 100644 --- a/install.yaml +++ b/install.yaml @@ -3,7 +3,7 @@ name: tailscale-router project_files: - tailscale-router/config/tailscale-private.json - tailscale-router/config/tailscale-public.json - - docker-compose.tailscale-router.yaml + - config.tailscale.yaml - commands/host/tailscale ddev_version_constraint: '>= v1.24.3' From 97fa037d5c1a19399c19479f596eb134518479b5 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 13:50:51 -0400 Subject: [PATCH 03/46] fix: update web_extra_exposed_ports to use string format --- config.tailscale.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config.tailscale.yaml b/config.tailscale.yaml index 8a56923..f8439b6 100644 --- a/config.tailscale.yaml +++ b/config.tailscale.yaml @@ -11,8 +11,8 @@ web_extra_daemons: directory: /var/www/html web_extra_exposed_ports: - - 80 - - 443 + - "80" + - "443" web_extra_volumes: - type: volume From 4fe2ef695f8f36488d8c77ae219e5d53e15fe302 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 13:53:05 -0400 Subject: [PATCH 04/46] fix: remove unused web_extra_volumes configuration --- config.tailscale.yaml | 8 -------- 1 file changed, 8 deletions(-) diff --git a/config.tailscale.yaml b/config.tailscale.yaml index f8439b6..44cf869 100644 --- a/config.tailscale.yaml +++ b/config.tailscale.yaml @@ -14,11 +14,3 @@ web_extra_exposed_ports: - "80" - "443" -web_extra_volumes: - - type: volume - source: tailscale-router-state - target: /var/lib/tailscale - - type: bind - source: ./tailscale-router/config - target: /config - read_only: true From fd30bff28575262a622cc4cbfa734fac31b9fee7 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 13:54:58 -0400 Subject: [PATCH 05/46] fix: remove web_extra_exposed_ports configuration --- config.tailscale.yaml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/config.tailscale.yaml b/config.tailscale.yaml index 44cf869..fdc5b76 100644 --- a/config.tailscale.yaml +++ b/config.tailscale.yaml @@ -9,8 +9,3 @@ web_extra_daemons: sleep 2; tailscale up --authkey=${TS_AUTHKEY:-} --hostname=${DDEV_SITENAME} --accept-routes --ssh --state=/var/lib/tailscale/tailscaled.state --userspace --serve-config=/config/tailscale-${TS_PRIVACY:-private}.json" directory: /var/www/html - -web_extra_exposed_ports: - - "80" - - "443" - From 876ea00e82d37da4bd4bbce478e19537d26e80c7 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 14:09:29 -0400 Subject: [PATCH 06/46] feat: add Dockerfile for Tailscale installation and update project files --- .ddev/web-build/Dockerfile | 8 ++++++++ config.tailscale.yaml | 2 -- install.yaml | 1 + 3 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 .ddev/web-build/Dockerfile diff --git a/.ddev/web-build/Dockerfile b/.ddev/web-build/Dockerfile new file mode 100644 index 0000000..c869168 --- /dev/null +++ b/.ddev/web-build/Dockerfile @@ -0,0 +1,8 @@ +ARG BASE_IMAGE +FROM $BASE_IMAGE + +# Install Tailscale using the official install script +RUN apt-get update && \ + apt-get install -y curl && \ + rm -rf /var/lib/apt/lists/* && \ + curl -fsSL https://tailscale.com/install.sh | sh diff --git a/config.tailscale.yaml b/config.tailscale.yaml index fdc5b76..0cecff2 100644 --- a/config.tailscale.yaml +++ b/config.tailscale.yaml @@ -1,6 +1,4 @@ #ddev-generated -webimage_extra_packages: - - tailscale web_extra_daemons: - name: "tailscale-router" diff --git a/install.yaml b/install.yaml index 5bfcd67..eaef4a1 100644 --- a/install.yaml +++ b/install.yaml @@ -5,6 +5,7 @@ project_files: - tailscale-router/config/tailscale-public.json - config.tailscale.yaml - commands/host/tailscale + - .ddev/web-build/Dockerfile ddev_version_constraint: '>= v1.24.3' From b6e41c464cf919045d81b284fa7389eb84e71534 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 14:12:51 -0400 Subject: [PATCH 07/46] fix: update project_files to reference correct Dockerfile path and add Dockerfile for Tailscale installation --- install.yaml | 2 +- {.ddev/web-build => web-build}/Dockerfile | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename {.ddev/web-build => web-build}/Dockerfile (100%) diff --git a/install.yaml b/install.yaml index eaef4a1..779adb1 100644 --- a/install.yaml +++ b/install.yaml @@ -5,7 +5,7 @@ project_files: - tailscale-router/config/tailscale-public.json - config.tailscale.yaml - commands/host/tailscale - - .ddev/web-build/Dockerfile + - web-build/Dockerfile ddev_version_constraint: '>= v1.24.3' diff --git a/.ddev/web-build/Dockerfile b/web-build/Dockerfile similarity index 100% rename from .ddev/web-build/Dockerfile rename to web-build/Dockerfile From a9366753c424b65611d549dd9d7a099154530b3e Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 14:14:26 -0400 Subject: [PATCH 08/46] feat: update install.yaml to reference Dockerfile.tailscale and add Dockerfile for Tailscale installation --- install.yaml | 2 +- web-build/{Dockerfile => Dockerfile.tailscale} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename web-build/{Dockerfile => Dockerfile.tailscale} (100%) diff --git a/install.yaml b/install.yaml index 779adb1..031d4f9 100644 --- a/install.yaml +++ b/install.yaml @@ -5,7 +5,7 @@ project_files: - tailscale-router/config/tailscale-public.json - config.tailscale.yaml - commands/host/tailscale - - web-build/Dockerfile + - web-build/Dockerfile.tailscale ddev_version_constraint: '>= v1.24.3' diff --git a/web-build/Dockerfile b/web-build/Dockerfile.tailscale similarity index 100% rename from web-build/Dockerfile rename to web-build/Dockerfile.tailscale From d6f5403dd6db882caa4e1b5f98a8059fa99d484e Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 14:30:31 -0400 Subject: [PATCH 09/46] feat: simplify Tailscale command in config and add environment variables in Dockerfile --- config.tailscale.yaml | 9 ++------- web-build/Dockerfile.tailscale | 10 ++++++++++ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/config.tailscale.yaml b/config.tailscale.yaml index 0cecff2..86a6b90 100644 --- a/config.tailscale.yaml +++ b/config.tailscale.yaml @@ -1,9 +1,4 @@ -#ddev-generated - web_extra_daemons: - name: "tailscale-router" - command: > - sh -c "tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock & - sleep 2; - tailscale up --authkey=${TS_AUTHKEY:-} --hostname=${DDEV_SITENAME} --accept-routes --ssh --state=/var/lib/tailscale/tailscaled.state --userspace --serve-config=/config/tailscale-${TS_PRIVACY:-private}.json" - directory: /var/www/html + command: tailscale up + directory: /var/www/html \ No newline at end of file diff --git a/web-build/Dockerfile.tailscale b/web-build/Dockerfile.tailscale index c869168..bfd179f 100644 --- a/web-build/Dockerfile.tailscale +++ b/web-build/Dockerfile.tailscale @@ -1,8 +1,18 @@ ARG BASE_IMAGE FROM $BASE_IMAGE +# Set Tailscale environment variables +ENV TS_AUTHKEY="${TS_AUTHKEY}" +ENV TS_HOSTNAME="${DDEV_SITENAME}" +ENV TS_EXTRA_ARGS="--accept-routes --ssh" +ENV TS_STATE_DIR="/var/lib/tailscale" +ENV TS_USERSPACE="false" +ENV TS_PRIVACY="${TS_PRIVACY:-private}" +ENV TS_SERVE_CONFIG="/config/tailscale-${TS_PRIVACY}.json" + # Install Tailscale using the official install script RUN apt-get update && \ apt-get install -y curl && \ rm -rf /var/lib/apt/lists/* && \ curl -fsSL https://tailscale.com/install.sh | sh + From 58eca198013efcb3aea5f4ff9092bcc8b7b96a4d Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 14:32:15 -0400 Subject: [PATCH 10/46] fix: add missing comments to Dockerfile.tailscale for clarity --- web-build/Dockerfile.tailscale | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web-build/Dockerfile.tailscale b/web-build/Dockerfile.tailscale index bfd179f..42d8373 100644 --- a/web-build/Dockerfile.tailscale +++ b/web-build/Dockerfile.tailscale @@ -1,3 +1,5 @@ +#ddev-generated +# This Dockerfile installs Tailscale in a web container. ARG BASE_IMAGE FROM $BASE_IMAGE From 7b7864a05444107968159a526a77654a5499e047 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 14:33:41 -0400 Subject: [PATCH 11/46] fix: add missing newline for clarity in config.tailscale.yaml --- config.tailscale.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config.tailscale.yaml b/config.tailscale.yaml index 86a6b90..07b3277 100644 --- a/config.tailscale.yaml +++ b/config.tailscale.yaml @@ -1,3 +1,5 @@ +#ddev-generated + web_extra_daemons: - name: "tailscale-router" command: tailscale up From 5c26b7e89157931a3a250ae68ad7376e6b8d675d Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 14:45:51 -0400 Subject: [PATCH 12/46] fix: improve clarity in config.tailscale.yaml by adding comments and reformatting --- config.tailscale.yaml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/config.tailscale.yaml b/config.tailscale.yaml index 07b3277..600f6c2 100644 --- a/config.tailscale.yaml +++ b/config.tailscale.yaml @@ -1,6 +1,9 @@ #ddev-generated - +# This configuration adds Tailscale routing capabilities to the web container. web_extra_daemons: + - name: tailscale-service + command: tailscaled --state=/var/run/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --tun=userspace-networking + directory: /var/run/tailscale - name: "tailscale-router" - command: tailscale up + command: tailscale up --authkey=$TS_AUTHKEY --hostname=$TS_HOSTNAME $TS_EXTRA_ARGS directory: /var/www/html \ No newline at end of file From b69781d3975250fb23857f1e20a86c7be8673eb2 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 15:04:55 -0400 Subject: [PATCH 13/46] fix: correct paths in config.tailscale.yaml and add docker-compose.tailscale.yaml for Tailscale service --- config.tailscale.yaml | 4 ++-- docker-compose.tailscale.yaml | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 docker-compose.tailscale.yaml diff --git a/config.tailscale.yaml b/config.tailscale.yaml index 600f6c2..91829f2 100644 --- a/config.tailscale.yaml +++ b/config.tailscale.yaml @@ -2,8 +2,8 @@ # This configuration adds Tailscale routing capabilities to the web container. web_extra_daemons: - name: tailscale-service - command: tailscaled --state=/var/run/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --tun=userspace-networking - directory: /var/run/tailscale + command: tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --tun=userspace-networking + directory: /usr/sbin - name: "tailscale-router" command: tailscale up --authkey=$TS_AUTHKEY --hostname=$TS_HOSTNAME $TS_EXTRA_ARGS directory: /var/www/html \ No newline at end of file diff --git a/docker-compose.tailscale.yaml b/docker-compose.tailscale.yaml new file mode 100644 index 0000000..1138666 --- /dev/null +++ b/docker-compose.tailscale.yaml @@ -0,0 +1,7 @@ +#ddev-generated +services: + web: + volumes: + - tailscale-router-state:/var/lib/tailscale +volumes: + tailscale-router-state: From 13e2176857e74e5fd302480542dc7101ae896d1f Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 15:06:14 -0400 Subject: [PATCH 14/46] feat: add Tailscale configuration and Dockerfile for routing capabilities --- config.tailscale.yaml => config.tailscale-router.yaml | 0 ...pose.tailscale.yaml => docker-compose.tailscale-router.yaml | 0 install.yaml | 3 ++- .../{Dockerfile.tailscale => Dockerfile.tailscale-router} | 0 4 files changed, 2 insertions(+), 1 deletion(-) rename config.tailscale.yaml => config.tailscale-router.yaml (100%) rename docker-compose.tailscale.yaml => docker-compose.tailscale-router.yaml (100%) rename web-build/{Dockerfile.tailscale => Dockerfile.tailscale-router} (100%) diff --git a/config.tailscale.yaml b/config.tailscale-router.yaml similarity index 100% rename from config.tailscale.yaml rename to config.tailscale-router.yaml diff --git a/docker-compose.tailscale.yaml b/docker-compose.tailscale-router.yaml similarity index 100% rename from docker-compose.tailscale.yaml rename to docker-compose.tailscale-router.yaml diff --git a/install.yaml b/install.yaml index 031d4f9..571d34d 100644 --- a/install.yaml +++ b/install.yaml @@ -5,7 +5,8 @@ project_files: - tailscale-router/config/tailscale-public.json - config.tailscale.yaml - commands/host/tailscale - - web-build/Dockerfile.tailscale + - web-build/Dockerfile.tailscale-router + - docker-compose.tailscale-router.yaml ddev_version_constraint: '>= v1.24.3' diff --git a/web-build/Dockerfile.tailscale b/web-build/Dockerfile.tailscale-router similarity index 100% rename from web-build/Dockerfile.tailscale rename to web-build/Dockerfile.tailscale-router From e917db2e51bd4f09490dacf2626bc5a88829d8d0 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 15:06:52 -0400 Subject: [PATCH 15/46] fix: update project file reference from config.tailscale.yaml to config.tailscale-router.yaml --- install.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.yaml b/install.yaml index 571d34d..bca6d37 100644 --- a/install.yaml +++ b/install.yaml @@ -3,7 +3,7 @@ name: tailscale-router project_files: - tailscale-router/config/tailscale-private.json - tailscale-router/config/tailscale-public.json - - config.tailscale.yaml + - config.tailscale-router.yaml - commands/host/tailscale - web-build/Dockerfile.tailscale-router - docker-compose.tailscale-router.yaml From dca717ebca80037864dcb791b7e05d3928b25826 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 16:19:23 -0400 Subject: [PATCH 16/46] feat: enhance Tailscale routing setup with improved configuration and new daemon script --- config.tailscale-router.yaml | 5 ++++- docker-compose.tailscale-router.yaml | 10 +++++++++- tailscale-router/tailscale-daemon.sh | 17 +++++++++++++++++ web-build/Dockerfile.tailscale-router | 11 ++--------- 4 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 tailscale-router/tailscale-daemon.sh diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index 91829f2..ff2fb8e 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -2,8 +2,11 @@ # This configuration adds Tailscale routing capabilities to the web container. web_extra_daemons: - name: tailscale-service - command: tailscaled --state=/var/lib/tailscale/tailscaled.state --socket=/run/tailscale/tailscaled.sock --tun=userspace-networking + command: tailscaled --statedir=${TS_STATE_DIR} --tun=userspace-networking directory: /usr/sbin - name: "tailscale-router" command: tailscale up --authkey=$TS_AUTHKEY --hostname=$TS_HOSTNAME $TS_EXTRA_ARGS + directory: /var/www/html + - name: "tailscale-daemon" + command: /tailscale-router/tailscale-daemon.sh directory: /var/www/html \ No newline at end of file diff --git a/docker-compose.tailscale-router.yaml b/docker-compose.tailscale-router.yaml index 1138666..c78e424 100644 --- a/docker-compose.tailscale-router.yaml +++ b/docker-compose.tailscale-router.yaml @@ -1,7 +1,15 @@ #ddev-generated services: web: - volumes: + environment: + - TS_AUTHKEY=${TS_AUTHKEY} + - TS_HOSTNAME=${DDEV_SITENAME} + - TS_EXTRA_ARGS=--accept-routes --ssh + - TS_STATE_DIR=/var/lib/tailscale + - TS_USERSPACE=false + - TS_PRIVACY=${TS_PRIVACY:-private} + - TS_SERVE_CONFIG=/config/tailscale-${TS_PRIVACY}.json + volumes: - tailscale-router-state:/var/lib/tailscale volumes: tailscale-router-state: diff --git a/tailscale-router/tailscale-daemon.sh b/tailscale-router/tailscale-daemon.sh new file mode 100644 index 0000000..4f38d45 --- /dev/null +++ b/tailscale-router/tailscale-daemon.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# Entrypoint for conditional Tailscale serve/funnel +# Usage: ./tailscale-daemon.sh + +set -e + +# Default to private if not set +TS_PRIVACY="${TS_PRIVACY:-private}" + +if [ "$TS_PRIVACY" = "private" ]; then + echo "[tailscale-daemon] Running in PRIVATE mode: tailscale serve 127.0.0.1:$DDEV_ROUTER_HTTP_PORT" + tailscale serve 127.0.0.1:$DDEV_ROUTER_HTTP_PORT +else + echo "[tailscale-daemon] Running in PUBLIC mode: tailscale funnel 127.0.0.1:$DDEV_ROUTER_HTTP_PORT" + tailscale funnel 127.0.0.1:$DDEV_ROUTER_HTTP_PORT +fi diff --git a/web-build/Dockerfile.tailscale-router b/web-build/Dockerfile.tailscale-router index 42d8373..ed71587 100644 --- a/web-build/Dockerfile.tailscale-router +++ b/web-build/Dockerfile.tailscale-router @@ -3,18 +3,11 @@ ARG BASE_IMAGE FROM $BASE_IMAGE -# Set Tailscale environment variables -ENV TS_AUTHKEY="${TS_AUTHKEY}" -ENV TS_HOSTNAME="${DDEV_SITENAME}" -ENV TS_EXTRA_ARGS="--accept-routes --ssh" -ENV TS_STATE_DIR="/var/lib/tailscale" -ENV TS_USERSPACE="false" -ENV TS_PRIVACY="${TS_PRIVACY:-private}" -ENV TS_SERVE_CONFIG="/config/tailscale-${TS_PRIVACY}.json" - # Install Tailscale using the official install script RUN apt-get update && \ apt-get install -y curl && \ rm -rf /var/lib/apt/lists/* && \ curl -fsSL https://tailscale.com/install.sh | sh +ARG username +RUN mkdir -p /var/lib/tailscale && chown -R atj:atj /var/lib/tailscale From 53886d9407ac128b8dc8fa68ab345b1c16860c59 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 16:44:25 -0400 Subject: [PATCH 17/46] feat: add 'share' command to Tailscale functionality and remove obsolete configuration files --- README.md | 1 + commands/host/tailscale | 60 +++++++++++++++---- .../config/tailscale-private.json | 20 ------- tailscale-router/config/tailscale-public.json | 20 ------- 4 files changed, 49 insertions(+), 52 deletions(-) delete mode 100644 tailscale-router/config/tailscale-private.json delete mode 100644 tailscale-router/config/tailscale-public.json diff --git a/README.md b/README.md index c363f90..3bb53e7 100644 --- a/README.md +++ b/README.md @@ -102,6 +102,7 @@ Access all [Tailscale CLI](https://tailscale.com/kb/1080/cli) commands plus help | ------- | ----------- | | `ddev tailscale ` | Run any Tailscale CLI command | | `ddev tailscale launch` | Launch your project's Tailscale URL in browser | +| `ddev tailscale share` | Share your project publicly via Tailscale Funnel | | `ddev tailscale status` | Show Tailscale status | | `ddev tailscale ping ` | Ping a Tailscale device | | `ddev tailscale stat` | Show status with self and active peers only | diff --git a/commands/host/tailscale b/commands/host/tailscale index 7427b1c..40e7e16 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -1,25 +1,61 @@ +# Helper to extract the Tailscale URL from status +get_tailscale_url() { + tailscale_web "$1" status | grep -o 'https://[^[:space:]]*' | head -1 +} #!/usr/bin/env bash ## #ddev-generated: If you want to edit and own this file, remove this line. -## Description: Tailscale command with launch functionality -## Usage: tailscale [launch|stat|proxy|url|args...] -## Example: "ddev tailscale launch" +## Description: Tailscale command with launch/share functionality +## Usage: tailscale [launch|share|stat|proxy|url|args...] +## Example: "ddev tailscale launch" or "ddev tailscale share" -if [ "$1" = "launch" ] || [ $# -eq 0 ]; then - TAILSCALE_URL=$(ddev exec -s tailscale-router tailscale funnel status | grep -o 'https://[^[:space:]]*' | head -1) - + +# Helper to run tailscale in the web container +tailscale_web() { + ddev exec -s web tailscale "$@" +} + +TS_PRIVACY="${TS_PRIVACY:-private}" + +# Dynamically select command based on TS_PRIVACY +if [ "$TS_PRIVACY" = "public" ]; then + CMD="funnel" + LABEL="public" +else + CMD="serve" + LABEL="private" +fi + +if [ "$1" = "share" ]; then + # Always run funnel for public sharing + tailscale_web $CMD 127.0.0.1:$DDEV_ROUTER_HTTP_PORT + TAILSCALE_URL=$(get_tailscale_url funnel) + if [ -z "$TAILSCALE_URL" ]; then + echo "Error: Could not retrieve Tailscale URL after funnel." + exit 1 + fi + echo "Tailscale public URL: $TAILSCALE_URL" + ddev launch "$TAILSCALE_URL" +elif [ "$1" = "launch" ] || [ $# -eq 0 ]; then + TAILSCALE_URL=$(get_tailscale_url $CMD) + if [ -z "$TAILSCALE_URL" ]; then + echo "No share found, creating one..." + tailscale_web $CMD --bg 127.0.0.1:$DDEV_ROUTER_HTTP_PORT + sleep 2 + TAILSCALE_URL=$(get_tailscale_url $CMD) + fi if [ -z "$TAILSCALE_URL" ]; then - echo "Error: Could not retrieve Tailscale URL." + echo "Error: Could not retrieve Tailscale URL after $CMD." exit 1 fi - + echo "Tailscale $LABEL URL: $TAILSCALE_URL" ddev launch "$TAILSCALE_URL" elif [ "$1" = "stat" ]; then - ddev exec -s tailscale-router tailscale status --self --peers=false --active=true + tailscale_web status --self --peers=false --active=true elif [ "$1" = "proxy" ]; then - ddev exec -s tailscale-router tailscale funnel status + tailscale_web $CMD status elif [ "$1" = "url" ]; then - ddev exec -s tailscale-router tailscale funnel status | grep -o 'https://[^[:space:]]*' | head -1 + get_tailscale_url $CMD else - ddev exec -s tailscale-router tailscale "$@" + tailscale_web "$@" fi diff --git a/tailscale-router/config/tailscale-private.json b/tailscale-router/config/tailscale-private.json deleted file mode 100644 index 6147ba0..0000000 --- a/tailscale-router/config/tailscale-private.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "#ddev-generated":true, - "TCP": { - "443": { - "HTTPS": true - } - }, - "Web": { - "${TS_CERT_DOMAIN}:443": { - "Handlers": { - "/": { - "Proxy": "http://127.0.0.1:${DDEV_ROUTER_HTTP_PORT}" - } - } - } - }, - "AllowFunnel": { - "${TS_CERT_DOMAIN}:443": false - } -} \ No newline at end of file diff --git a/tailscale-router/config/tailscale-public.json b/tailscale-router/config/tailscale-public.json deleted file mode 100644 index 9f5bc1f..0000000 --- a/tailscale-router/config/tailscale-public.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "#ddev-generated":true, - "TCP": { - "443": { - "HTTPS": true - } - }, - "Web": { - "${TS_CERT_DOMAIN}:443": { - "Handlers": { - "/": { - "Proxy": "http://127.0.0.1:${DDEV_ROUTER_HTTP_PORT}" - } - } - } - }, - "AllowFunnel": { - "${TS_CERT_DOMAIN}:443": true - } -} \ No newline at end of file From dc4622732fba54f665a3e54366c3d10ca64a5186 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 16:46:20 -0400 Subject: [PATCH 18/46] fix: remove obsolete Tailscale configuration files from install.yaml --- install.yaml | 2 -- 1 file changed, 2 deletions(-) diff --git a/install.yaml b/install.yaml index bca6d37..7ffddfb 100644 --- a/install.yaml +++ b/install.yaml @@ -1,8 +1,6 @@ name: tailscale-router project_files: - - tailscale-router/config/tailscale-private.json - - tailscale-router/config/tailscale-public.json - config.tailscale-router.yaml - commands/host/tailscale - web-build/Dockerfile.tailscale-router From 96931a4314e33a2c9913f664600ec940324d3c18 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 16:49:27 -0400 Subject: [PATCH 19/46] chore: update configuration for Tailscale routing capabilities --- config.tailscale-router.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index ff2fb8e..be301ae 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -5,8 +5,5 @@ web_extra_daemons: command: tailscaled --statedir=${TS_STATE_DIR} --tun=userspace-networking directory: /usr/sbin - name: "tailscale-router" - command: tailscale up --authkey=$TS_AUTHKEY --hostname=$TS_HOSTNAME $TS_EXTRA_ARGS - directory: /var/www/html - - name: "tailscale-daemon" - command: /tailscale-router/tailscale-daemon.sh + command: tailscale up --auth-key=$TS_AUTHKEY --hostname=$TS_HOSTNAME $TS_EXTRA_ARGS directory: /var/www/html \ No newline at end of file From 000a1230284f34a09dffd73efb80ec47c93ccd46 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 17:14:23 -0400 Subject: [PATCH 20/46] feat: add support for sharing with public flag and forward arbitrary args in Tailscale commands --- README.md | 32 +++++++++++++++++ commands/host/tailscale | 79 ++++++++++++++++++++++++++--------------- tests/test.bats | 26 ++++++++++++++ 3 files changed, 109 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 3bb53e7..41d4d98 100644 --- a/README.md +++ b/README.md @@ -110,6 +110,38 @@ Access all [Tailscale CLI](https://tailscale.com/kb/1080/cli) commands plus help | `ddev tailscale url` | Get your project's Tailscale URL | | `ddev logs -s tailscale-router` | Show logs for the Tailscale router service | +You can run any [Tailscale CLI](https://tailscale.com/kb/1080/cli) command directly, and use the special `--public` flag to share via Funnel: + +| Command | Description | +| ------- | ----------- | +| `ddev tailscale [flags]` | Run any Tailscale CLI command (all arguments except `--public` are passed through) | +| `ddev tailscale launch [--public]` | Launch your project's Tailscale URL in browser (use `--public` for Funnel/public URL) | +| `ddev tailscale share [--bg] [--public]` | Start sharing your project (use `--public` for Funnel, `--bg` to run in background) | +| `ddev tailscale stat` | Show status with self and active peers only | +| `ddev tailscale proxy` | Show funnel status | +| `ddev tailscale url` | Get your project's Tailscale URL | +| `ddev tailscale stop` | Stop sharing (turn off serve/funnel) | +| `ddev logs -s tailscale-router` | Show logs for the Tailscale router service | + +**Note:** +- The `--public` flag is handled by the wrapper and will switch to Tailscale Funnel mode (public sharing). It is not passed to the Tailscale CLI. +- All other arguments and flags are forwarded to the Tailscale CLI as-is. + +**Examples:** + +```bash +# Launch private share (default) +ddev tailscale launch +# Launch public share (Funnel) +ddev tailscale launch --public +# Start sharing in background (private) +ddev tailscale share --bg +# Start sharing in background (public) +ddev tailscale share --bg --public +# Run any Tailscale CLI command +ddev tailscale status +ddev tailscale ping +``` ## Advanced Customization To change the used Docker image: diff --git a/commands/host/tailscale b/commands/host/tailscale index 40e7e16..49f52de 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -1,7 +1,3 @@ -# Helper to extract the Tailscale URL from status -get_tailscale_url() { - tailscale_web "$1" status | grep -o 'https://[^[:space:]]*' | head -1 -} #!/usr/bin/env bash ## #ddev-generated: If you want to edit and own this file, remove this line. @@ -15,32 +11,42 @@ tailscale_web() { ddev exec -s web tailscale "$@" } -TS_PRIVACY="${TS_PRIVACY:-private}" +# Helper to extract the Tailscale URL from status +get_tailscale_url() { + tailscale_web "$1" status | grep -o 'https://[^[:space:]]*' | head -1 +} -# Dynamically select command based on TS_PRIVACY -if [ "$TS_PRIVACY" = "public" ]; then - CMD="funnel" - LABEL="public" -else - CMD="serve" - LABEL="private" -fi +# Helper to run tailscale share/funnel/serve with options +run_tailscale_share() { + local cmd="$1" + local bg_flag="$2" + tailscale_web $cmd $bg_flag 127.0.0.1:$DDEV_ROUTER_HTTP_PORT +} -if [ "$1" = "share" ]; then - # Always run funnel for public sharing - tailscale_web $CMD 127.0.0.1:$DDEV_ROUTER_HTTP_PORT - TAILSCALE_URL=$(get_tailscale_url funnel) - if [ -z "$TAILSCALE_URL" ]; then - echo "Error: Could not retrieve Tailscale URL after funnel." - exit 1 +stop_tailscale_share() { + local cmd="$1" + tailscale_web $cmd --https=443 off +} + +# Parse args, handle --public, and forward all other args +CMD="serve" +LABEL="private" +ARGS=() +for arg in "$@"; do + if [ "$arg" = "--public" ]; then + CMD="funnel" + LABEL="public" + else + ARGS+=("$arg") fi - echo "Tailscale public URL: $TAILSCALE_URL" - ddev launch "$TAILSCALE_URL" -elif [ "$1" = "launch" ] || [ $# -eq 0 ]; then +done + +# If no args, default to launching a share +if [ ${#ARGS[@]} -eq 0 ] || [ "${ARGS[0]}" = "launch" ]; then TAILSCALE_URL=$(get_tailscale_url $CMD) if [ -z "$TAILSCALE_URL" ]; then echo "No share found, creating one..." - tailscale_web $CMD --bg 127.0.0.1:$DDEV_ROUTER_HTTP_PORT + run_tailscale_share "$CMD" "--bg" sleep 2 TAILSCALE_URL=$(get_tailscale_url $CMD) fi @@ -50,12 +56,29 @@ elif [ "$1" = "launch" ] || [ $# -eq 0 ]; then fi echo "Tailscale $LABEL URL: $TAILSCALE_URL" ddev launch "$TAILSCALE_URL" -elif [ "$1" = "stat" ]; then +elif [ "${ARGS[0]}" = "share" ]; then + BG_FLAG="" + for arg in "${ARGS[@]}"; do + if [ "$arg" = "--bg" ]; then + BG_FLAG="--bg" + fi + done + run_tailscale_share "$CMD" "$BG_FLAG" + TAILSCALE_URL=$(get_tailscale_url $CMD) + if [ -z "$TAILSCALE_URL" ]; then + echo "Error: Could not retrieve Tailscale URL after $CMD." + exit 1 + fi + echo "Tailscale $LABEL URL: $TAILSCALE_URL" + ddev launch "$TAILSCALE_URL" +elif [ "${ARGS[0]}" = "stop" ] ; then + stop_tailscale_share "${ARGS[0]}" +elif [ "${ARGS[0]}" = "stat" ]; then tailscale_web status --self --peers=false --active=true -elif [ "$1" = "proxy" ]; then +elif [ "${ARGS[0]}" = "proxy" ]; then tailscale_web $CMD status -elif [ "$1" = "url" ]; then +elif [ "${ARGS[0]}" = "url" ]; then get_tailscale_url $CMD else - tailscale_web "$@" + tailscale_web "${ARGS[@]}" fi diff --git a/tests/test.bats b/tests/test.bats index 5767ba8..ed1f42d 100644 --- a/tests/test.bats +++ b/tests/test.bats @@ -1,3 +1,29 @@ +@test "tailscale share --public forwards correctly" { + set -eu -o pipefail + run ddev add-on get "${DIR}" + assert_success + run ddev restart -y + assert_success + + # Should use funnel (public) and not pass --public to tailscale CLI + run ddev tailscale share --public --bg + # Command should execute (may show error if not logged in, but shouldn't crash) +} + +@test "tailscale arbitrary args are forwarded" { + set -eu -o pipefail + run ddev add-on get "${DIR}" + assert_success + run ddev restart -y + assert_success + + # Should forward all args except --public + run ddev tailscale status + # Command should execute (may show error if not logged in, but shouldn't crash) + + run ddev tailscale ping 127.0.0.1 + # Command should execute (may show error if not logged in, but shouldn't crash) +} #!/usr/bin/env bats # Bats is a testing framework for Bash From ecb3771120cfe76395d5e2719e252aef8af6b786 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 20:14:10 -0400 Subject: [PATCH 21/46] feat: update Tailscale share command documentation and remove obsolete daemon script --- README.md | 25 +------ tailscale-router/tailscale-daemon.sh | 17 ----- tests/test.bats | 102 ++++++--------------------- 3 files changed, 22 insertions(+), 122 deletions(-) delete mode 100644 tailscale-router/tailscale-daemon.sh diff --git a/README.md b/README.md index 41d4d98..d659d6d 100644 --- a/README.md +++ b/README.md @@ -102,7 +102,7 @@ Access all [Tailscale CLI](https://tailscale.com/kb/1080/cli) commands plus help | ------- | ----------- | | `ddev tailscale ` | Run any Tailscale CLI command | | `ddev tailscale launch` | Launch your project's Tailscale URL in browser | -| `ddev tailscale share` | Share your project publicly via Tailscale Funnel | +| `ddev tailscale share [--bg] [--public]` | Start sharing your project (use `--public` for Funnel, `--bg` to run in background) | | `ddev tailscale status` | Show Tailscale status | | `ddev tailscale ping ` | Ping a Tailscale device | | `ddev tailscale stat` | Show status with self and active peers only | @@ -115,13 +115,6 @@ You can run any [Tailscale CLI](https://tailscale.com/kb/1080/cli) command direc | Command | Description | | ------- | ----------- | | `ddev tailscale [flags]` | Run any Tailscale CLI command (all arguments except `--public` are passed through) | -| `ddev tailscale launch [--public]` | Launch your project's Tailscale URL in browser (use `--public` for Funnel/public URL) | -| `ddev tailscale share [--bg] [--public]` | Start sharing your project (use `--public` for Funnel, `--bg` to run in background) | -| `ddev tailscale stat` | Show status with self and active peers only | -| `ddev tailscale proxy` | Show funnel status | -| `ddev tailscale url` | Get your project's Tailscale URL | -| `ddev tailscale stop` | Stop sharing (turn off serve/funnel) | -| `ddev logs -s tailscale-router` | Show logs for the Tailscale router service | **Note:** - The `--public` flag is handled by the wrapper and will switch to Tailscale Funnel mode (public sharing). It is not passed to the Tailscale CLI. @@ -142,22 +135,6 @@ ddev tailscale share --bg --public ddev tailscale status ddev tailscale ping ``` -## Advanced Customization - -To change the used Docker image: - -```bash -ddev dotenv set .ddev/.env.tailscale-router --ts-docker-image=tailscale/tailscale:latest -ddev restart -``` - -All customization options (use with caution): - -| Variable | Flag | Default | -| -------- | ---- | ------- | -| `TS_DOCKER_IMAGE` | `--ts-docker-image` | `tailscale/tailscale:latest` | -| `TS_AUTHKEY` | `--ts-authkey` | (none, required, not recommended to set in `.ddev/.env.tailscale-router`) | -| `TS_PRIVACY` | `--ts-privacy` | `private` (`private`/`public`) | ## Components of the Repository diff --git a/tailscale-router/tailscale-daemon.sh b/tailscale-router/tailscale-daemon.sh deleted file mode 100644 index 4f38d45..0000000 --- a/tailscale-router/tailscale-daemon.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -# Entrypoint for conditional Tailscale serve/funnel -# Usage: ./tailscale-daemon.sh - -set -e - -# Default to private if not set -TS_PRIVACY="${TS_PRIVACY:-private}" - -if [ "$TS_PRIVACY" = "private" ]; then - echo "[tailscale-daemon] Running in PRIVATE mode: tailscale serve 127.0.0.1:$DDEV_ROUTER_HTTP_PORT" - tailscale serve 127.0.0.1:$DDEV_ROUTER_HTTP_PORT -else - echo "[tailscale-daemon] Running in PUBLIC mode: tailscale funnel 127.0.0.1:$DDEV_ROUTER_HTTP_PORT" - tailscale funnel 127.0.0.1:$DDEV_ROUTER_HTTP_PORT -fi diff --git a/tests/test.bats b/tests/test.bats index ed1f42d..0574f40 100644 --- a/tests/test.bats +++ b/tests/test.bats @@ -1,29 +1,3 @@ -@test "tailscale share --public forwards correctly" { - set -eu -o pipefail - run ddev add-on get "${DIR}" - assert_success - run ddev restart -y - assert_success - - # Should use funnel (public) and not pass --public to tailscale CLI - run ddev tailscale share --public --bg - # Command should execute (may show error if not logged in, but shouldn't crash) -} - -@test "tailscale arbitrary args are forwarded" { - set -eu -o pipefail - run ddev add-on get "${DIR}" - assert_success - run ddev restart -y - assert_success - - # Should forward all args except --public - run ddev tailscale status - # Command should execute (may show error if not logged in, but shouldn't crash) - - run ddev tailscale ping 127.0.0.1 - # Command should execute (may show error if not logged in, but shouldn't crash) -} #!/usr/bin/env bats # Bats is a testing framework for Bash @@ -85,6 +59,7 @@ teardown() { fi } + @test "install from directory" { set -eu -o pipefail echo "# ddev add-on get ${DIR} with project ${PROJNAME} in $(pwd)" >&3 @@ -92,19 +67,8 @@ teardown() { assert_success run ddev restart -y assert_success - health_checks } -# bats test_tags=release -@test "install from release" { - set -eu -o pipefail - echo "# ddev add-on get ${GITHUB_REPO} with project ${PROJNAME} in $(pwd)" >&3 - run ddev add-on get "${GITHUB_REPO}" - assert_success - run ddev restart -y - assert_success - health_checks -} @test "tailscale command exists and responds" { set -eu -o pipefail @@ -113,35 +77,13 @@ teardown() { run ddev restart -y assert_success - # Test tailscale command exists (without --help which may not work) + # Test tailscale command exists (should not crash) run ddev tailscale status # Command should execute (may show error but shouldn't crash) } -@test "tailscale service container is running" { - set -eu -o pipefail - run ddev add-on get "${DIR}" - assert_success - run ddev restart -y - assert_success - # Check if tailscale-router container exists - run docker ps -a --filter "name=ddev-${PROJNAME}-tailscale-router" --format "{{.Names}}" - assert_success - assert_output "ddev-${PROJNAME}-tailscale-router" -} -@test "configuration files are properly installed" { - set -eu -o pipefail - run ddev add-on get "${DIR}" - assert_success - - # Check if config files exist - assert_file_exists ".ddev/tailscale-router/config/tailscale-private.json" - assert_file_exists ".ddev/tailscale-router/config/tailscale-public.json" - assert_file_exists ".ddev/docker-compose.tailscale-router.yaml" - assert_file_exists ".ddev/commands/host/tailscale" -} @test "tailscale command shortcuts work" { set -eu -o pipefail @@ -157,38 +99,36 @@ teardown() { # Test proxy command run ddev tailscale proxy # Command should execute -} -@test "docker-compose file has required services and volumes" { + # Test share and launch commands (should not crash) + run ddev tailscale share --bg + run ddev tailscale launch +} +@test "tailscale share --public forwards correctly" { set -eu -o pipefail run ddev add-on get "${DIR}" assert_success - - # Check docker-compose file contains required elements - run grep -q "tailscale-router:" ".ddev/docker-compose.tailscale-router.yaml" - assert_success - - run grep -q "tailscale-router-state:" ".ddev/docker-compose.tailscale-router.yaml" + run ddev restart -y assert_success - run grep -q "image: \${TS_DOCKER_IMAGE:-tailscale/tailscale:latest}-\${DDEV_SITENAME}-built" ".ddev/docker-compose.tailscale-router.yaml" - assert_success + # Should use funnel (public) and not pass --public to tailscale CLI + run ddev tailscale share --public --bg + # Command should execute (may show error if not logged in, but shouldn't crash) } -@test "configuration supports both private and public modes" { +@test "tailscale arbitrary args are forwarded" { set -eu -o pipefail run ddev add-on get "${DIR}" assert_success - - # Check private config - run grep -q '"AllowFunnel"' ".ddev/tailscale-router/config/tailscale-private.json" - assert_success - run grep -q 'false' ".ddev/tailscale-router/config/tailscale-private.json" + run ddev restart -y assert_success - # Check public config - run grep -q '"AllowFunnel"' ".ddev/tailscale-router/config/tailscale-public.json" - assert_success - run grep -q 'true' ".ddev/tailscale-router/config/tailscale-public.json" - assert_success + # Should forward all args except --public + run ddev tailscale status + # Command should execute (may show error if not logged in, but shouldn't crash) + + run ddev tailscale ping 127.0.0.1 + # Command should execute (may show error if not logged in, but shouldn't crash) } + + From bbcb5a39e774a50915595cde0eb2d4448f343d39 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 20:19:20 -0400 Subject: [PATCH 22/46] fix: update ownership command in Dockerfile to use dynamic username variable --- web-build/Dockerfile.tailscale-router | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web-build/Dockerfile.tailscale-router b/web-build/Dockerfile.tailscale-router index ed71587..7df8245 100644 --- a/web-build/Dockerfile.tailscale-router +++ b/web-build/Dockerfile.tailscale-router @@ -10,4 +10,4 @@ RUN apt-get update && \ curl -fsSL https://tailscale.com/install.sh | sh ARG username -RUN mkdir -p /var/lib/tailscale && chown -R atj:atj /var/lib/tailscale +RUN mkdir -p /var/lib/tailscale && chown -R ${username}:${username} /var/lib/tailscale From 5e03fe1c3e95aca7555f0f8cb4f47511f274ca76 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 20:31:14 -0400 Subject: [PATCH 23/46] Update config.tailscale-router.yaml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- config.tailscale-router.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index be301ae..28983fd 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -2,7 +2,7 @@ # This configuration adds Tailscale routing capabilities to the web container. web_extra_daemons: - name: tailscale-service - command: tailscaled --statedir=${TS_STATE_DIR} --tun=userspace-networking + command: tailscaled --statedir=${TS_STATE_DIR} --tun=userspace-networking directory: /usr/sbin - name: "tailscale-router" command: tailscale up --auth-key=$TS_AUTHKEY --hostname=$TS_HOSTNAME $TS_EXTRA_ARGS From 78e8aa43258535a050f566e8bc67243c1f386ca6 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 20:31:22 -0400 Subject: [PATCH 24/46] Update config.tailscale-router.yaml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- config.tailscale-router.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index 28983fd..6dbe9b8 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -5,5 +5,5 @@ web_extra_daemons: command: tailscaled --statedir=${TS_STATE_DIR} --tun=userspace-networking directory: /usr/sbin - name: "tailscale-router" - command: tailscale up --auth-key=$TS_AUTHKEY --hostname=$TS_HOSTNAME $TS_EXTRA_ARGS + command: tailscale up --auth-key=$TS_AUTHKEY --hostname=$TS_HOSTNAME $TS_EXTRA_ARGS directory: /var/www/html \ No newline at end of file From 34ce9432e4e045f49073e7488e4ddd00d75d696c Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 20:31:29 -0400 Subject: [PATCH 25/46] Update commands/host/tailscale Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- commands/host/tailscale | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/host/tailscale b/commands/host/tailscale index 49f52de..fe72ff1 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -72,7 +72,7 @@ elif [ "${ARGS[0]}" = "share" ]; then echo "Tailscale $LABEL URL: $TAILSCALE_URL" ddev launch "$TAILSCALE_URL" elif [ "${ARGS[0]}" = "stop" ] ; then - stop_tailscale_share "${ARGS[0]}" + stop_tailscale_share "$CMD" elif [ "${ARGS[0]}" = "stat" ]; then tailscale_web status --self --peers=false --active=true elif [ "${ARGS[0]}" = "proxy" ]; then From 666e00570f102c6986a2f4f129b9afecb7b65ebd Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 20:33:17 -0400 Subject: [PATCH 26/46] Update config.tailscale-router.yaml Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- config.tailscale-router.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index 6dbe9b8..3b34cb7 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -2,7 +2,7 @@ # This configuration adds Tailscale routing capabilities to the web container. web_extra_daemons: - name: tailscale-service - command: tailscaled --statedir=${TS_STATE_DIR} --tun=userspace-networking + command: tailscaled --statedir=${TS_STATE_DIR:-/var/lib/tailscale} --tun=userspace-networking directory: /usr/sbin - name: "tailscale-router" command: tailscale up --auth-key=$TS_AUTHKEY --hostname=$TS_HOSTNAME $TS_EXTRA_ARGS From 2bce8a35665b1821740a7f211b6a0317c81b8111 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 20:34:27 -0400 Subject: [PATCH 27/46] Update commands/host/tailscale Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- commands/host/tailscale | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/host/tailscale b/commands/host/tailscale index fe72ff1..9c434f1 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -20,7 +20,7 @@ get_tailscale_url() { run_tailscale_share() { local cmd="$1" local bg_flag="$2" - tailscale_web $cmd $bg_flag 127.0.0.1:$DDEV_ROUTER_HTTP_PORT + tailscale_web "$cmd" "$bg_flag" 127.0.0.1:$DDEV_ROUTER_HTTP_PORT } stop_tailscale_share() { From 9ef1771cf6ecca1501d769a43afd20067878f1b9 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 20:57:19 -0400 Subject: [PATCH 28/46] Refactor Tailscale command and update configuration for hostname --- commands/host/tailscale | 6 +++++- config.tailscale-router.yaml | 2 +- docker-compose.tailscale-router.yaml | 4 ---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/commands/host/tailscale b/commands/host/tailscale index 9c434f1..c424e49 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -13,7 +13,11 @@ tailscale_web() { # Helper to extract the Tailscale URL from status get_tailscale_url() { - tailscale_web "$1" status | grep -o 'https://[^[:space:]]*' | head -1 + local cmd="$1" + if [ "$cmd" != "funnel" ] && [ "$cmd" != "serve" ]; then + cmd="serve" + fi + tailscale_web "$cmd" status | grep -o 'https://[^[:space:]]*' | head -1 } # Helper to run tailscale share/funnel/serve with options diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index 3b34cb7..43e6f21 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -5,5 +5,5 @@ web_extra_daemons: command: tailscaled --statedir=${TS_STATE_DIR:-/var/lib/tailscale} --tun=userspace-networking directory: /usr/sbin - name: "tailscale-router" - command: tailscale up --auth-key=$TS_AUTHKEY --hostname=$TS_HOSTNAME $TS_EXTRA_ARGS + command: tailscale up --auth-key=$TS_AUTHKEY --hostname=$DDEV_SITENAME $TS_EXTRA_ARGS directory: /var/www/html \ No newline at end of file diff --git a/docker-compose.tailscale-router.yaml b/docker-compose.tailscale-router.yaml index c78e424..f0cbf41 100644 --- a/docker-compose.tailscale-router.yaml +++ b/docker-compose.tailscale-router.yaml @@ -3,12 +3,8 @@ services: web: environment: - TS_AUTHKEY=${TS_AUTHKEY} - - TS_HOSTNAME=${DDEV_SITENAME} - TS_EXTRA_ARGS=--accept-routes --ssh - TS_STATE_DIR=/var/lib/tailscale - - TS_USERSPACE=false - - TS_PRIVACY=${TS_PRIVACY:-private} - - TS_SERVE_CONFIG=/config/tailscale-${TS_PRIVACY}.json volumes: - tailscale-router-state:/var/lib/tailscale volumes: From acee5df0e569fa37dc699afc419321deccf95208 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 23:34:03 -0400 Subject: [PATCH 29/46] Update commands/host/tailscale Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- commands/host/tailscale | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/host/tailscale b/commands/host/tailscale index c424e49..d4a18bf 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -29,7 +29,7 @@ run_tailscale_share() { stop_tailscale_share() { local cmd="$1" - tailscale_web $cmd --https=443 off + tailscale_web "$cmd" --https=443 off } # Parse args, handle --public, and forward all other args From 68f090c6c63546e7f8b2f81b646edfe4361ce98a Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 23:35:16 -0400 Subject: [PATCH 30/46] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- commands/host/tailscale | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/commands/host/tailscale b/commands/host/tailscale index d4a18bf..9f256cf 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -24,7 +24,11 @@ get_tailscale_url() { run_tailscale_share() { local cmd="$1" local bg_flag="$2" - tailscale_web "$cmd" "$bg_flag" 127.0.0.1:$DDEV_ROUTER_HTTP_PORT + if [ -n "$bg_flag" ]; then + tailscale_web "$cmd" "$bg_flag" 127.0.0.1:$DDEV_ROUTER_HTTP_PORT + else + tailscale_web "$cmd" 127.0.0.1:$DDEV_ROUTER_HTTP_PORT + fi } stop_tailscale_share() { From 4638319c04a922d89e64d659ceb4d97e821c4beb Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 23:39:32 -0400 Subject: [PATCH 31/46] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- commands/host/tailscale | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/commands/host/tailscale b/commands/host/tailscale index 9f256cf..04c77b3 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -54,7 +54,8 @@ if [ ${#ARGS[@]} -eq 0 ] || [ "${ARGS[0]}" = "launch" ]; then TAILSCALE_URL=$(get_tailscale_url $CMD) if [ -z "$TAILSCALE_URL" ]; then echo "No share found, creating one..." - run_tailscale_share "$CMD" "--bg" + BG_FLAG="--bg" + run_tailscale_share "$CMD" "$BG_FLAG" sleep 2 TAILSCALE_URL=$(get_tailscale_url $CMD) fi From b78154c6ed5b81a313bab5dd8ff4c1e8bb6354be Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Fri, 12 Sep 2025 23:39:40 -0400 Subject: [PATCH 32/46] Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- commands/host/tailscale | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/commands/host/tailscale b/commands/host/tailscale index 04c77b3..7a3ee0a 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -25,9 +25,9 @@ run_tailscale_share() { local cmd="$1" local bg_flag="$2" if [ -n "$bg_flag" ]; then - tailscale_web "$cmd" "$bg_flag" 127.0.0.1:$DDEV_ROUTER_HTTP_PORT + tailscale_web "$cmd" "$bg_flag" 127.0.0.1:"$DDEV_ROUTER_HTTP_PORT" else - tailscale_web "$cmd" 127.0.0.1:$DDEV_ROUTER_HTTP_PORT + tailscale_web "$cmd" 127.0.0.1:"$DDEV_ROUTER_HTTP_PORT" fi } From 0cb927e87a5aaf62ffb816a1fa3edd982e6c9966 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Mon, 15 Sep 2025 14:42:40 -0400 Subject: [PATCH 33/46] Update Tailscale configuration and Dockerfile for improved setup --- install.yaml | 6 +++++- traefik/config/tailscale-router.yaml | 3 +++ traefik/static_config.tailscale-router.yaml | 3 +++ web-build/Dockerfile.tailscale-router | 10 +--------- 4 files changed, 12 insertions(+), 10 deletions(-) create mode 100644 traefik/config/tailscale-router.yaml create mode 100644 traefik/static_config.tailscale-router.yaml diff --git a/install.yaml b/install.yaml index 7ffddfb..2c95720 100644 --- a/install.yaml +++ b/install.yaml @@ -4,7 +4,11 @@ project_files: - config.tailscale-router.yaml - commands/host/tailscale - web-build/Dockerfile.tailscale-router - - docker-compose.tailscale-router.yaml + - docker-compose.tailscale-router.config.tailscale-router.yaml + +global_config: + - traefik/static_config.tailscale-router.yaml + ddev_version_constraint: '>= v1.24.3' diff --git a/traefik/config/tailscale-router.yaml b/traefik/config/tailscale-router.yaml new file mode 100644 index 0000000..36b343b --- /dev/null +++ b/traefik/config/tailscale-router.yaml @@ -0,0 +1,3 @@ +tls: + certificates: + - certResolver: tailscale-router \ No newline at end of file diff --git a/traefik/static_config.tailscale-router.yaml b/traefik/static_config.tailscale-router.yaml new file mode 100644 index 0000000..8237475 --- /dev/null +++ b/traefik/static_config.tailscale-router.yaml @@ -0,0 +1,3 @@ +certificatesResolvers: + tailscale-router: + tailscale: {} \ No newline at end of file diff --git a/web-build/Dockerfile.tailscale-router b/web-build/Dockerfile.tailscale-router index 7df8245..d197493 100644 --- a/web-build/Dockerfile.tailscale-router +++ b/web-build/Dockerfile.tailscale-router @@ -1,13 +1,5 @@ #ddev-generated -# This Dockerfile installs Tailscale in a web container. -ARG BASE_IMAGE -FROM $BASE_IMAGE - -# Install Tailscale using the official install script -RUN apt-get update && \ - apt-get install -y curl && \ - rm -rf /var/lib/apt/lists/* && \ - curl -fsSL https://tailscale.com/install.sh | sh +RUN curl -fsSL https://tailscale.com/install.sh | sh ARG username RUN mkdir -p /var/lib/tailscale && chown -R ${username}:${username} /var/lib/tailscale From cd824370bcb5b6669dfca6155b802d73845576a1 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Mon, 15 Sep 2025 14:47:16 -0400 Subject: [PATCH 34/46] Fix docker-compose file reference in install.yaml --- install.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.yaml b/install.yaml index 2c95720..da0b9fd 100644 --- a/install.yaml +++ b/install.yaml @@ -4,7 +4,7 @@ project_files: - config.tailscale-router.yaml - commands/host/tailscale - web-build/Dockerfile.tailscale-router - - docker-compose.tailscale-router.config.tailscale-router.yaml + - docker-compose.tailscale-router.yaml global_config: - traefik/static_config.tailscale-router.yaml From 92b3b389b67e007ae9299acdc596e542fa13bdce Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Mon, 15 Sep 2025 14:48:19 -0400 Subject: [PATCH 35/46] Add traefik configuration file to project files in install.yaml --- install.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.yaml b/install.yaml index da0b9fd..65e4bf4 100644 --- a/install.yaml +++ b/install.yaml @@ -5,11 +5,11 @@ project_files: - commands/host/tailscale - web-build/Dockerfile.tailscale-router - docker-compose.tailscale-router.yaml + - traefik/config/tailscale-router.yaml global_config: - traefik/static_config.tailscale-router.yaml - ddev_version_constraint: '>= v1.24.3' post_install_actions: From e02732cb7fa77f6b6f93137da09d1a60b2142bef Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Mon, 15 Sep 2025 14:50:20 -0400 Subject: [PATCH 36/46] Add ddev-generated comments to Traefik configuration files --- traefik/config/tailscale-router.yaml | 2 ++ traefik/static_config.tailscale-router.yaml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/traefik/config/tailscale-router.yaml b/traefik/config/tailscale-router.yaml index 36b343b..46b3cbe 100644 --- a/traefik/config/tailscale-router.yaml +++ b/traefik/config/tailscale-router.yaml @@ -1,3 +1,5 @@ +#ddev-generated + tls: certificates: - certResolver: tailscale-router \ No newline at end of file diff --git a/traefik/static_config.tailscale-router.yaml b/traefik/static_config.tailscale-router.yaml index 8237475..dc33017 100644 --- a/traefik/static_config.tailscale-router.yaml +++ b/traefik/static_config.tailscale-router.yaml @@ -1,3 +1,5 @@ +#ddev-generated + certificatesResolvers: tailscale-router: tailscale: {} \ No newline at end of file From 7692914525604c51ca742220997d6125aaadaa5f Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Mon, 15 Sep 2025 14:54:56 -0400 Subject: [PATCH 37/46] Fix typo in install.yaml: change 'global_config' to 'global_files' --- install.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install.yaml b/install.yaml index 65e4bf4..013f643 100644 --- a/install.yaml +++ b/install.yaml @@ -7,7 +7,7 @@ project_files: - docker-compose.tailscale-router.yaml - traefik/config/tailscale-router.yaml -global_config: +global_files: - traefik/static_config.tailscale-router.yaml ddev_version_constraint: '>= v1.24.3' From 50d9d2889d980bff37a98c0195e4714921ca0142 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Mon, 15 Sep 2025 15:46:55 -0400 Subject: [PATCH 38/46] Update install.yaml for improved installation instructions --- docker-compose.tailscale-router.yaml | 1 + install.yaml | 5 +---- traefik/config/tailscale-router.yaml | 5 ----- traefik/static_config.tailscale-router.yaml | 5 ----- 4 files changed, 2 insertions(+), 14 deletions(-) delete mode 100644 traefik/config/tailscale-router.yaml delete mode 100644 traefik/static_config.tailscale-router.yaml diff --git a/docker-compose.tailscale-router.yaml b/docker-compose.tailscale-router.yaml index f0cbf41..2235565 100644 --- a/docker-compose.tailscale-router.yaml +++ b/docker-compose.tailscale-router.yaml @@ -7,5 +7,6 @@ services: - TS_STATE_DIR=/var/lib/tailscale volumes: - tailscale-router-state:/var/lib/tailscale + - ./custom_certs:/var/lib/tailscale/certs volumes: tailscale-router-state: diff --git a/install.yaml b/install.yaml index 013f643..1bfd6c3 100644 --- a/install.yaml +++ b/install.yaml @@ -5,10 +5,7 @@ project_files: - commands/host/tailscale - web-build/Dockerfile.tailscale-router - docker-compose.tailscale-router.yaml - - traefik/config/tailscale-router.yaml - -global_files: - - traefik/static_config.tailscale-router.yaml + - custom_certs ddev_version_constraint: '>= v1.24.3' diff --git a/traefik/config/tailscale-router.yaml b/traefik/config/tailscale-router.yaml deleted file mode 100644 index 46b3cbe..0000000 --- a/traefik/config/tailscale-router.yaml +++ /dev/null @@ -1,5 +0,0 @@ -#ddev-generated - -tls: - certificates: - - certResolver: tailscale-router \ No newline at end of file diff --git a/traefik/static_config.tailscale-router.yaml b/traefik/static_config.tailscale-router.yaml deleted file mode 100644 index dc33017..0000000 --- a/traefik/static_config.tailscale-router.yaml +++ /dev/null @@ -1,5 +0,0 @@ -#ddev-generated - -certificatesResolvers: - tailscale-router: - tailscale: {} \ No newline at end of file From eb1c8534d7770be413c2cbb42c11fa036d31255a Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Mon, 15 Sep 2025 15:47:54 -0400 Subject: [PATCH 39/46] Fix file paths in project_files section of install.yaml --- install.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/install.yaml b/install.yaml index 1bfd6c3..17573e8 100644 --- a/install.yaml +++ b/install.yaml @@ -2,10 +2,10 @@ name: tailscale-router project_files: - config.tailscale-router.yaml - - commands/host/tailscale - - web-build/Dockerfile.tailscale-router - - docker-compose.tailscale-router.yaml - - custom_certs + - ./commands/host/tailscale + - ./web-build/Dockerfile.tailscale-router + - ./docker-compose.tailscale-router.yaml + - ./custom_certs ddev_version_constraint: '>= v1.24.3' From 7a36f5862506fec0c4be6411dd9e95361be64dcd Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Mon, 15 Sep 2025 15:50:42 -0400 Subject: [PATCH 40/46] Add README.txt for custom certificates and update project_files in install.yaml --- custom_certs/README.txt | 3 +++ install.yaml | 8 ++++---- 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 custom_certs/README.txt diff --git a/custom_certs/README.txt b/custom_certs/README.txt new file mode 100644 index 0000000..f919807 --- /dev/null +++ b/custom_certs/README.txt @@ -0,0 +1,3 @@ +#ddev-generated + +Files in this directory are generated by `tailscale cert` to when a new certificate is generated for the host. \ No newline at end of file diff --git a/install.yaml b/install.yaml index 17573e8..d32f630 100644 --- a/install.yaml +++ b/install.yaml @@ -2,10 +2,10 @@ name: tailscale-router project_files: - config.tailscale-router.yaml - - ./commands/host/tailscale - - ./web-build/Dockerfile.tailscale-router - - ./docker-compose.tailscale-router.yaml - - ./custom_certs + - commands/host/tailscale + - web-build/Dockerfile.tailscale-router + - docker-compose.tailscale-router.yaml + - custom_certs/README.txt ddev_version_constraint: '>= v1.24.3' From 38db99a8fb6594abcaf80f1c580a06c81779c61d Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Tue, 16 Sep 2025 15:30:59 -0400 Subject: [PATCH 41/46] Add Tailscale certificate and serve daemons to configuration --- config.tailscale-router.yaml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index 43e6f21..6deeeb9 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -6,4 +6,10 @@ web_extra_daemons: directory: /usr/sbin - name: "tailscale-router" command: tailscale up --auth-key=$TS_AUTHKEY --hostname=$DDEV_SITENAME $TS_EXTRA_ARGS - directory: /var/www/html \ No newline at end of file + directory: /var/www/html + - name: "tailscale-certificates" + command: bash -c 'tailscale cert --cert-file custom_certs/${DDEV_PROJECT}.crt --key-file custom_certs/${DDEV_PROJECT}.key $(tailscale status --peers=false --json | jq -r ".Self.DNSName" | sed "s/\.$//")' + directory: /var/www/html/.ddev + - name: "tailscale-serve" + command: bash -c 'tailscale serve $(tailscale status --peers=false --json | jq -r ".Self.DNSName" | sed "s/\.$//")' + directory: /var/www/html/.ddev \ No newline at end of file From 1eec0454db761e38c5658e9cbdd06eba8b0036d1 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Tue, 16 Sep 2025 15:35:28 -0400 Subject: [PATCH 42/46] Update tailscale-serve command to include DDEV_HOST_PORT_HTTP --- config.tailscale-router.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index 6deeeb9..a5286f9 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -11,5 +11,5 @@ web_extra_daemons: command: bash -c 'tailscale cert --cert-file custom_certs/${DDEV_PROJECT}.crt --key-file custom_certs/${DDEV_PROJECT}.key $(tailscale status --peers=false --json | jq -r ".Self.DNSName" | sed "s/\.$//")' directory: /var/www/html/.ddev - name: "tailscale-serve" - command: bash -c 'tailscale serve $(tailscale status --peers=false --json | jq -r ".Self.DNSName" | sed "s/\.$//")' + command: bash -c 'tailscale serve $(tailscale status --peers=false --json | jq -r ".Self.DNSName" | sed "s/\.$//"):$DDEV_HOST_PORT_HTTP' directory: /var/www/html/.ddev \ No newline at end of file From a724bbb47c99b617fc4bc6925fecf25366b77c64 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Tue, 16 Sep 2025 17:18:08 -0400 Subject: [PATCH 43/46] Update README and scripts for Tailscale integration; remove unused README.txt --- README.md | 92 ++++++++++++-------------- commands/host/tailscale | 97 +++++++++++----------------- config.tailscale-router.yaml | 2 +- custom_certs/README.txt | 3 - docker-compose.tailscale-router.yaml | 1 - install.yaml | 1 - 6 files changed, 80 insertions(+), 116 deletions(-) delete mode 100644 custom_certs/README.txt diff --git a/README.md b/README.md index d659d6d..6e32d39 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,8 @@ Before installing the add-on: ```bash ddev dotenv set .ddev/.env.tailscale-router --ts-authkey=tskey-auth-your-key-here ``` + + > **Note:** You can also set up authentication using `ddev tailscale login` after your project starts. This provides secure, interactive access for your DDEV project. 4. **For public access**: Configure your [Access Control List (ACL)](https://tailscale.com/kb/1223/funnel#funnel-node-attribute) to enable Funnel. Add the `funnel` node attribute to your ACL policy in the [Tailscale admin console](https://login.tailscale.com/admin/acls): @@ -71,10 +73,15 @@ Before installing the add-on: ```bash ddev add-on get atj4me/ddev-tailscale-router ddev restart +``` -# Launch your project's Tailscale URL in browser +Launch your project's Tailscale URL in browser +``` ddev tailscale launch -# Or get your project's Tailscale URL +``` + +Or get your project's Tailscale URL +``` ddev tailscale url ``` @@ -82,71 +89,52 @@ Your project's permanent Tailscale URL will look like: `https://.< ### Configure Privacy (Optional) -By default, your project is only accessible to devices on your Tailscale network (private mode). You can make it publicly accessible: +By default, your project is only accessible to devices on your Tailscale network (private mode). This happens automatically when the project starts. You can stop sharing automatically using +```bash +ddev tailscale stop +``` + +To make your project publicly accessible (Funnel mode): ```bash -# Switch to public mode (accessible to anyone on the internet) -ddev dotenv set .ddev/.env.tailscale-router --ts-privacy=public -ddev restart +ddev tailscale share --public +``` -# Switch back to private mode (default) -ddev dotenv set .ddev/.env.tailscale-router --ts-privacy=private -ddev restart +To revert to private mode (only accessible to your Tailscale devices): + +```bash +ddev tailscale share ``` ## Usage -Access all [Tailscale CLI](https://tailscale.com/kb/1080/cli) commands plus helpful shortcuts: -| Command | Description | -| ------- | ----------- | -| `ddev tailscale ` | Run any Tailscale CLI command | -| `ddev tailscale launch` | Launch your project's Tailscale URL in browser | -| `ddev tailscale share [--bg] [--public]` | Start sharing your project (use `--public` for Funnel, `--bg` to run in background) | -| `ddev tailscale status` | Show Tailscale status | -| `ddev tailscale ping ` | Ping a Tailscale device | -| `ddev tailscale stat` | Show status with self and active peers only | -| `ddev tailscale proxy` | Show funnel status | -| `ddev tailscale url` | Get your project's Tailscale URL | -| `ddev logs -s tailscale-router` | Show logs for the Tailscale router service | - -You can run any [Tailscale CLI](https://tailscale.com/kb/1080/cli) command directly, and use the special `--public` flag to share via Funnel: +Access all [Tailscale CLI](https://tailscale.com/kb/1080/cli) commands plus helpful shortcuts: | Command | Description | | ------- | ----------- | -| `ddev tailscale [flags]` | Run any Tailscale CLI command (all arguments except `--public` are passed through) | - -**Note:** -- The `--public` flag is handled by the wrapper and will switch to Tailscale Funnel mode (public sharing). It is not passed to the Tailscale CLI. -- All other arguments and flags are forwarded to the Tailscale CLI as-is. +| `ddev tailscale launch [--public]` | Launch your project's Tailscale URL in browser (`--public` uses Funnel mode for public access) | +| `ddev tailscale share [--public]` | Start sharing your project (`--public` uses Funnel mode for public access) | +| `ddev tailscale stop` | Stop sharing | +| `ddev tailscale stat` | Show Tailscale status for self and active peers | +| `ddev tailscale proxystat` | Show Funnel/Serve (proxy) status | +| `ddev tailscale url` | Get your project's Tailscale Funnel URL | +| `ddev tailscale login` | Authenticate with Tailscale interactively | +| `ddev tailscale ` | Run any Tailscale CLI command in the web container | -**Examples:** - -```bash -# Launch private share (default) -ddev tailscale launch -# Launch public share (Funnel) -ddev tailscale launch --public -# Start sharing in background (private) -ddev tailscale share --bg -# Start sharing in background (public) -ddev tailscale share --bg --public -# Run any Tailscale CLI command -ddev tailscale status -ddev tailscale ping -``` ## Components of the Repository -- **`install.yaml`** - DDEV add-on installation manifest that copies necessary files and shows setup instructions -- **`docker-compose.tailscale-router.yaml`** - Core Docker Compose configuration defining the `tailscale-router` service with Tailscale authentication and `socat` traffic forwarding -- **`commands/host/tailscale`** - Custom DDEV host command providing access to Tailscale CLI with helpful shortcuts -- **`tailscale-router/config/`** - JSON configuration files for Tailscale's serve command: - - `tailscale-private.json` - Private sharing configuration (default) - - `tailscale-public.json` - Public sharing configuration -- **`tests/test.bats`** - Automated test script for verifying Tailscale integration -- **`.github/workflows/tests.yml`** - GitHub Actions for automated testing on push and schedule -- **`.github/ISSUE_TEMPLATE/` and `PULL_REQUEST_TEMPLATE.md`** - Templates for streamlined contributions + +- **`install.yaml`** – DDEV add-on installation manifest, copies files and provides setup instructions +- **`docker-compose.tailscale-router.yaml`** – Docker Compose config for the Tailscale router service, including authentication and proxy settings +- **`config.tailscale-router.yaml`** – Main YAML configuration for Tailscale router settings +- **`commands/host/tailscale`** – Bash wrapper for DDEV host, provides Tailscale CLI access and shortcuts +- **`web-build/Dockerfile.tailscale-router`** – Dockerfile for building the web container with Tailscale support +- **`tests/test.bats`** – Automated BATS test script for verifying Tailscale integration +- **`tests/testdata/`** – Test data for automated tests +- **`.github/workflows/tests.yml`** – GitHub Actions workflow for automated testing +- **`.github/ISSUE_TEMPLATE/` and `PULL_REQUEST_TEMPLATE.md`** – Contribution and PR templates ## Testing diff --git a/commands/host/tailscale b/commands/host/tailscale index 7a3ee0a..f979fee 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -11,83 +11,64 @@ tailscale_web() { ddev exec -s web tailscale "$@" } -# Helper to extract the Tailscale URL from status get_tailscale_url() { - local cmd="$1" - if [ "$cmd" != "funnel" ] && [ "$cmd" != "serve" ]; then - cmd="serve" - fi - tailscale_web "$cmd" status | grep -o 'https://[^[:space:]]*' | head -1 + URL=$(ddev exec -s web bash -c 'tailscale status --peers=false --json | jq -r ".Self.DNSName" | sed "s/\.$//"') + echo "https://$URL" +} + +tailscale_login() { + ddev exec -s web bash -c 'tailscale up --auth-key=$TS_AUTHKEY --hostname=$DDEV_SITENAME $TS_EXTRA_ARGS' } -# Helper to run tailscale share/funnel/serve with options run_tailscale_share() { local cmd="$1" - local bg_flag="$2" - if [ -n "$bg_flag" ]; then - tailscale_web "$cmd" "$bg_flag" 127.0.0.1:"$DDEV_ROUTER_HTTP_PORT" - else - tailscale_web "$cmd" 127.0.0.1:"$DDEV_ROUTER_HTTP_PORT" + # Capture output + output=$(tailscale_web "$cmd" --bg 127.0.0.1:$DDEV_ROUTER_HTTP_PORT) + share_status=$? + if [ $share_status -ne 0 ]; then + tailscale_login + run_tailscale_share "$cmd" + exit 0 fi + # Replace the disable proxy instruction + echo "$output" | sed "s/To disable the proxy, run: tailscale $cmd --https=443 off/To disable the proxy, run: ddev tailscale stop instead/" } stop_tailscale_share() { local cmd="$1" - tailscale_web "$cmd" --https=443 off + tailscale_web "$cmd" --https 443 off } -# Parse args, handle --public, and forward all other args + CMD="serve" -LABEL="private" -ARGS=() -for arg in "$@"; do - if [ "$arg" = "--public" ]; then - CMD="funnel" - LABEL="public" - else - ARGS+=("$arg") - fi -done +if [ "$2" = "--public" ]; then + echo -e "⚠️ Sharing your local development environment publicly can expose sensitive data. Ensure you understand the implications before proceeding." + CMD="funnel" +fi + +if [ "$1" = "login" ]; then + tailscale_login + exit 0 +elif [ "$1" = "launch" ] || [ "$1" = "share" ] || [ $# -eq 0 ]; then + + run_tailscale_share "$CMD" + sleep 1 # Give it a moment to start + TAILSCALE_URL=$(get_tailscale_url) -# If no args, default to launching a share -if [ ${#ARGS[@]} -eq 0 ] || [ "${ARGS[0]}" = "launch" ]; then - TAILSCALE_URL=$(get_tailscale_url $CMD) - if [ -z "$TAILSCALE_URL" ]; then - echo "No share found, creating one..." - BG_FLAG="--bg" - run_tailscale_share "$CMD" "$BG_FLAG" - sleep 2 - TAILSCALE_URL=$(get_tailscale_url $CMD) - fi - if [ -z "$TAILSCALE_URL" ]; then - echo "Error: Could not retrieve Tailscale URL after $CMD." - exit 1 - fi - echo "Tailscale $LABEL URL: $TAILSCALE_URL" - ddev launch "$TAILSCALE_URL" -elif [ "${ARGS[0]}" = "share" ]; then - BG_FLAG="" - for arg in "${ARGS[@]}"; do - if [ "$arg" = "--bg" ]; then - BG_FLAG="--bg" - fi - done - run_tailscale_share "$CMD" "$BG_FLAG" - TAILSCALE_URL=$(get_tailscale_url $CMD) if [ -z "$TAILSCALE_URL" ]; then - echo "Error: Could not retrieve Tailscale URL after $CMD." + echo "Error: Could not retrieve Tailscale URL." exit 1 fi - echo "Tailscale $LABEL URL: $TAILSCALE_URL" + ddev launch "$TAILSCALE_URL" -elif [ "${ARGS[0]}" = "stop" ] ; then +elif [ "$1" = "stop" ]; then stop_tailscale_share "$CMD" -elif [ "${ARGS[0]}" = "stat" ]; then +elif [ "$1" = "stat" ]; then tailscale_web status --self --peers=false --active=true -elif [ "${ARGS[0]}" = "proxy" ]; then - tailscale_web $CMD status -elif [ "${ARGS[0]}" = "url" ]; then - get_tailscale_url $CMD +elif [ "$1" = "proxystat" ]; then + tailscale_web funnel status +elif [ "$1" = "url" ]; then + get_tailscale_url else - tailscale_web "${ARGS[@]}" + tailscale_web "$@" fi diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index a5286f9..cf46413 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -11,5 +11,5 @@ web_extra_daemons: command: bash -c 'tailscale cert --cert-file custom_certs/${DDEV_PROJECT}.crt --key-file custom_certs/${DDEV_PROJECT}.key $(tailscale status --peers=false --json | jq -r ".Self.DNSName" | sed "s/\.$//")' directory: /var/www/html/.ddev - name: "tailscale-serve" - command: bash -c 'tailscale serve $(tailscale status --peers=false --json | jq -r ".Self.DNSName" | sed "s/\.$//"):$DDEV_HOST_PORT_HTTP' + command: bash -c 'tailscale serve 127.0.0.1:$DDEV_ROUTER_HTTP_PORT' directory: /var/www/html/.ddev \ No newline at end of file diff --git a/custom_certs/README.txt b/custom_certs/README.txt deleted file mode 100644 index f919807..0000000 --- a/custom_certs/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -#ddev-generated - -Files in this directory are generated by `tailscale cert` to when a new certificate is generated for the host. \ No newline at end of file diff --git a/docker-compose.tailscale-router.yaml b/docker-compose.tailscale-router.yaml index 2235565..f0cbf41 100644 --- a/docker-compose.tailscale-router.yaml +++ b/docker-compose.tailscale-router.yaml @@ -7,6 +7,5 @@ services: - TS_STATE_DIR=/var/lib/tailscale volumes: - tailscale-router-state:/var/lib/tailscale - - ./custom_certs:/var/lib/tailscale/certs volumes: tailscale-router-state: diff --git a/install.yaml b/install.yaml index d32f630..7ffddfb 100644 --- a/install.yaml +++ b/install.yaml @@ -5,7 +5,6 @@ project_files: - commands/host/tailscale - web-build/Dockerfile.tailscale-router - docker-compose.tailscale-router.yaml - - custom_certs/README.txt ddev_version_constraint: '>= v1.24.3' From 2a469c88261c25d214a8086e0bace90b4656f51d Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Tue, 16 Sep 2025 18:26:04 -0400 Subject: [PATCH 44/46] Enhance Tailscale command functionality with public sharing option and dynamic port configuration; update docker-compose environment variable syntax. --- commands/host/tailscale | 37 ++++++++++++++++++---------- config.tailscale-router.yaml | 2 +- docker-compose.tailscale-router.yaml | 2 +- 3 files changed, 26 insertions(+), 15 deletions(-) diff --git a/commands/host/tailscale b/commands/host/tailscale index f979fee..98e7668 100644 --- a/commands/host/tailscale +++ b/commands/host/tailscale @@ -21,14 +21,31 @@ tailscale_login() { } run_tailscale_share() { - local cmd="$1" + local cmd="serve" + local port="$DDEV_ROUTER_HTTP_PORT" + # Parse flags from arguments + for arg in "$@"; do + case $arg in + --public) + echo -e "⚠️ Sharing your local development environment publicly can expose sensitive data. Ensure you understand the implications before proceeding." + cmd="funnel" + ;; + --port=*) + port="${arg#--port=}" + ;; + esac + done # Capture output - output=$(tailscale_web "$cmd" --bg 127.0.0.1:$DDEV_ROUTER_HTTP_PORT) + output=$(tailscale_web "$cmd" --bg 127.0.0.1:$port) share_status=$? - if [ $share_status -ne 0 ]; then + if [[ "$output" == *"Logged out"* ]]; then tailscale_login - run_tailscale_share "$cmd" - exit 0 + output=$(tailscale_web "$cmd" --bg 127.0.0.1:$port) + share_status=$? + fi + if [ $share_status -ne 0 ]; then + echo "Error: Tailscale share failed. Output:\n$output" + exit $share_status fi # Replace the disable proxy instruction echo "$output" | sed "s/To disable the proxy, run: tailscale $cmd --https=443 off/To disable the proxy, run: ddev tailscale stop instead/" @@ -41,25 +58,19 @@ stop_tailscale_share() { CMD="serve" -if [ "$2" = "--public" ]; then - echo -e "⚠️ Sharing your local development environment publicly can expose sensitive data. Ensure you understand the implications before proceeding." - CMD="funnel" -fi +PORT="$DDEV_ROUTER_HTTP_PORT" if [ "$1" = "login" ]; then tailscale_login exit 0 elif [ "$1" = "launch" ] || [ "$1" = "share" ] || [ $# -eq 0 ]; then - - run_tailscale_share "$CMD" + run_tailscale_share "$@" sleep 1 # Give it a moment to start TAILSCALE_URL=$(get_tailscale_url) - if [ -z "$TAILSCALE_URL" ]; then echo "Error: Could not retrieve Tailscale URL." exit 1 fi - ddev launch "$TAILSCALE_URL" elif [ "$1" = "stop" ]; then stop_tailscale_share "$CMD" diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index cf46413..a5b89a7 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -11,5 +11,5 @@ web_extra_daemons: command: bash -c 'tailscale cert --cert-file custom_certs/${DDEV_PROJECT}.crt --key-file custom_certs/${DDEV_PROJECT}.key $(tailscale status --peers=false --json | jq -r ".Self.DNSName" | sed "s/\.$//")' directory: /var/www/html/.ddev - name: "tailscale-serve" - command: bash -c 'tailscale serve 127.0.0.1:$DDEV_ROUTER_HTTP_PORT' + command: bash -c 'tailscale serve $DDEV_ROUTER_HTTP_PORT' directory: /var/www/html/.ddev \ No newline at end of file diff --git a/docker-compose.tailscale-router.yaml b/docker-compose.tailscale-router.yaml index f0cbf41..8670730 100644 --- a/docker-compose.tailscale-router.yaml +++ b/docker-compose.tailscale-router.yaml @@ -2,7 +2,7 @@ services: web: environment: - - TS_AUTHKEY=${TS_AUTHKEY} + - TS_AUTHKEY=${TS_AUTHKEY:-} - TS_EXTRA_ARGS=--accept-routes --ssh - TS_STATE_DIR=/var/lib/tailscale volumes: From f59fb1ad636e2c53b06424c7f717d2ed507d296f Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Tue, 16 Sep 2025 19:11:40 -0400 Subject: [PATCH 45/46] Update README to enhance authentication instructions and clarify public access setup for Tailscale --- README.md | 63 ++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 48 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 6e32d39..c6181c8 100644 --- a/README.md +++ b/README.md @@ -47,15 +47,10 @@ Before installing the add-on: echo 'export TS_AUTHKEY=tskey-auth-your-key-here' >> ~/.bashrc ``` - Alternatively, you can set it per project (**NOT RECOMMENDED**, because `.ddev/.env.tailscale-router` is not intended to store secrets) using: + Alternatively, you can also set up authentication using `ddev tailscale login` after your project starts. This provides secure, interactive access for your DDEV project. - ```bash - ddev dotenv set .ddev/.env.tailscale-router --ts-authkey=tskey-auth-your-key-here - ``` - - > **Note:** You can also set up authentication using `ddev tailscale login` after your project starts. This provides secure, interactive access for your DDEV project. -4. **For public access**: Configure your [Access Control List (ACL)](https://tailscale.com/kb/1223/funnel#funnel-node-attribute) to enable Funnel. Add the `funnel` node attribute to your ACL policy in the [Tailscale admin console](https://login.tailscale.com/admin/acls): +4. **For public access**: To enable Funnel (public sharing), configure your [Access Control List (ACL)](https://tailscale.com/kb/1223/funnel#funnel-node-attribute) in the [Tailscale admin console](https://login.tailscale.com/admin/acls) by adding the `funnel` node attribute: ```json { @@ -68,6 +63,17 @@ Before installing the add-on: } ``` +5. **For SSL certificate generation** (Optional): To run the command `tailscale cert` from the container, the machine needs corresponsing access by adding a `certs` capability inside node attributes: + + ```json + "nodeAttrs": [ + { + "target": ["*"], + "attr": ["tailscale.com/cap/certs"], + }, + ], + ``` + ## Installation ```bash @@ -75,25 +81,29 @@ ddev add-on get atj4me/ddev-tailscale-router ddev restart ``` -Launch your project's Tailscale URL in browser -``` + +To launch your project's Tailscale URL in your browser: +```bash ddev tailscale launch ``` -Or get your project's Tailscale URL -``` +To get your project's Tailscale URL: +```bash ddev tailscale url ``` -Your project's permanent Tailscale URL will look like: `https://..ts.net`. Also, it can be found in your [Tailscale admin console](https://login.tailscale.com/admin/machines). + +Your project's permanent Tailscale URL will look like: `https://..ts.net`. You can also find it in your [Tailscale admin console](https://login.tailscale.com/admin/machines). ### Configure Privacy (Optional) -By default, your project is only accessible to devices on your Tailscale network (private mode). This happens automatically when the project starts. You can stop sharing automatically using + +By default, your project is only accessible to devices on your Tailscale network (private mode). This happens automatically when the project starts. You can stop sharing using: ```bash ddev tailscale stop ``` + To make your project publicly accessible (Funnel mode): ```bash @@ -108,7 +118,6 @@ ddev tailscale share ## Usage - Access all [Tailscale CLI](https://tailscale.com/kb/1080/cli) commands plus helpful shortcuts: | Command | Description | @@ -123,12 +132,34 @@ Access all [Tailscale CLI](https://tailscale.com/kb/1080/cli) commands plus help | `ddev tailscale ` | Run any Tailscale CLI command in the web container | +> **Note:** The add-on assumes your project uses the port configured in `DDEV_ROUTER_HTTP_PORT` (usually port `80`). To use a custom port, add `--port=` to your command. For example, `ddev tailscale share --port=8025 --public` will expose the Mailpit service to the internet. Only ports inside the `web` service are supported. + +## Advanced Commands + +[Tailscale Serve](https://tailscale.com/kb/1242/tailscale-serve) or [Tailscale Funnel](https://tailscale.com/kb/1311/tailscale-funnel) commands can be used to serve custom ports or files on your TailNet Server. You would need to run `ddev tailscale stop` first. + +```bash +# To serve a ReactJS application running on port 8443 +ddev tailscale stop +ddev tailscale serve --bg --https=8443 localhost:5173 +``` + + +Only ports `8443`, `443`, and `10000` are supported by `tailscale funnel`. + + +## Troubleshooting + + +If you get an error while running the share command, try logging out using `ddev tailscale logout` and then run your command again (`ddev tailscale share`, `ddev tailscale launch`, or your custom command). + + ## Components of the Repository - **`install.yaml`** – DDEV add-on installation manifest, copies files and provides setup instructions - **`docker-compose.tailscale-router.yaml`** – Docker Compose config for the Tailscale router service, including authentication and proxy settings -- **`config.tailscale-router.yaml`** – Main YAML configuration for Tailscale router settings +- **`config.tailscale-router.yaml`** – Main YAML configuration for Tailscale router settings - **`commands/host/tailscale`** – Bash wrapper for DDEV host, provides Tailscale CLI access and shortcuts - **`web-build/Dockerfile.tailscale-router`** – Dockerfile for building the web container with Tailscale support - **`tests/test.bats`** – Automated BATS test script for verifying Tailscale integration @@ -148,6 +179,7 @@ bats tests/test.bats Tests also run automatically in GitHub Actions on every push. + ## Contributing Contributions are welcome! If you have suggestions, bug reports, or feature requests, please: @@ -157,6 +189,7 @@ Contributions are welcome! If you have suggestions, bug reports, or feature requ 3. Make your changes. 4. Submit a pull request. + ## License This project is licensed under the Apache License 2.0. See the [LICENSE](LICENSE) file for details. From 91cd37ec899fe95410ace18d323df0d1ed2d3170 Mon Sep 17 00:00:00 2001 From: Ajith Thampi Joseph Date: Tue, 16 Sep 2025 19:25:15 -0400 Subject: [PATCH 46/46] Remove unused tailscale-certificates daemon from configuration --- config.tailscale-router.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/config.tailscale-router.yaml b/config.tailscale-router.yaml index a5b89a7..54a9c9b 100644 --- a/config.tailscale-router.yaml +++ b/config.tailscale-router.yaml @@ -7,9 +7,6 @@ web_extra_daemons: - name: "tailscale-router" command: tailscale up --auth-key=$TS_AUTHKEY --hostname=$DDEV_SITENAME $TS_EXTRA_ARGS directory: /var/www/html - - name: "tailscale-certificates" - command: bash -c 'tailscale cert --cert-file custom_certs/${DDEV_PROJECT}.crt --key-file custom_certs/${DDEV_PROJECT}.key $(tailscale status --peers=false --json | jq -r ".Self.DNSName" | sed "s/\.$//")' - directory: /var/www/html/.ddev - name: "tailscale-serve" command: bash -c 'tailscale serve $DDEV_ROUTER_HTTP_PORT' directory: /var/www/html/.ddev \ No newline at end of file