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 één volume, 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, en start het:

Dat is de hele opzet: de app op http://localhost:7979, met Redis en SQLite in dezelfde container en alles wat ze bewaren op het benoemde 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 onder de service, dat het bestand weglaat tot je er een nodig hebt:

environment:
- 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, alles in één container. De app beantwoordt verzoeken en draait de worker in zichzelf, want Sidekiq zit ingebed in Puma, en hij start Redis naast zich en stopt het bij het afsluiten. Redis houdt de huidige voortgang van elke taak en de jobwachtrij bij en schrijft van beide snapshots naar het volume; SQLite houdt spaces en de vorm van elke taak bij. Zet REDIS_URL en de app gebruikt die Redis in plaats daarvan en start er zelf geen.

Bijwerken

Haal de nieuwe image op en start opnieuw:

docker compose pull
docker compose up -d

Elke lopende taak blijft waar die was. Bij het stoppen van de container schrijft Redis een snapshot naar het volume, en de nieuwe container laadt die in bij het starten. Alleen een crash of stroomstoring slaat die stap over, en dan komt de laatste periodieke snapshot terug, minuten oud bij frequente rapportages en tot een uur oud als ze schaars zijn: een taak toont «Wachten op gegevens…» of een ouder getal tot de volgende rapportage.

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, taakstructuur, een snapshot van Redis en de geheime sleutel staan erop. Als het weg is maak je een nieuwe ruimte aan en vullen je rapporterende processen bij hun volgende verzoek alles weer aan, en een nieuwe geheime sleutel kost niets, want er zijn geen accounts om iemand uit te loggen. 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.