2026-08-26 12:12:33 +02:00
|
|
|
|
# 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)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-08-26 15:04:13 +02:00
|
|
|
|
* **Slug** lages av tittelen (`Grønt er skjønt` → `grønt-er-skjønt`). Den følger tittelen så
|
2026-08-26 12:12:33 +02:00
|
|
|
|
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 ``. Ved opplasting
|
|
|
|
|
|
skaleres de ned (maks 2000 px) og EXIF fjernes (ingen GPS-posisjon publiseres).
|
2026-08-26 13:21:32 +02:00
|
|
|
|
* **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`).
|
2026-08-26 12:12:33 +02:00
|
|
|
|
* **Gjester** ser og redigerer bare egne innlegg. Hovedbrukeren ser alt og administrerer gjester.
|
2026-08-26 15:42:36 +02:00
|
|
|
|
* **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.
|
2026-08-26 15:48:15 +02:00
|
|
|
|
* **Brukersider**: `/brukere/` lister hovedbruker øverst og gjester alfabetisk; `/brukere/<navn>/`
|
|
|
|
|
|
viser visningsnavn, beskrivelse (Markdown, settes under Profil), e-post og innlegg.
|
2026-08-26 15:37:27 +02:00
|
|
|
|
* **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.
|
2026-08-26 12:12:33 +02:00
|
|
|
|
|
|
|
|
|
|
## 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)
|
|
|
|
|
|
|
2026-08-26 12:36:12 +02:00
|
|
|
|
Se `.env.example` for en kommentert mal. Alt har standardverdier; kun `SOAPBOX_SITE_URL` og
|
|
|
|
|
|
hovedbrukeren bør settes.
|
|
|
|
|
|
|
2026-08-26 12:12:33 +02:00
|
|
|
|
| Variabel | Standard | Beskrivelse |
|
|
|
|
|
|
|---|---|---|
|
|
|
|
|
|
| `SOAPBOX_DATA_DIR` | `./data` (`/data` i container) | Alt persistent |
|
2026-08-26 15:04:13 +02:00
|
|
|
|
| `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 |
|
2026-08-26 12:12:33 +02:00
|
|
|
|
| `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
|
2026-08-26 12:36:12 +02:00
|
|
|
|
cp .env.example .env # sett SOAPBOX_SITE_URL og hovedbruker
|
|
|
|
|
|
./build.sh # bygger localhost/soapbox:latest med build-metadata
|
2026-08-26 15:09:39 +02:00
|
|
|
|
./run.sh # podman run --replace med .env, lytter på SOAPBOX_BIND:SOAPBOX_PORT
|
2026-08-26 12:36:12 +02:00
|
|
|
|
# eller: podman compose up -d
|
2026-08-26 12:12:33 +02:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-08-26 12:36:12 +02:00
|
|
|
|
Ny versjon: `git pull && ./build.sh && ./run.sh`. Data ligger i podman-volumet `soapbox-data`
|
|
|
|
|
|
(`podman volume inspect soapbox-data` viser stien).
|
|
|
|
|
|
|
2026-08-26 14:41:16 +02:00
|
|
|
|
`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>`.
|
|
|
|
|
|
|
2026-08-26 15:13:32 +02:00
|
|
|
|
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
|
2026-08-26 15:04:13 +02:00
|
|
|
|
prefikset – appen monteres selv under stien fra `SOAPBOX_SITE_URL`.
|
2026-08-26 12:12:33 +02:00
|
|
|
|
|
|
|
|
|
|
## Flytte bloggen (nytt domene og/eller sub-path)
|
|
|
|
|
|
|
2026-08-26 13:21:32 +02:00
|
|
|
|
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
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-08-26 15:04:13 +02:00
|
|
|
|
Deretter, uansett metode: sett `SOAPBOX_SITE_URL` til den nye adressen (sub-path utledes
|
|
|
|
|
|
derfra) og start. Siden bygges på nytt ved oppstart.
|
2026-08-26 12:12:33 +02:00
|
|
|
|
|
|
|
|
|
|
## Tema
|
|
|
|
|
|
|
2026-08-26 13:45:04 +02:00
|
|
|
|
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
|
2026-08-26 15:49:43 +02:00
|
|
|
|
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/`.
|
2026-08-26 12:12:33 +02:00
|
|
|
|
|
2026-08-26 13:13:25 +02:00
|
|
|
|
## 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`).
|
|
|
|
|
|
|
2026-08-26 12:12:33 +02:00
|
|
|
|
## Veien videre (ikke i denne omgangen)
|
|
|
|
|
|
|
|
|
|
|
|
* Poste lenker til fediverset/Bluesky og vise svar som kommentarer.
|
|
|
|
|
|
* Push av innholdsrepoet til en ekstern git-remote.
|