soapbox/README.md
Ole-Morten Duesund ea07f346a9 Cache-busting for temafiler
Malene får asset('theme/style.css') som gir en relativ URL med
innholdshash (?v=…), beregnet ved bygging. Temafiler serveres nå med
max-age=1 år + immutable; URL-en endres når innholdet gjør det, så
besøkende får ny stil umiddelbart etter oppgradering.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JcEy43fNYpwg6K6oTKakWR
2026-08-26 15:49:43 +02:00

134 lines
6.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Soapbox
En liten blogg: statiske sider, mobilvennlig Markdown-editor med bildeopplasting og live
forhåndsvisning, innhold versjonert i git. Én hovedbruker («soapbox») pluss valgfrie gjester.
## Hvordan det henger sammen
```
data/
├── content/ git-repo alt innhold, kan klones/flyttes fritt
│ ├── site.toml tittel, beskrivelse, språk
│ ├── posts/<slug>/index.md + bilder → /<slug>/
│ └── guests/<bruker>/<slug>/index.md → /<bruker>/<slug>/
├── public/ generert statisk side (bygges automatisk ved lagring)
├── soapbox.sqlite brukere og passord-hasher det eneste som ikke ligger i git
└── secret_key cookie-signering (genereres automatisk)
```
* **Slug** lages av tittelen (`Grønt er skjønt``grønt-er-skjønt`). Den følger tittelen så
lenge innlegget er utkast, og fryses ved publisering så lenker aldri brekker.
* **Alle interne lenker er relative.** Malene regner ut `../` ut fra sidens dybde, og absolutte
lenker du skriver i Markdown (`/annet-innlegg/`) skrives om. Derfor fungerer samme `public/`
både på `blog.domene.no/` og `annet-domene.com/blog/` uten rebuild.
* **Bilder** ligger i samme mappe som innlegget og refereres som `![](bilde.jpg)`. Ved opplasting
skaleres de ned (maks 2000 px) og EXIF fjernes (ingen GPS-posisjon publiseres).
* **Hver lagring er en git-commit** med brukeren som forfatter. Hvert innlegg har en
«Historikk»-seksjon i editoren med diff per endring; hele loggen ligger under Innstillinger
(eller `git -C data/content log`).
* **Gjester** ser og redigerer bare egne innlegg. Hovedbrukeren ser alt og administrerer gjester.
* **Tagger** settes kommaseparert i editoren. `/tag/<tagg>/` lister alle innlegg med taggen (også
gjesters), `/tag/` alle tagger. Tagger får slug på samme måte som titler.
* **Brukersider**: `/brukere/` lister hovedbruker øverst og gjester alfabetisk; `/brukere/<navn>/`
viser visningsnavn, beskrivelse (Markdown, settes under Profil), e-post og innlegg.
* **Signatur**: innlegg avsluttes med «– Visningsnavn», evt. med e-post som mailto-lenke. Begge
settes under Profil i admin og slås opp ved bygging, så en endring gjelder alle innlegg.
## Kjøre lokalt
```sh
uv sync
SOAPBOX_DATA_DIR=./data uv run soapbox create-user olemd --role owner
SOAPBOX_DATA_DIR=./data uv run soapbox serve --debug
# → http://localhost:8080/admin/
```
Tester: `uv run pytest`. Lint: `uv run ruff check . && uv run ruff format .`
## Konfigurasjon (miljøvariabler)
Se `.env.example` for en kommentert mal. Alt har standardverdier; kun `SOAPBOX_SITE_URL` og
hovedbrukeren bør settes.
| Variabel | Standard | Beskrivelse |
|---|---|---|
| `SOAPBOX_DATA_DIR` | `./data` (`/data` i container) | Alt persistent |
| `SOAPBOX_BASE_PATH` | stien i `SOAPBOX_SITE_URL` | Overstyring, kun hvis proxyen stripper prefikset |
| `SOAPBOX_SITE_URL` | `http://localhost:8080` | Absolutt URL til rot inkl. sub-path; brukes i Open Graph, feed, sitemap og til å utlede base-path |
| `SOAPBOX_THEME` | `green` | Mappe under `soapbox/themes/` |
| `SOAPBOX_MAX_IMAGE_PX` | `2000` | Lengste side på opplastede bilder |
| `SOAPBOX_SECRET_KEY` | autogenerert | Overstyr hvis du vil ha nøkkelen utenfor volumet |
| `SOAPBOX_OWNER_USER` / `_PASSWORD` | | Oppretter hovedbruker ved første start |
## Container og Caddy
```sh
cp .env.example .env # sett SOAPBOX_SITE_URL og hovedbruker
./build.sh # bygger localhost/soapbox:latest med build-metadata
./run.sh # podman run --replace med .env, lytter på SOAPBOX_BIND:SOAPBOX_PORT
# eller: podman compose up -d
```
Ny versjon: `git pull && ./build.sh && ./run.sh`. Data ligger i podman-volumet `soapbox-data`
(`podman volume inspect soapbox-data` viser stien).
`run.sh` tar automatisk backup av volumet før hver oppstart til `SOAPBOX_BACKUP_DIR`
(standard `./backups/soapbox-data-<tidsstempel>.tar.gz`) og beholder de `SOAPBOX_BACKUP_KEEP`
nyeste (standard 5). Gjenopprett med `podman volume import soapbox-data <fil>`.
Caddy er ren reverse proxy, se `Caddyfile.example`. Appen lytter som standard på alle adresser
(IPv4 og IPv6), så Caddy kan stå på en annen maskin og nå den over Tailscale/MagicDNS. Sett
`SOAPBOX_BIND=127.0.0.1` for å begrense når Caddy kjører lokalt. Ved sub-path skal Caddy **ikke** strippe
prefikset appen monteres selv under stien fra `SOAPBOX_SITE_URL`.
## Flytte bloggen (nytt domene og/eller sub-path)
Ingen innhold trenger endring alle lenker er relative. Velg én av to måter:
**A. Kopier hele `data/`-volumet.** Tar med innhold, brukere og cookie-nøkkel. Ingenting må
opprettes på nytt.
```sh
podman volume export soapbox-data | ssh ny-server 'podman volume import soapbox-data -'
```
**B. Klon bare innholdsrepoet.** Brukere ligger i sqlite, ikke i git, så de må opprettes på nytt
(hovedbruker via `SOAPBOX_OWNER_USER/_PASSWORD` eller `soapbox create-user`, gjester i admin med
**samme brukernavn** som før brukernavnet er URL-prefikset `/gjest/`).
```sh
git clone gammel-server:/sti/til/data/content ./data/content
```
Deretter, uansett metode: sett `SOAPBOX_SITE_URL` til den nye adressen (sub-path utledes
derfra) og start. Siden bygges på nytt ved oppstart.
## Tema
Aktivt tema velges under Innstillinger i admin og lagres i `site.toml` (følger med i git).
`SOAPBOX_THEME` er bare standardverdien før noe er valgt.
**Lag et eget tema uten å bygge containeren på nytt:** legg det i innholdsrepoet, så følger det
med i git, backup og ved flytting.
```sh
mkdir -p data/content/themes/skog/static
cp soapbox/themes/green/static/style.css data/content/themes/skog/static/ # rediger fargene
```
Et tema kan være **delvis**: bare filene som finnes overstyrer det innebygde `green`-temaet.
Vil du endre malene, legg `templates/base.html`, `index.html` eller `post.html` i temamappen.
Malene får `site`, `posts`/`post`, `html`, `source_url` og `rel(sti)` (relativ lenke fra
gjeldende side), samt filtrene `date`, `excerpt(n)` og `tagslug`. Bruk `asset('theme/fil.css')` for temafiler:
den gir en relativ URL med innholdshash (`?v=…`) for cache-busting. `static/` havner under `/theme/`.
## Lisens
AGPL-3.0-or-later, se `LICENSE`. Bloggen lenker til kildekoden i footeren, slik lisensen
krever for nettverkstjenester. Endrer du koden og hoster den, må lenken peke til din versjon
(`SOURCE_URL` i `soapbox/build.py`).
## Veien videre (ikke i denne omgangen)
* Poste lenker til fediverset/Bluesky og vise svar som kommentarer.
* Push av innholdsrepoet til en ekstern git-remote.