# Gokapi — public file-share (Firefox Send-style), separate from Nextcloud. # # Nextcloud stays the private "twierdza" (mesh/kapala.org only). Gokapi is # the OPPOSITE end of the spectrum on purpose: a small, single-container, # genuinely public link-share for sending someone outside the mesh a file. # Runs on VPS (Hetzner, public host) — home nodes stay untouched. services: gokapi: # Pinned to the current stable release (v2.2.4, verified against # github.com/Forceu/Gokapi releases + Docker Hub f0rc3/gokapi tags on # 2026-07-09) — never :latest, so upgrades are a deliberate git diff, # same convention as nextcloud. image: f0rc3/gokapi:v2.2.4 container_name: gokapi restart: unless-stopped env_file: - .env volumes: # /opt/homelab/data convention. `data` holds uploaded files (churns # constantly — links expire and get deleted); `config` holds # config.json + the E2E encryption master key. See README backup note: # config is the part that actually needs backing up. - /opt/homelab/data/gokapi/data:/app/data - /opt/homelab/data/gokapi/config:/app/config ports: # PUBLIC reachability is via npm@VPS + share.okit.pl, NOT this bind. # Bound ONLY to the VPS Tailscale interface (TAILSCALE_BIND_IP), never # 0.0.0.0 — same defense-in-depth convention as fleet-prometheus: the # raw port does not exist on the public Hetzner IP (135.181.153.108) # at all. npm, running as its own container on the same host, reaches # gokapi via Docker hairpin NAT through this real interface IP # (loopback would NOT work for that trick — see fleet-prometheus / # nextcloud for the same pattern). Requires .env (from env.example) # next to this file at deploy. - "${TAILSCALE_BIND_IP}:53842:53842" # Image ships curl (alpine-based), so an in-container check works here — # unlike vikunja's image, which has neither curl nor wget. healthcheck: test: ["CMD", "curl", "-fs", "--max-time", "5", "http://127.0.0.1:53842/"] interval: 30s timeout: 10s retries: 5 start_period: 15s