Files
Lumpiasty e0cbaee48b
ci/woodpecker/push/release-tag Pipeline was successful
split docs into README + USAGE/DEVELOPMENT/DESIGN
README shrinks to a repo intro with pointers. Separate the three
audiences:
- docs/USAGE.md      deploy the prebuilt image on RouterOS + operate it
- docs/DEVELOPMENT.md build, local test, version bump, cut releases
- docs/DESIGN.md     size optimizations, feature allowlist, why the
                     updater and netmap disk-cache are removed, flash-wear
                     protection, versioning/release architecture, the
                     overlayfs layer-duplication gotcha, dependency pinning
2026-05-29 04:24:12 +02:00

4.4 KiB

Development

Building the image, testing it locally, bumping the Tailscale version, and cutting releases. This is for working on this repo; if you just want to run the published image on a router, see USAGE.md.

For the reasoning behind the build choices, see DESIGN.md.

Prerequisites

  • docker with buildx.

  • For cross-arch builds, QEMU/binfmt emulators registered:

    docker run --privileged --rm tonistiigi/binfmt --install arm64,arm
    

The Go toolchain and busybox are built inside the image stages, so no local Go install is needed.

Building

All architectures at once

Use the helper script:

# Build all arches and load into local docker
./build.sh

# Build all arches and also export per-arch tarballs into ./dist/
./build.sh --tar

# Build a single arch
./build.sh arm64
./build.sh --tar armv7

Manual single-arch build

The architecture is selected via buildx --platform; the Dockerfile maps it to the correct GOARCH/GOARM automatically:

docker buildx build --platform linux/arm64  --load -t mikrotik-tailscale:arm64 .
docker buildx build --platform linux/arm/v7 --load -t mikrotik-tailscale:armv7 .
docker buildx build --platform linux/amd64  --load -t mikrotik-tailscale:amd64 .

To build for a different Tailscale version, add:

--build-arg TAILSCALE_VERSION=v1.98.3

Notes

  • The Go builder cross-compiles natively (fast); only the busybox stage runs under emulation for non-native targets.

  • The build prints the resolved target and Go build tags, e.g.:

    Cross-compiling: GOOS=linux GOARCH=arm64 GOARM=
    Build tags: ts_include_cli,ts_omit_ace,ts_omit_acme,...
    

Running (local test)

Quick smoke test on a dev machine with Docker (this is not how it runs on a router — see USAGE.md for that):

# Create a volume for persistent state
docker volume create tailscale-state

# Start the daemon
docker run -d \
  --name tailscale \
  --cap-add NET_ADMIN \
  --cap-add NET_RAW \
  --device /dev/net/tun \
  --tmpfs /var/run/tailscale \
  -v tailscale-state:/var/lib/tailscale \
  mikrotik-tailscale

# Authenticate (opens browser / prints auth URL)
docker exec tailscale tailscale login

# Check status
docker exec tailscale tailscale status

# Advertise a subnet
docker exec tailscale tailscale set --advertise-routes=192.168.88.0/24

# Advertise as exit node
docker exec tailscale tailscale set --advertise-exit-node

Subnet routes and exit node advertisement must also be approved in the Tailscale admin console.

For headless / unattended auth, use a reusable auth key from the admin console (Settings → Keys):

docker exec tailscale tailscale up \
  --authkey=tskey-auth-<key> \
  --advertise-routes=192.168.88.0/24 \
  --advertise-exit-node

Bumping the Tailscale version

Version bumps (Tailscale, busybox, base image digests) are normally proposed automatically via Renovate (see DESIGN.md → Dependency pinning). Merge the Renovate PR; a Tailscale bump then auto-publishes a new release.

The feature allowlist in the Dockerfile carries forward automatically across Tailscale versions — any new ts_omit_* tags introduced in a new release will be omitted by default.

To bump manually, edit ARG TAILSCALE_VERSION in the Dockerfile (so the pin stays in version control) and rebuild:

./build.sh --tar      # rebuild all arches at the pinned version
# or, override at build time without editing the Dockerfile:
docker buildx build --platform linux/arm64 \
  --build-arg TAILSCALE_VERSION=v1.100.0 \
  --load -t mikrotik-tailscale:arm64 .

Cutting a manual release

A Tailscale bump auto-creates v<ts>-mt.1 and publishes it. For a meaningful fix/change on the current Tailscale version, tag the next mt.N by hand:

# fix something, commit to main, then:
git tag -a v1.98.3-mt.2 -m "Fix X"
git push origin v1.98.3-mt.2

The tag push triggers the build + multi-arch publish automatically. See DESIGN.md → Versioning & releases for the full scheme and CI wiring.

Validating CI configs locally

# Renovate repo config
docker run --rm -e RENOVATE_CONFIG_TYPE=repo -v "$PWD":/work -w /work \
  --entrypoint renovate-config-validator renovate/renovate

# Woodpecker pipelines
docker run --rm -v "$PWD":/work -w /work \
  woodpeckerci/woodpecker-cli:v3 lint .woodpecker/renovate.yaml