The action spins up an ephemeral Tailscale node during the CI run using OAuth (so it never needs a long-lived auth key), reaches your Portainer API over the tailnet, deploys or updates your stack, then immediately logs the node out on cleanup — even if the job fails.
The problem I was trying to solve: I run Portainer on a home server and didn't want to expose port 9443 publicly or set up a reverse proxy just to enable CD from GitHub Actions. Tailscale already handled my VPN — I just needed the CI runner to join the tailnet temporarily. It supports stack create/update/delete, private registry auth (GHCR, Docker Hub, etc.), env var injection, MagicDNS hostnames, and auto-detects your Portainer endpoint if you only have one.
Marketplace: https://github.com/marketplace/actions/portainer-tailscale-d...
Happy to answer questions — feedback welcome, especially if you use Portainer + Tailscale differently.