commit e211ce677053a236add7174617908bbe5f137328 Author: Patrick Gniza Date: Mon Nov 3 19:47:43 2025 +0100 initial commit diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..f0ded94 --- /dev/null +++ b/.env.sample @@ -0,0 +1,11 @@ +# Headscale / Tailscale Einstellungen +TS_AUTHKEY=tskey-xxxxxxxxxxxxxxxxxxxxxxxx +TS_LOGIN_SERVER=https://headscale.example.com +TS_HOSTNAME=portainer-agent-hamburg + +# Optionale Parameter +TS_ACCEPT_DNS=false +TS_ACCEPT_ROUTES=true + +# Container Verhalten +TZ=Europe/Berlin diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8c2c315 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +# Lokale Umgebungsdateien +.env +.env.* +!.env.sample + +# Docker +tailscale/ +__pycache__/ +*.log + +# Build-Artefakte +*.bak +*.swp +*.tmp diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..1ce8782 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,41 @@ +# --- Stage 1: Portainer Agent --- +FROM portainer/agent:latest AS agent + +# --- Stage 2: Tailscale --- +FROM tailscale/tailscale:latest AS tailscale + +# --- Stage 3: Finales Image (Alpine) --- +FROM alpine:3.20 + +# Basis-Pakete +RUN apk add --no-cache \ + iptables \ + iproute2 \ + ca-certificates \ + curl \ + bash \ + tini + +# Binaries von Tailscale kopieren +COPY --from=tailscale /usr/local/bin/tailscaled /usr/local/bin/tailscaled +COPY --from=tailscale /usr/local/bin/tailscale /usr/local/bin/tailscale + +# Komplette Portainer-Agent-App übernehmen +COPY --from=agent /app /app + +# Arbeitsverzeichnis +WORKDIR /app + +# Startskript hinzufügen +COPY entrypoint.sh /entrypoint.sh +RUN chmod +x /entrypoint.sh + +# TUN-Gerät vorbereiten +RUN mkdir -p /dev/net +VOLUME ["/var/lib/tailscale"] + +# Portainer Agent Port +EXPOSE 9001 + +ENTRYPOINT ["/sbin/tini", "--"] +CMD ["/entrypoint.sh"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..55b7509 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# .. Portainer Agent + Tailscale (Headscale) + +Ein schlankes Alpine-basiertes Docker-Image, das den **Portainer Agent** über **Tailscale oder Headscale** sicher erreichbar macht . + ohne offene Ports im Internet. + +--- + +## .. Features + +- .. Kombinierter Container mit **Portainer Agent** & **Tailscale Client** +- .. Sichere Kommunikation über Tailscale / Headscale (kein Port 9001 nach außen nötig) +- .. Basierend auf **Alpine Linux** (minimaler Footprint, ca. 70 MB) +- .. Automatische Wiederverbindung dank persistentem `/var/lib/tailscale` +- .. Konfiguration über `.env`-Datei +- .. Multi-Stage-Dockerfile (nutzt offizielle `portainer/agent` + `tailscale/tailscale` Images) + +--- + +## ... Projektstruktur + +```bash +. +... Dockerfile # Multi-Stage-Build (Portainer-Agent + Tailscale) +... entrypoint.sh # Startskript für Tailscale + Agent +... docker-compose.yml # Beispiel-Compose für schnellen Start +... .env.sample # Konfigurationsvorlage +... .gitignore # ignoriert deine lokale .env +... README.md diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..8f39595 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,26 @@ +version: "3.8" + +services: + agent: + build: . + container_name: portainer_agent_tailscale + cap_add: + - NET_ADMIN + devices: + - /dev/net/tun + environment: + - TZ=${TZ} + - TS_AUTHKEY=${TS_AUTHKEY} + - TS_LOGIN_SERVER=${TS_LOGIN_SERVER} + - TS_HOSTNAME=${TS_HOSTNAME} + - TS_ACCEPT_DNS=${TS_ACCEPT_DNS} + - TS_ACCEPT_ROUTES=${TS_ACCEPT_ROUTES} + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /var/lib/docker/volumes:/var/lib/docker/volumes + - tailscale-state:/var/lib/tailscale + restart: unless-stopped + +volumes: + tailscale-state: + name: portainer_tailscale_state diff --git a/entrypoint.sh b/entrypoint.sh new file mode 100644 index 0000000..be5ddf5 --- /dev/null +++ b/entrypoint.sh @@ -0,0 +1,24 @@ +#!/bin/sh +set -e + +echo "[+] Starting Tailscale daemon..." +/usr/local/bin/tailscaled --state=/var/lib/tailscale/tailscaled.state & + +sleep 2 + +# Prüfen, ob bereits verbunden +if ! tailscale status >/dev/null 2>&1; then + echo "[+] Bringing up Tailscale..." + tailscale up \ + --authkey="${TS_AUTHKEY}" \ + --login-server="${TS_LOGIN_SERVER:-https://controlplane.tailscale.com}" \ + --hostname="${TS_HOSTNAME:-portainer-agent}" \ + --accept-dns="${TS_ACCEPT_DNS:-false}" \ + --accept-routes="${TS_ACCEPT_ROUTES:-true}" +else + echo "[+] Existing Tailscale session found, skipping login." +fi + +echo "[+] Tailscale IP: $(tailscale ip -4 || true)" +echo "[+] Starting Portainer Agent..." +exec /app/agent