From 67af7a8e60f9d00fd74184a96341c359acff3c3e Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Wed, 6 May 2026 06:29:16 -0700 Subject: [PATCH 1/3] C1: add containers/tailscale (nix) for ringtail proxyclass Local mirror of docker.io/tailscale/tailscale, pinned at v1.94.2 to match service-versions.yaml and current ringtail proxyclass. Nix-only build via ringtail's nix-container-builder runner; mirrors upstream Dockerfile contents (tailscale, tailscaled, containerboot binaries plus iptables, iproute2, ca-certificates). Co-Authored-By: Claude Opus 4.7 (1M context) --- containers/tailscale/default.nix | 77 ++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 containers/tailscale/default.nix diff --git a/containers/tailscale/default.nix b/containers/tailscale/default.nix new file mode 100644 index 0000000..8e87f76 --- /dev/null +++ b/containers/tailscale/default.nix @@ -0,0 +1,77 @@ +# Nix-built tailscale container for ringtail's tailscale-operator ProxyClass +# Builds v1.94.2 from forge mirror; mirrors upstream Dockerfile contents. +# Built with dockerTools.buildLayeredImage on the ringtail nix-container-builder. +{ pkgs ? import { } }: + +let + version = "1.94.2"; + + src = pkgs.fetchgit { + url = "https://forge.ops.eblu.me/mirrors/tailscale.git"; + rev = "v${version}"; + hash = "sha256-qjWVB8xWVgIVUgrf27F6hwiFIE+4ERXWeHv26ugg/x4="; + }; + + tailscale = pkgs.buildGoModule { + inherit src version; + pname = "tailscale"; + vendorHash = "sha256-WeMTOkERj4hvdg4yPaZ1gRgKnhRIBXX55kUVbX/k/xM="; + + subPackages = [ + "cmd/tailscale" + "cmd/tailscaled" + "cmd/containerboot" + ]; + + ldflags = [ + "-s" + "-w" + "-X tailscale.com/version.longStamp=${version}" + "-X tailscale.com/version.shortStamp=${version}" + ]; + + doCheck = false; + + meta = with pkgs.lib; { + description = "The easiest, most secure way to use WireGuard"; + homepage = "https://tailscale.com"; + license = licenses.bsd3; + }; + }; +in + +pkgs.dockerTools.buildLayeredImage { + name = "blumeops/tailscale"; + tag = "v${version}"; + + contents = [ + tailscale + pkgs.cacert + pkgs.iptables + pkgs.iproute2 + pkgs.tzdata + pkgs.busybox + ]; + + # Match upstream Dockerfile: symlink iptables-legacy over iptables. + # Synology NAS and similar hosts don't support nftables. + # Also recreate the /tailscale/run.sh compat symlink. + extraCommands = '' + rm -f usr/sbin/iptables usr/sbin/ip6tables + ln -s ${pkgs.iptables}/bin/iptables-legacy usr/sbin/iptables || true + ln -s ${pkgs.iptables}/bin/ip6tables-legacy usr/sbin/ip6tables || true + mkdir -p tailscale + ln -s /bin/containerboot tailscale/run.sh + mkdir -p tmp + chmod 1777 tmp + ''; + + config = { + Entrypoint = [ "/bin/containerboot" ]; + Env = [ + "SSL_CERT_FILE=${pkgs.cacert}/etc/ssl/certs/ca-bundle.crt" + "TZDIR=${pkgs.tzdata}/share/zoneinfo" + "PATH=/bin:/usr/bin:/usr/sbin" + ]; + }; +} -- 2.50.1 (Apple Git-155) From 3bc99903557b658949124dabb21e2863b3987d34 Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Wed, 6 May 2026 06:42:58 -0700 Subject: [PATCH 2/3] C1: rewrite ringtail proxyclass image to local tailscale container MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a kustomize images: rewrite scoped to tailscale-operator-ringtail, pointing docker.io/tailscale/tailscale at registry.ops.eblu.me's v1.94.2-67af7a8-nix build. Indri's tailscale-operator overlay is unchanged — it continues pulling upstream until the k3s migration retires the indri minikube cluster. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../tailscale-operator-ringtail/kustomization.yaml | 8 ++++++++ docs/changelog.d/mirror-tailscale-container.infra.md | 1 + 2 files changed, 9 insertions(+) create mode 100644 docs/changelog.d/mirror-tailscale-container.infra.md diff --git a/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml b/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml index a14ca81..5e30291 100644 --- a/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml +++ b/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml @@ -8,3 +8,11 @@ resources: - ../tailscale-operator-base - proxygroup-ingress.yaml - external-secret.yaml + +# Rewrite the proxyclass image to our local nix-built mirror. +# Scoped to ringtail only; indri's tailscale-operator/kustomization.yaml still +# pulls from upstream docker.io. +images: + - name: docker.io/tailscale/tailscale + newName: registry.ops.eblu.me/blumeops/tailscale + newTag: v1.94.2-67af7a8-nix diff --git a/docs/changelog.d/mirror-tailscale-container.infra.md b/docs/changelog.d/mirror-tailscale-container.infra.md new file mode 100644 index 0000000..54ca3ba --- /dev/null +++ b/docs/changelog.d/mirror-tailscale-container.infra.md @@ -0,0 +1 @@ +Add local nix container build for `tailscale` (`containers/tailscale/default.nix`) so ringtail's tailscale-operator ProxyClass proxy pods pull from the forge mirror instead of `docker.io/tailscale/tailscale`. Pinned at v1.94.2 to match `service-versions.yaml`. Indri's tailscale-operator continues to use upstream during the k8s-to-ringtail migration. -- 2.50.1 (Apple Git-155) From 4381e1d86f5007f48f53d771caee90f1011bc66b Mon Sep 17 00:00:00 2001 From: Erich Blume Date: Wed, 6 May 2026 06:46:37 -0700 Subject: [PATCH 3/3] C1: switch to strategic merge patch for proxyclass image rewrite Kustomize's images: directive only rewrites image fields on built-in k8s kinds (Pod, Deployment, etc.), not on custom resources like ProxyClass. The first attempt left the rendered ProxyClass pointing at upstream docker.io. Replaces it with a strategic merge patch over spec.statefulSet.pod.tailscale{Container,InitContainer}.image. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../kustomization.yaml | 16 +++++++++++----- .../proxyclass-image.yaml | 11 +++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 argocd/manifests/tailscale-operator-ringtail/proxyclass-image.yaml diff --git a/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml b/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml index 5e30291..2d9ceb2 100644 --- a/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml +++ b/argocd/manifests/tailscale-operator-ringtail/kustomization.yaml @@ -11,8 +11,14 @@ resources: # Rewrite the proxyclass image to our local nix-built mirror. # Scoped to ringtail only; indri's tailscale-operator/kustomization.yaml still -# pulls from upstream docker.io. -images: - - name: docker.io/tailscale/tailscale - newName: registry.ops.eblu.me/blumeops/tailscale - newTag: v1.94.2-67af7a8-nix +# pulls from upstream docker.io. A strategic merge patch is used instead of +# kustomize's `images:` directive because that directive only rewrites images +# in standard k8s container fields, not custom-resource fields like +# ProxyClass.spec.statefulSet.pod.tailscaleContainer.image. +patches: + - path: proxyclass-image.yaml + target: + group: tailscale.com + version: v1alpha1 + kind: ProxyClass + name: default diff --git a/argocd/manifests/tailscale-operator-ringtail/proxyclass-image.yaml b/argocd/manifests/tailscale-operator-ringtail/proxyclass-image.yaml new file mode 100644 index 0000000..b585e22 --- /dev/null +++ b/argocd/manifests/tailscale-operator-ringtail/proxyclass-image.yaml @@ -0,0 +1,11 @@ +apiVersion: tailscale.com/v1alpha1 +kind: ProxyClass +metadata: + name: default +spec: + statefulSet: + pod: + tailscaleContainer: + image: registry.ops.eblu.me/blumeops/tailscale:v1.94.2-67af7a8-nix + tailscaleInitContainer: + image: registry.ops.eblu.me/blumeops/tailscale:v1.94.2-67af7a8-nix -- 2.50.1 (Apple Git-155)