Skip to content
Open
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
30 changes: 26 additions & 4 deletions documentation/free-up-port-53.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ A DNS service such as Pi-hole or AdGuard Home needs port 53. This page applies o

## Why port 53 is in use

On Debian-based systems that use `systemd-resolved`, such as Ubuntu Server 22.04 and 24.04, a DNS stub listener runs by default. It listens on `127.0.0.53:53` and answers DNS queries from local applications. A container that publishes port 53 on all host addresses then fails to start, because the port is already taken.
On Debian-based systems that use `systemd-resolved`, such as Ubuntu Server 22.04 and 24.04, a DNS stub listener runs by default. It listens on `127.0.0.53:53` and, since systemd 250 (for example on Ubuntu 24.04), also on `127.0.0.54:53`. It answers DNS queries from local applications. A container that publishes port 53 on all host addresses then fails to start, because the port is already taken.

The `DNSStubListener` option in `/etc/systemd/resolved.conf` controls this listener:

- `DNSStubListener=yes`: `systemd-resolved` listens on `127.0.0.53:53`. This is the default.
- `DNSStubListener=yes`: `systemd-resolved` listens on port 53 of these addresses. This is the default.
- `DNSStubListener=no`: `systemd-resolved` does not listen on port 53, so another DNS service can use it.

## Steps
Expand All @@ -25,13 +25,35 @@ The `DNSStubListener` option in `/etc/systemd/resolved.conf` controls this liste
DNSStubListener=no
```

3. Restart the service:
3. Point `/etc/resolv.conf` to the file that lists your upstream DNS servers:

```bash
sudo ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
```

Do this before the next step. On Ubuntu, `/etc/resolv.conf` points to the stub at `127.0.0.53`. That stub stops answering after the restart, so the host would lose DNS.

4. Restart the service:

```bash
sudo systemctl restart systemd-resolved
```

5. Check that the host still resolves names:

```bash
getent hosts github.com
```

The command prints an IP address and the name. If it prints nothing, undo the change and enable the stub listener again:

```bash
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
sudo sed -i 's/^DNSStubListener=no/#DNSStubListener=yes/' /etc/systemd/resolved.conf
sudo systemctl restart systemd-resolved
```

4. Check that port 53 is free:
6. Check that port 53 is free:

```bash
sudo ss -tuln | grep ':53 '
Expand Down
8 changes: 5 additions & 3 deletions documentation/standard-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,22 @@ The application uses `network_mode: service:tailscale` and starts only after the
| `IMAGE_URL` | Image of the application. |
| `SERVICEPORT` | Port used by the optional `ports` block. The port for Tailscale Serve is set in `compose.yaml`. |
| `DNS_SERVER` | DNS server used by the optional `dns` block. |
| `TS_AUTHKEY` | Your Tailscale auth key. Only needed for the first start. |
| `TS_AUTHKEY` | Your Tailscale auth key. Used only when the container is not logged in, for example at the first start or after you delete `./ts/state`. |
| `TZ` | Time zone, passed to the application when its image supports it. |

Some stacks need secrets that you choose. Compose stops with an error that starts with `required variable X is missing a value` until you set them. The service README lists them under "Before you start".

## Data

All data stays in the service directory, next to `compose.yaml`.

| Path | Content |
| ------------------- | ----------------------------------------- |
| `./config` | Tailscale configuration files. |
| `./config` | Holds `serve.json`, the Serve configuration. Compose writes it from the `configs` block in `compose.yaml` when it creates the container or starts a stopped one, so change `compose.yaml` instead. `docker compose restart` keeps the current file. |
| `./ts/state` | Tailscale state, including the device key. |
| `./<service>-data/` | Data of the application. |

Keep `./ts/state` when you recreate the stack. Without it, the device joins your Tailnet again as a new device.
Keep `./ts/state` when you recreate the stack. Without it, the device needs a valid auth key and joins your Tailnet as a new device.

## DNS

Expand Down
25 changes: 13 additions & 12 deletions documentation/tailscale-on-arm.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Setting up Tailscale on OpenPLi (ARM Linux)
# Install Tailscale on an OpenPLi set-top box (without Docker)

This page describes how to install and configure **Tailscale** on an OpenPLi set-top box using the ARM version of Linux.
Because OpenPLi is a lightweight distribution, the usual package manager method may not work. Instead, you may need to use Tailscale’s static binaries and configure an init.d service for automatic startup.
Expand All @@ -20,11 +20,10 @@ curl -fsSL https://tailscale.com/install.sh | sh

## 2. Download the ARM static binaries

Go to [Tailscale Stable Releases](https://pkgs.tailscale.com/stable/#static) and download the ARM package.
For example:
Go to [Tailscale Stable Releases](https://pkgs.tailscale.com/stable/#static) and download the archive for your architecture: `arm`, `arm64`, `mips`, or `mipsle`. The file names follow the pattern `tailscale_<version>_<arch>.tgz`, where `<version>` is the current version shown on that page. For an ARM device, for example:

```sh
wget https://pkgs.tailscale.com/stable/tailscale_1.86.2_arm.tgz
wget https://pkgs.tailscale.com/stable/tailscale_<version>_arm.tgz
```

---
Expand All @@ -34,11 +33,13 @@ wget https://pkgs.tailscale.com/stable/tailscale_1.86.2_arm.tgz
Extract the archive and copy the executables into `/usr/sbin`:

```sh
tar zxvf tailscale_1.86.2_arm.tgz
cp tailscale_1.86.2_arm/tailscal* /usr/sbin/
tar zxvf tailscale_*_arm.tgz
cp tailscale_*_arm/tailscal* /usr/sbin/
chmod +x /usr/sbin/tailscal*
```

If you downloaded another architecture, replace `arm` in the file names.

This provides both `tailscale` (CLI) and `tailscaled` (daemon).

---
Expand All @@ -50,7 +51,7 @@ Since OpenPLi does not use `systemd`, we need to create an **init.d service** to
Create the service script:

```sh
cat << EOF >/etc/init.d/tailscaled
cat << 'EOF' > /etc/init.d/tailscaled
#!/bin/sh
DAEMON=/usr/sbin/tailscaled
PIDFILE=/var/run/tailscaled.pid
Expand All @@ -59,20 +60,20 @@ DAEMON_OPTS="--state=/var/lib/tailscale/tailscaled.state --socket=/var/run/tails
case "$1" in
start)
echo "Starting tailscaled"
start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON -- $DAEMON_OPTS
start-stop-daemon --start --quiet --background --make-pidfile --pidfile "$PIDFILE" --exec "$DAEMON" -- $DAEMON_OPTS
;;
stop)
echo "Stopping tailscaled"
start-stop-daemon --stop --quiet ---retry=TERM/9/KILL/11 --pidfile $PIDFILE
$DAEMON --cleanup
rm -f $PIDFILE
start-stop-daemon --stop --quiet --retry=TERM/9/KILL/11 --pidfile "$PIDFILE"
"$DAEMON" --cleanup
rm -f "$PIDFILE"
;;
restart)
$0 stop
$0 start
;;
status)
if [ -f $PIDFILE ] && kill -0 "$(cat $PIDFILE)" 2>/dev/null; then
if [ -f "$PIDFILE" ] && kill -0 "$(cat "$PIDFILE")" 2>/dev/null; then
echo "tailscaled is running"
else
echo "tailscaled is not running"
Expand Down
Loading