Je eigen Progress Watch draaien
De server is open source onder de AGPL, en de gehoste dienst draait dezelfde image die jij zou draaien. Zelf hosten kost één container en een Redis, en de database blijft voor altijd klein omdat voortgang er nooit in wordt geschreven.
Eén bestand
docker-compose.yml is de hele installatie. Het draait de gepubliceerde image, dus er valt niets te klonen en niets te bouwen — kopieer het van de Docker-pagina, die het huidige bestand afdrukt, vervang het voorbeeldgeheim door openssl rand -hex 64 en start het:
Dat is de hele opzet: de app op http://localhost:7979, een Redis en een SQLite-bestand op een benoemd volume. Open hem, maak een ruimte aan, en het Verbinden-menu van die ruimte geeft je commando's met de UUID er al in.
Instellen
Het bestand is van jou vanaf het moment dat je het opslaat, en het is de enige plek waar iets wordt ingesteld — elke instelling is een regel in een environment:-blok, dus er een toevoegen is een regel toevoegen:
environment:
- SECRET_KEY_BASE=8f3c…
- DATABASE_URL=postgresql://progresswatch:secret@db.internal/progresswatch
- VAPID_PUBLIC_KEY=BJ1w…
- VAPID_PRIVATE_KEY=xK2p…
Omgevingsvariabelen is de volledige lijst, en alles daarop werkt hier. Om op een andere poort dan 7979 te publiceren verander je de linkerkant van 7979:3000 — de app binnen de container zit altijd op 3000.
curl http://localhost:7979/up
{"status":"ok","database":true,"redis":true,"worker":true}
Wat er draait
Twee processen en een bestand. De app beantwoordt verzoeken en draait de worker in zichzelf — Sidekiq zit ingebed in Puma, dus aan een melding kan geen eigen service ontbreken. Redis houdt de huidige voortgang van elke taak en de jobwachtrij bij; SQLite houdt spaces en de vorm van elke taak bij.
Bijwerken
Noem de service. Een kale docker compose pull haalt ook Redis op, en als er een nieuwere redis:8-alpine is gepubliceerd, vervangt up -d die container ook — waarmee de voortgang van alles wat nu draait weg is.
docker compose pull progresswatch docker compose up -d progresswatch
Alleen de app-container vervangen laat elke lopende taak precies waar die was, want de voortgang zit in Redis en Redis is niet aangeraakt. Titels en structuur staan op het volume en overleven sowieso. Niets overleeft docker compose down of een herstart van de host: Redis bewaart bewust niets op schijf.
Waarom 7979
Niet 3000. Dit is een dienst die je wekenlang laat draaien terwijl je werkt, en 3000 is waar je eigen ontwikkelservers landen — Rails, Vite, Next, Grafana en de helft van de docker run-regels in andere handleidingen. Een achtergronddienst hoort niet de meest omstreden poort van de machine te bezetten, zeker niet een waarvan je de URL in een CI-secret plakt en daarna vergeet.
Binnen de container is het nog steeds 3000; alleen de gepubliceerde poort is verhuisd, en dat is de regel 7979:3000.
Het volume kwijtraken is te herstellen
Ruimtes en taakstructuur staan erop, en verder niets. Als het weg is maak je een nieuwe ruimte aan en vullen je rapporterende processen bij hun volgende verzoek alles weer aan. Maak er een back-up van als je liever geen nieuwe ruimte-UUID uitdeelt aan alles wat erin rapporteert — maar er staat niets op dat niet opnieuw op te bouwen is door de klussen nog eens te draaien.
SQLite of PostgreSQL
Allebei, vanuit dezelfde image en dezelfde migraties, gekozen met DATABASE_URL. SQLite is de standaard en het juiste antwoord voor één machine: twee tabellen, opzoeken op primaire sleutel, bijna nooit schrijven. Wijs naar postgresql://… als je meerdere app-containers draait, want die kunnen geen bestand delen.
Achter een proxy
Zet FORCE_SSL=true zodra iets vóór de app de TLS afhandelt. Het staat standaard uit zodat een installatie die je via gewoon HTTP bereikt je niet doorstuurt naar een certificaat dat je niet hebt.
Meldingen
Zet een VAPID-sleutelpaar en er verschijnt een «Waarschuw mij»-knop op elke ruimte; laat de sleutels leeg en de functie bestaat niet. Er valt niets te registreren bij Apple of Google. Zie meldingen voor het hele verhaal, inclusief wat er op een telefoon moet gebeuren.
Lege ruimtes opruimen
De site openen maakt een ruimte voor je aan, dus er ontstaan er heel wat die nooit gebruikt worden — ook door alles wat de pagina crawlt. Een ruimte die ooit een taak heeft bevat, blijft voorgoed bewaard, hoe lang niemand er ook naar kijkt. Alleen die nooit één taak bevatten worden opgeruimd, en pas als ze ouder zijn dan 30 dagen.
Niets voert dat voor je uit. Plan het zoals je al dingen plant:
# crontab, dagelijks om 04:17 17 4 * * * cd /path/to/progresswatch && docker compose exec -T progresswatch bin/rails sweep_empty_spaces
Omdat niets op een timer loopt, zijn 30 dagen een ondergrens en geen schema: voer het dagelijks uit en lege ruimtes verdwijnen op de dag dat ze ervoor in aanmerking komen, één keer per jaar en ze blijven tot dan. Het overslaan is veilig voor je gegevens — de opruiming pakt alleen rijen die nooit gebruikt zijn — het betekent alleen dat de tabel groeit met ruimtes die niemand ooit heeft geopend.
Jouw instantie is niet indexeerbaar
Elke pagina van een zelf gehoste installatie is noindex, robots.txt verbiedt alles, en /sitemap.xml antwoordt 404. Vanaf iemands eigen machine is er geen publiek te bereiken en staat er niets dat in een zoekopdracht gevonden wil worden, en daar hoeft niets voor ingesteld te worden — zo krijg je het.