Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 18 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,29 @@ to your `devcontainer.json`:
}
```

Then launch your Codespace. After it starts up, run [`tailscale up`](https://tailscale.com/kb/1080/cli/#up):
## Starting Tailscale

The Tailscale daemon starts automatically as part of the devcontainer entrypoint.

### Manual Log in

```shell
sudo tailscale up --accept-routes
```

You'll only need to run `tailscale up` once per Codespace.
The Tailscale state will be saved between rebuilds.
More info: [`tailscale up`](https://tailscale.com/kb/1080/cli/#up)

### Automatic login

Create an [auth key](https://tailscale.com/kb/1085/auth-keys) in the Tailscale
[admin panel](https://login.tailscale.com/admin/settings/keys).

Create a codespace secret called `TS_AUTH_KEY` in your
[codespaces configuration](https://github.com/settings/codespaces) containing
the auth key you made above.

Now whenever you launch a devcontainer with access to this secret, it will
automatically perform a `tailscale up --accept-routes --auth-key=$TS_AUTH_KEY`.

## Details

Expand Down
34 changes: 29 additions & 5 deletions src/tailscale/tailscaled-devcontainer-start.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ if [[ $(id -u) -ne 0 ]]; then
exec sudo --non-interactive -E "$0" "$@"
fi

# Move the auth key to a non-exported variable so it is not leaking into child
# process environments.
auth_key="$TS_AUTH_KEY"
unset TS_AUTH_KEY

if [[ ! -c /dev/net/tun ]]; then
mkdir -p /dev/net
mknod /dev/net/tun c 10 200
Expand All @@ -31,11 +36,18 @@ TAILSCALED_PID=""
TAILSCALED_SOCK=/var/run/tailscale/tailscaled.sock
TAILSCALED_LOG=/var/log/tailscaled.log

# Note: TS_DEBUG_FIREWALL_MODE: it is not recommended that users copy this
# setting into other environments, the feature is in test and will be formally
# released in the future, debug flags may later be recycled for other purposes
# leading to unexpected behavior.
>$TAILSCALED_LOG 2>&1 TS_DEBUG_FIREWALL_MODE=auto /usr/local/sbin/tailscaled &
(
exec 1>$TAILSCALED_LOG 2>&1
cd /
umask 0
# Note: TS_DEBUG_FIREWALL_MODE: it is not recommended that users copy this
# setting into other environments, the feature is in test and will be formally
# released in the future, debug flags may later be recycled for other purposes
# leading to unexpected behavior.
unset TAILSCALED_PID TAILSCALED_SOCK TAILSCALED_LOG
export TS_DEBUG_FIREWALL_MODE=auto
exec setsid /usr/local/sbin/tailscaled
) &
TAILSCALED_PID=$!

if [[ -n "$TAILSCALED_PID" ]]; then
Expand All @@ -50,4 +62,16 @@ if [[ -n "$TAILSCALED_PID" ]]; then
break
fi
done
fi

if [[ -n "$auth_key" ]]; then
if [[ "$auth_key" == "test-auth-key" ]]; then
touch /tmp/test-auth-key-seen
else
hostnamearg=""
if [[ -n "${CODESPACE_NAME}" ]]; then
hostnamearg="--hostname=${CODESPACE_NAME}"
fi
/usr/local/sbin/tailscale up --accept-routes --authkey="$auth_key" $hostnamearg
fi
fi
2 changes: 2 additions & 0 deletions src/tailscale/tailscaled-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,6 @@

/usr/local/sbin/tailscaled-devcontainer-start

unset TS_AUTH_KEY

exec "$@"
9 changes: 9 additions & 0 deletions test/tailscale/scenarios.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,14 @@
"version": "1.80.2"
}
}
},
"tailscale_auth_key": {
"image": "ubuntu:latest",
"containerEnv": {
"TS_AUTH_KEY": "test-auth-key"
},
"features": {
"tailscale": {}
}
}
}
22 changes: 22 additions & 0 deletions test/tailscale/tailscale_auth_key.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
# Copyright (c) 2025 Tailscale Inc & AUTHORS All rights reserved.
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.

set -e

source dev-container-features-test-lib

# Wait for the auth key to be seen by the start script.
count=100
while ((count--)); do
[[ -f /tmp/test-auth-key-seen ]] && break
sleep 0.1
done

check "/tmp/test-auth-key-seen" ls /tmp/test-auth-key-seen

# It would be nice to directly test that the entrypoint is doing unset
# TS_AUTH_KEY, however that isn't visible to the test execution.

reportResults
8 changes: 4 additions & 4 deletions test/tailscale/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ set -e

source dev-container-features-test-lib

if [[ "$VERSION" == latest ]]; then
check "Daemon: " tailscale version --daemon
else
check "$VERSION" tailscale version --daemon
check "daemon is running" tailscale version --daemon

if [[ -n "$VERSION" ]]; then
check "version is correct" bash -c "tailscale version --daemon | grep -q $VERSION"
fi

reportResults