diff --git a/.github/workflows/generate-registry.yml b/.github/workflows/generate-registry.yml new file mode 100644 index 0000000..99e2e54 --- /dev/null +++ b/.github/workflows/generate-registry.yml @@ -0,0 +1,35 @@ +name: Generate registry + +on: + push: + branches: + - main + paths: + - "services/**" + - "README.md" + - "scripts/generate_registry.py" + workflow_dispatch: + +permissions: + contents: write + +jobs: + generate: + if: github.actor != 'github-actions[bot]' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Generate registry.json + run: python3 scripts/generate_registry.py --ref "${{ github.ref_name }}" + - name: Commit registry.json + run: | + if git diff --quiet; then + echo "No registry changes" + exit 0 + fi + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add registry.json + git commit -m "chore: update registry.json" + git push diff --git a/.github/workflows/linting.yml b/.github/workflows/linting.yml index e75cca1..7a0b3c5 100644 --- a/.github/workflows/linting.yml +++ b/.github/workflows/linting.yml @@ -6,7 +6,6 @@ on: - main paths-ignore: - '.github/**' - # - 'README.md' - 'LICENSE' - '.gitignore' - '.gitattributes' @@ -16,7 +15,6 @@ on: - main paths-ignore: - '.github/**' - # - 'README.md' - 'LICENSE' - '.gitignore' - '.gitattributes' @@ -27,11 +25,11 @@ jobs: runs-on: ubuntu-latest steps: - name: Clone this repo - uses: actions/checkout@v4 + uses: actions/checkout@v6 - - name: Markdown Linting Action - id: lint - uses: avto-dev/markdown-lint@v1.5.0 + - name: Markdown Linting + uses: DavidAnson/markdownlint-cli2-action@v22 with: config: "./.markdownlint.yml" - args: "./services/**/*.md" + globs: "./services/**/*.md" + fix: true diff --git a/registry.json b/registry.json new file mode 100644 index 0000000..f074282 --- /dev/null +++ b/registry.json @@ -0,0 +1,1283 @@ +{ + "name": "ScaleTail Templates", + "description": "Curated Tailscale sidecar Docker configurations for self-hosted services.", + "version": "1.0.0", + "author": "ScaleTail", + "url": "https://github.com/jackspiering/ScaleTail-testing", + "templates": [ + { + "id": "adguardhome", + "name": "AdGuard Home", + "description": "ScaleTail configuration for AdGuard Home running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/adguardhome/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/adguardhome/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/adguardhome/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "adguardhome-sync", + "name": "AdGuardHome Sync", + "description": "ScaleTail configuration for AdGuardHome Sync running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/adguardhome-sync/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/adguardhome-sync/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/adguardhome-sync/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "audiobookshelf", + "name": "Audiobookshelf", + "description": "ScaleTail configuration for Audiobookshelf running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/audiobookshelf/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/audiobookshelf/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/audiobookshelf/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "bazarr", + "name": "Bazarr", + "description": "ScaleTail configuration for Bazarr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/bazarr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/bazarr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/bazarr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "bentopdf", + "name": "BentoPDF", + "description": "ScaleTail configuration for BentoPDF running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/bentopdf/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/bentopdf/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/bentopdf/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "beszel-agent", + "name": "Beszel Agent", + "description": "ScaleTail configuration for Beszel Agent running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/beszel/agent/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/beszel/agent/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/beszel/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "beszel-hub", + "name": "Beszel Hub", + "description": "ScaleTail configuration for Beszel Hub running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/beszel/hub/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/beszel/hub/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/beszel/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "booklore", + "name": "BookLore", + "description": "ScaleTail configuration for BookLore running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/booklore/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/booklore/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/booklore/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "caddy", + "name": "Caddy", + "description": "ScaleTail configuration for Caddy running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/caddy/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/caddy/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/caddy/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "changedetection", + "name": "ChangeDetection.io", + "description": "ScaleTail configuration for ChangeDetection.io running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/changedetection/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/changedetection/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/changedetection/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "clipcascade", + "name": "ClipCascade", + "description": "ScaleTail configuration for ClipCascade running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/clipcascade/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/clipcascade/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/clipcascade/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "coder", + "name": "Coder", + "description": "ScaleTail configuration for Coder running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/coder/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/coder/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/coder/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "configarr", + "name": "Configarr", + "description": "ScaleTail configuration for Configarr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/configarr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/configarr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/configarr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "convertx", + "name": "ConvertX", + "description": "ScaleTail configuration for ConvertX running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/convertx/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/convertx/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/convertx/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "copyparty", + "name": "Copyparty", + "description": "ScaleTail configuration for Copyparty running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/copyparty/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/copyparty/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/copyparty/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "cyberchef", + "name": "CyberChef", + "description": "ScaleTail configuration for CyberChef running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/cyberchef/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/cyberchef/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/cyberchef/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "ddns-updater", + "name": "DDNS Updater", + "description": "ScaleTail configuration for DDNS Updater running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/ddns-updater/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/ddns-updater/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/ddns-updater/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "docmost", + "name": "Docmost", + "description": "ScaleTail configuration for Docmost running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/docmost/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/docmost/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/docmost/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "donetick", + "name": "Donetick", + "description": "ScaleTail configuration for Donetick running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/donetick/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/donetick/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/donetick/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "dozzle", + "name": "Dozzle", + "description": "ScaleTail configuration for Dozzle running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/dozzle/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/dozzle/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/dozzle/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "dumbdo", + "name": "DumbDo", + "description": "ScaleTail configuration for DumbDo running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/dumbdo/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/dumbdo/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/dumbdo/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "eigenfocus", + "name": "Eigenfocus", + "description": "ScaleTail configuration for Eigenfocus running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/eigenfocus/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/eigenfocus/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/eigenfocus/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "excalidraw", + "name": "Excalidraw", + "description": "ScaleTail configuration for Excalidraw running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/excalidraw/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/excalidraw/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/excalidraw/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "flatnotes", + "name": "Flatnotes", + "description": "ScaleTail configuration for Flatnotes running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/flatnotes/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/flatnotes/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/flatnotes/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "forgejo", + "name": "Forgejo", + "description": "ScaleTail configuration for Forgejo running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/forgejo/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/forgejo/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/forgejo/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "formbricks", + "name": "Formbricks", + "description": "ScaleTail configuration for Formbricks running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/formbricks/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/formbricks/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/formbricks/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "fossflow", + "name": "FossFLOW", + "description": "ScaleTail configuration for FossFLOW running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/fossflow/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/fossflow/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/fossflow/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "ghost", + "name": "Ghost", + "description": "ScaleTail configuration for Ghost running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/ghost/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/ghost/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/ghost/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "gitsave", + "name": "GitSave", + "description": "ScaleTail configuration for GitSave running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/gitsave/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/gitsave/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/gitsave/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "glance", + "name": "Glance", + "description": "ScaleTail configuration for Glance running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/glance/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/glance/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/glance/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "gokapi", + "name": "Gokapi", + "description": "ScaleTail configuration for Gokapi running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/gokapi/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/gokapi/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/gokapi/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "gotify", + "name": "Gotify", + "description": "ScaleTail configuration for Gotify running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/gotify/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/gotify/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/gotify/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "grampsweb", + "name": "Gramps Web", + "description": "ScaleTail configuration for Gramps Web running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/grampsweb/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/grampsweb/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/grampsweb/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "haptic", + "name": "Haptic", + "description": "ScaleTail configuration for Haptic running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/haptic/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/haptic/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/haptic/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "hemmelig", + "name": "Hemmelig.app", + "description": "ScaleTail configuration for Hemmelig.app running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/hemmelig/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/hemmelig/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/hemmelig/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "homarr", + "name": "Homarr", + "description": "ScaleTail configuration for Homarr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/homarr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/homarr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/homarr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "home-assistant", + "name": "Home Assistant", + "description": "ScaleTail configuration for Home Assistant running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/home-assistant/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/home-assistant/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/home-assistant/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "homebox", + "name": "Homebox", + "description": "ScaleTail configuration for Homebox running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/homebox/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/homebox/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/homebox/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "homepage", + "name": "Homepage", + "description": "ScaleTail configuration for Homepage running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/homepage/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/homepage/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/homepage/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "hytale", + "name": "Hytale Server", + "description": "ScaleTail configuration for Hytale Server running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/hytale/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/hytale/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/hytale/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "immich", + "name": "Immich", + "description": "ScaleTail configuration for Immich running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/immich/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/immich/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/immich/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "isley", + "name": "Isley", + "description": "ScaleTail configuration for Isley running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/isley/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/isley/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/isley/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "it-tools", + "name": "IT-Tools", + "description": "ScaleTail configuration for IT-Tools running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/it-tools/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/it-tools/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/it-tools/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "jellyfin", + "name": "Jellyfin", + "description": "ScaleTail configuration for Jellyfin running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/jellyfin/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/jellyfin/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/jellyfin/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "jellyseerr", + "name": "Jellyseerr", + "description": "ScaleTail configuration for Jellyseerr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/jellyseerr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/jellyseerr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/jellyseerr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "kaneo", + "name": "Kaneo", + "description": "ScaleTail configuration for Kaneo running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/kaneo/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/kaneo/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/kaneo/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "karakeep", + "name": "Karakeep", + "description": "ScaleTail configuration for Karakeep running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/karakeep/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/karakeep/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/karakeep/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "kavita", + "name": "Kavita", + "description": "ScaleTail configuration for Kavita running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/kavita/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/kavita/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/kavita/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "languagetool", + "name": "LanguageTool", + "description": "ScaleTail configuration for LanguageTool running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/languagetool/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/languagetool/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/languagetool/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "linkding", + "name": "Linkding", + "description": "ScaleTail configuration for Linkding running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/linkding/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/linkding/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/linkding/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "lube-logger", + "name": "LubeLogger", + "description": "ScaleTail configuration for LubeLogger running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/lube-logger/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/lube-logger/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/lube-logger/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "mattermost", + "name": "Mattermost", + "description": "ScaleTail configuration for Mattermost running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/mattermost/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/mattermost/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/mattermost/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "mealie", + "name": "Mealie", + "description": "ScaleTail configuration for Mealie running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/mealie/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/mealie/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/mealie/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "metube", + "name": "Metube", + "description": "ScaleTail configuration for Metube running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/metube/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/metube/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/metube/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "miniqr", + "name": "Mini-QR", + "description": "ScaleTail configuration for Mini-QR running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/miniqr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/miniqr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/miniqr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "nanote", + "name": "Nanote", + "description": "ScaleTail configuration for Nanote running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nanote/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nanote/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nanote/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "navidrome", + "name": "Navidrome", + "description": "ScaleTail configuration for Navidrome running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/navidrome/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/navidrome/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/navidrome/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "nessus", + "name": "Nessus", + "description": "ScaleTail configuration for Nessus running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nessus/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nessus/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nessus/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "netbox", + "name": "Netbox", + "description": "ScaleTail configuration for Netbox running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/netbox/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/netbox/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/netbox/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "nextcloud", + "name": "Nextcloud Server", + "description": "ScaleTail configuration for Nextcloud Server running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nextcloud/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nextcloud/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nextcloud/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "nodered", + "name": "Node-RED", + "description": "ScaleTail configuration for Node-RED running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nodered/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nodered/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/nodered/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "ntfy", + "name": "ntfy", + "description": "ScaleTail configuration for ntfy running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/ntfy/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/ntfy/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/ntfy/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "overseerr", + "name": "Overseerr", + "description": "ScaleTail configuration for Overseerr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/overseerr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/overseerr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/overseerr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "picard", + "name": "MusicBrainz Picard", + "description": "ScaleTail configuration for MusicBrainz Picard running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/picard/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/picard/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/picard/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "pihole", + "name": "Pi-hole", + "description": "ScaleTail configuration for Pi-hole running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/pihole/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/pihole/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/pihole/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "pingvin-share", + "name": "Pingvin Share", + "description": "ScaleTail configuration for Pingvin Share running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/pingvin-share/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/pingvin-share/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/pingvin-share/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "plex", + "name": "Plex", + "description": "ScaleTail configuration for Plex running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/plex/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/plex/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/plex/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "pocket-id", + "name": "Pocket ID", + "description": "ScaleTail configuration for Pocket ID running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/pocket-id/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/pocket-id/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/pocket-id/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "portainer", + "name": "Portainer", + "description": "ScaleTail configuration for Portainer running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/portainer/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/portainer/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/portainer/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "portracker", + "name": "Portracker", + "description": "ScaleTail configuration for Portracker running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/portracker/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/portracker/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/portracker/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "posterizarr", + "name": "Posterizarr", + "description": "ScaleTail configuration for Posterizarr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/posterizarr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/posterizarr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/posterizarr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "prowlarr", + "name": "Prowlarr", + "description": "ScaleTail configuration for Prowlarr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/prowlarr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/prowlarr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/prowlarr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "qbittorrent", + "name": "qBittorrent", + "description": "ScaleTail configuration for qBittorrent running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/qbittorrent/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/qbittorrent/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/qbittorrent/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "radarr", + "name": "Radarr", + "description": "ScaleTail configuration for Radarr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/radarr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/radarr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/radarr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "recyclarr", + "name": "Recyclarr", + "description": "ScaleTail configuration for Recyclarr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/recyclarr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/recyclarr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/recyclarr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "resilio-sync", + "name": "Resilio Sync", + "description": "ScaleTail configuration for Resilio Sync running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/resilio-sync/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/resilio-sync/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/resilio-sync/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "searxng", + "name": "searXNG", + "description": "ScaleTail configuration for searXNG running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/searxng/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/searxng/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/searxng/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "slink", + "name": "Slink", + "description": "ScaleTail configuration for Slink running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/slink/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/slink/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/slink/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "sonarr", + "name": "Sonarr", + "description": "ScaleTail configuration for Sonarr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/sonarr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/sonarr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/sonarr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "speedtest-tracker", + "name": "Speedtest Tracker", + "description": "ScaleTail configuration for Speedtest Tracker running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/speedtest-tracker/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/speedtest-tracker/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/speedtest-tracker/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "stirlingpdf", + "name": "Stirling-PDF", + "description": "ScaleTail configuration for Stirling-PDF running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/stirlingpdf/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/stirlingpdf/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/stirlingpdf/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "subtrackr", + "name": "Subtrackr", + "description": "ScaleTail configuration for Subtrackr running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/subtrackr/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/subtrackr/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/subtrackr/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "swingmx", + "name": "Swing Music", + "description": "ScaleTail configuration for Swing Music running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/swingmx/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/swingmx/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/swingmx/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "tailscale-exit-node", + "name": "Tailscale Exit Node Configuration", + "description": "ScaleTail configuration for Tailscale Exit Node Configuration running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/tailscale-exit-node/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/tailscale-exit-node/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/tailscale-exit-node/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "tandoor", + "name": "Tandoor Recipes", + "description": "ScaleTail configuration for Tandoor Recipes running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/tandoor/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/tandoor/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/tandoor/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "tautulli", + "name": "Tautulli", + "description": "ScaleTail configuration for Tautulli running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/tautulli/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/tautulli/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/tautulli/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "technitium", + "name": "Technitium DNS server", + "description": "ScaleTail configuration for Technitium DNS server running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/technitium/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/technitium/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/technitium/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "traefik", + "name": "Traefik", + "description": "ScaleTail configuration for Traefik running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/traefik/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/traefik/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/traefik/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "uptime-kuma", + "name": "Uptime Kuma", + "description": "ScaleTail configuration for Uptime Kuma running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/uptime-kuma/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/uptime-kuma/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/uptime-kuma/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "vaultwarden", + "name": "Vaultwarden", + "description": "ScaleTail configuration for Vaultwarden running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/vaultwarden/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/vaultwarden/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/vaultwarden/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + }, + { + "id": "wallos", + "name": "Wallos", + "description": "ScaleTail configuration for Wallos running a Tailscale sidecar.", + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/wallos/compose.yaml", + "env_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/wallos/.env", + "documentation_url": "https://raw.githubusercontent.com/jackspiering/ScaleTail-testing/main/services/wallos/README.md", + "tags": [ + "ScaleTail", + "Tailscale" + ] + } + ] +} diff --git a/scripts/generate_registry.py b/scripts/generate_registry.py new file mode 100755 index 0000000..946e658 --- /dev/null +++ b/scripts/generate_registry.py @@ -0,0 +1,337 @@ +#!/usr/bin/env python3 +"""Generate Arcane registry.json from /services.""" +from __future__ import annotations + +import argparse +import json +import os +import re +import subprocess +from pathlib import Path +from typing import Dict, List, Optional, Tuple + +REPO_ROOT = Path(__file__).resolve().parents[1] +SERVICES_DIR = REPO_ROOT / "services" +REPO_SLUG_RE = re.compile(r"^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$") +REF_RE = re.compile(r"^[A-Za-z0-9._/-]+$") +TAG_MAX_LEN = 32 +NAME_MAX_LEN = 80 +TAG_SANITIZE_RE = re.compile(r"[^A-Za-z0-9 _.-]") +NAME_SANITIZE_RE = re.compile(r"[\x00-\x1f\x7f<>]") +STANDARD_TAGS = ("ScaleTail", "Tailscale") +TAILSCALE_SUFFIX_RES = ( + re.compile(r"\s+with\s+Tailscale\s+Sidecar\s+Configuration\s*$", re.IGNORECASE), + re.compile(r"\s+with\s+Tailscale\s+Sidecar\s*$", re.IGNORECASE), + re.compile(r"\s+with\s+Tailscale\s+Configuration\s*$", re.IGNORECASE), + re.compile(r"\s+with\s+Tailscale\s*$", re.IGNORECASE), + re.compile(r"\s+Tailscale\s+Sidecar\s+Configuration\s*$", re.IGNORECASE), + re.compile(r"\s+Tailscale\s+Sidecar\s*$", re.IGNORECASE), + re.compile(r"\s+Sidecar\s+Configuration\s*$", re.IGNORECASE), +) +FRONTMATTER_TAG_RE = re.compile(r"^(tags|tag)\s*:\s*(.*)$", re.IGNORECASE) +FRONTMATTER_LIST_ITEM_RE = re.compile(r"^-\s+(.+)$") + + +def title_from_id(value: str) -> str: + parts = re.split(r"[-_]+", value) + return " ".join(p.capitalize() for p in parts if p) + + +def strip_tailscale_suffix(value: str) -> str: + base = value.strip() + for pattern in TAILSCALE_SUFFIX_RES: + base = pattern.sub("", base) + base = base.strip(" -") + if not base: + base = value.strip() + return base + + +def normalize_service_name(value: str) -> str: + return strip_tailscale_suffix(value) + + +def first_heading(text: str) -> Optional[str]: + for line in text.splitlines(): + line = line.strip() + if line.startswith("# "): + return line[2:].strip() + return None + + +def sanitize_name(value: str) -> str: + cleaned = NAME_SANITIZE_RE.sub("", value) + cleaned = re.sub(r"\s+", " ", cleaned).strip() + if not cleaned: + cleaned = "Service" + return cleaned[:NAME_MAX_LEN] + + +def sanitize_tag(value: str) -> Optional[str]: + cleaned = TAG_SANITIZE_RE.sub("", value) + cleaned = re.sub(r"\s+", " ", cleaned).strip() + if not cleaned: + return None + return cleaned[:TAG_MAX_LEN] + + +def strip_wrapping_quotes(value: str) -> str: + if len(value) > 1 and value[0] == value[-1] and value[0] in {"'", '"'}: + return value[1:-1].strip() + return value + + +def _parse_tag_values(raw: str) -> List[str]: + value = raw.strip() + value = strip_wrapping_quotes(value) + if value.startswith("[") and value.endswith("]") and len(value) > 1: + value = value[1:-1].strip() + parts = [part.strip() for part in value.split(",")] + tags: List[str] = [] + for part in parts: + if not part: + continue + part = strip_wrapping_quotes(part) + cleaned = sanitize_tag(part) + if cleaned: + tags.append(cleaned) + return tags + + +def extract_frontmatter(lines: List[str]) -> List[str]: + idx = 0 + while idx < len(lines) and not lines[idx].strip(): + idx += 1 + if idx >= len(lines) or lines[idx].strip() != "---": + return [] + idx += 1 + frontmatter: List[str] = [] + while idx < len(lines) and lines[idx].strip() != "---": + frontmatter.append(lines[idx]) + idx += 1 + if idx >= len(lines): + return [] + return frontmatter + + +def extract_frontmatter_tags(text: str) -> List[str]: + lines = text.splitlines() + frontmatter = extract_frontmatter(lines) + idx = 0 + while idx < len(frontmatter): + line = frontmatter[idx].strip() + match = FRONTMATTER_TAG_RE.match(line) + if not match: + idx += 1 + continue + raw_value = match.group(2).strip() + if raw_value: + return _parse_tag_values(raw_value) + + idx += 1 + tags: List[str] = [] + while idx < len(frontmatter): + item = frontmatter[idx].strip() + if not item: + idx += 1 + continue + list_match = FRONTMATTER_LIST_ITEM_RE.match(item) + if not list_match: + break + cleaned = sanitize_tag(strip_wrapping_quotes(list_match.group(1).strip())) + if cleaned: + tags.append(cleaned) + idx += 1 + return tags + return [] + + +def dedupe_tags(tags: List[str]) -> List[str]: + seen: set[str] = set() + result: List[str] = [] + for tag in tags: + key = tag.lower() + if key in seen: + continue + seen.add(key) + result.append(tag) + return result + + +def ensure_standard_tags(tags: List[str]) -> List[str]: + deduped = dedupe_tags(tags) + seen = {tag.lower() for tag in deduped} + required = [tag for tag in STANDARD_TAGS if tag.lower() not in seen] + return dedupe_tags([*required, *deduped]) + + +def read_text(path: Path) -> Optional[str]: + try: + return path.read_text(encoding="utf-8") + except FileNotFoundError: + return None + except (OSError, UnicodeDecodeError) as exc: + raise SystemExit(f"Failed to read '{path}': {exc}") from exc + + +def validate_repo_slug(repo: str) -> str: + if not REPO_SLUG_RE.match(repo): + raise SystemExit(f"Invalid repo slug '{repo}'; expected owner/name") + return repo + + +def validate_ref(ref: str) -> str: + if not ref or not REF_RE.match(ref): + raise SystemExit(f"Invalid ref '{ref}'") + if ref.startswith("/") or ref.endswith("/") or ".." in ref or "//" in ref: + raise SystemExit(f"Invalid ref '{ref}'") + return ref + + +def infer_repo_slug(repo_arg: Optional[str]) -> Optional[str]: + if repo_arg: + return validate_repo_slug(repo_arg) + env_repo = os.environ.get("GITHUB_REPOSITORY") + if env_repo: + return validate_repo_slug(env_repo) + try: + url = subprocess.check_output( + ["git", "remote", "get-url", "origin"], + cwd=REPO_ROOT, + text=True, + ).strip() + except (OSError, subprocess.SubprocessError): + return None + remote = url.rstrip("/") + repo: Optional[str] = None + ssh_match = re.match(r"^git@github\.com:([^/]+/[^/]+?)(?:\.git)?$", remote) + https_match = re.match(r"^https://github\.com/([^/]+/[^/]+?)(?:\.git)?$", remote) + if ssh_match: + repo = ssh_match.group(1) + elif https_match: + repo = https_match.group(1) + if not repo: + return None + return validate_repo_slug(repo) + + +def resolve_output_path(output_arg: str) -> Path: + output_path = Path(output_arg) + if not output_path.is_absolute(): + output_path = REPO_ROOT / output_path + resolved = output_path.resolve() + try: + resolved.relative_to(REPO_ROOT) + except ValueError: + raise SystemExit( + f"Output path '{resolved}' must be inside repository {REPO_ROOT}" + ) + return resolved + + +def build_raw_base(repo: str, ref: str) -> str: + return f"https://raw.githubusercontent.com/{repo}/{ref}" + + +def pick_readme(compose_dir: Path) -> Tuple[Optional[Path], bool]: + local_readme = compose_dir / "README.md" + if local_readme.exists(): + return local_readme, False + parent_readme = compose_dir.parent / "README.md" + if parent_readme.exists(): + return parent_readme, True + return None, False + + +def build_template( + compose_path: Path, + repo: str, + ref: str, +) -> Dict[str, object]: + rel_compose = compose_path.relative_to(REPO_ROOT).as_posix() + service_rel = compose_path.parent.relative_to(SERVICES_DIR).as_posix() + template_id = service_rel.replace("/", "-") + name = sanitize_name(title_from_id(template_id)) + raw_base = build_raw_base(repo, ref) + + readme_path, parent_readme = pick_readme(compose_path.parent) + tag_values = list(STANDARD_TAGS) + if readme_path: + readme_text = read_text(readme_path) + if readme_text: + heading = first_heading(readme_text) + if heading and not (parent_readme and "/" in service_rel): + name = sanitize_name(heading) + tags = extract_frontmatter_tags(readme_text) + if tags: + tag_values = tags + tag_values = ensure_standard_tags(tag_values) + + name = normalize_service_name(name) + description_name = strip_tailscale_suffix(name) + description = ( + f"ScaleTail configuration for {description_name} running a Tailscale sidecar." + ) + + env_path = compose_path.parent / ".env" + rel_env = env_path.relative_to(REPO_ROOT).as_posix() + + documentation_url = None + if readme_path: + documentation_url = raw_base + "/" + readme_path.relative_to(REPO_ROOT).as_posix() + + template = { + "id": template_id, + "name": name, + "description": description, + "version": "1.0.0", + "author": "ScaleTail", + "compose_url": raw_base + "/" + rel_compose, + "env_url": raw_base + "/" + rel_env, + "documentation_url": documentation_url or raw_base + "/" + rel_compose, + "tags": tag_values, + } + return template + + +def main() -> int: + parser = argparse.ArgumentParser(description="Generate registry.json") + parser.add_argument("--repo", help="GitHub repo in owner/name format") + parser.add_argument("--ref", default=os.environ.get("GITHUB_REF_NAME", "main")) + parser.add_argument( + "--output", + default=str(REPO_ROOT / "registry.json"), + help="Output path for registry.json", + ) + args = parser.parse_args() + + repo = infer_repo_slug(args.repo) + if not repo: + raise SystemExit("Unable to determine repo slug; pass --repo owner/name") + ref = validate_ref(args.ref) + + templates: List[Dict[str, object]] = [] + for compose_path in sorted(SERVICES_DIR.rglob("compose.yaml")): + env_path = compose_path.parent / ".env" + if not env_path.exists(): + raise SystemExit(f"Missing .env for {compose_path}") + templates.append(build_template(compose_path, repo, ref)) + + templates.sort(key=lambda t: str(t["id"])) + + registry = { + "name": "ScaleTail Templates", + "description": "Curated Tailscale sidecar Docker configurations for self-hosted services.", + "version": "1.0.0", + "author": "ScaleTail", + "url": f"https://github.com/{repo}", + "templates": templates, + } + + output_path = resolve_output_path(args.output) + output_path.write_text(json.dumps(registry, indent=2) + "\n", encoding="utf-8") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/services/glance/README.md b/services/glance/README.md index 8877f97..435e05c 100644 --- a/services/glance/README.md +++ b/services/glance/README.md @@ -6,7 +6,7 @@ This Docker Compose configuration sets up [Glance](https://github.com/glanceapp/ [Glance](https://github.com/glanceapp/glance) is a sleek, real-time dashboard for monitoring your system metrics, Docker containers, and other self-hosted services. It offers a clean and responsive interface that consolidates key system stats and service statuses in one place. This configuration uses Tailscale to securely expose your Glance instance, keeping it protected from the public internet and accessible only within your private Tailscale network. -To install Glance properly, make sure to add the files glance.yml and home.yml to the config folder. The contents of these files can be found [here](https://github.com/glanceapp/docker-compose-template/tree/main/root/config). Also add the file user.css to the assets folder which can be found [here](https://github.com/glanceapp/docker-compose-template/tree/main/root/assets). +To install Glance properly, make sure to add the files glance.yml and home.yml to the config folder. The contents of these files can be found [at the Glance repository](https://github.com/glanceapp/docker-compose-template/tree/main/root/config). Also add the file user.css to the assets folder which can be found [here in their repository](https://github.com/glanceapp/docker-compose-template/tree/main/root/assets). ## Configuration Overview