# Guida del redattore — Blog di my-vps Guida per chi (umano o agente AI) deve scrivere e pubblicare articoli sul blog di my-vps. Ultimo aggiornamento: 2026-08-10 --- ## 1. Panoramica - **Blog**: - sul **web** (con password): `https://blog.194.164.167.80.nip.io` — accesso tramite **Authelia** (SSO, login unico). - in **VPN** (senza password, rete privata): `http://100.64.0.2:8083`. - **Sito statico** generato con **Astro**, servito da **nginx** in un container, esposto da **Traefik**. - **Due repo Forgejo separati**: - **codice** (PUBBLICO): `forgejo-admin/astro-blog` (`https://git.194.164.167.80.nip.io/forgejo-admin/astro-blog`) — tema, layout, configurazione. Non contiene articoli. - **articoli** (PRIVATO): `forgejo-admin/astro-blog-content` (`https://git.194.164.167.80.nip.io/forgejo-admin/astro-blog-content`) — i post in Markdown, in `blog/`. - **Copia di lavoro sul server**: `/opt/astro-blog` (codice) e `/opt/astro-blog-content` (articoli). - **Pipeline**: a ogni push su `main` di **uno dei due repo**, **Forgejo Actions** (runner self-hosted) esegue `/root/.hermes/scripts/deploy-blog.sh` che ricostruisce l'immagine e ricrea il container in automatico. > La regola d'oro: **ogni post = un file Markdown nel repo PRIVATO > `astro-blog-content` + `git push` su `main`**. Il deploy è automatico. ## 2. Struttura di un post ### 2.1 File e URL - Il post va in `blog/.md` nella copia di lavoro del repo **privato** (o su Forgejo: repo `astro-blog-content` → cartella `blog/`). - `` determina l'URL finale: `/posts//`. - Lo slug: minuscolo, trattini al posto degli spazi, niente spazi/caratteri speciali. Es. `come-si-installa-podman.md` → `/posts/come-si-installa-podman/`. - Non usare slug duplicati (la build fallisce). ### 2.2 Frontmatter (schema obbligatorio) ```markdown --- title: "Titolo del post" description: "Una o due frasi di riassunto (opzionale ma consigliato)." pubDate: 2026-08-10T10:30:00+02:00 author: "forgejo-admin" tags: ["infrastruttura", "podman"] --- ``` | Campo | Obbligatorio | Note | |---|---|---| | `title` | si | testo tra virgolette | | `description` | no | mostrata in lista e nel feed RSS; consigliata | | `pubDate` | si | data ISO **con offset**, ora esatta al secondo in `Europe/Rome` | | `author` | no | default `admin`; usare `forgejo-admin` | | `tags` | no | array di stringhe, es. `["meta", "infrastruttura"]` | **Attenzione agli orari**: il sito usa `Europe/Rome`. In estate l'offset è `+02:00`, in inverno `+01:00`. Usare sempre l'offset esatto del momento in cui si vuole che il post risulti pubblicato. Esempio valido: `pubDate: 2026-08-10T10:30:00+02:00`. ### 2.3 Corpo del post - Markdown standard: titoli `##`, elenchi, citazioni, `code fence`, link, grassetto. - Non serve altro: il rendering è automatico. - Il post viene ordinato per `pubDate` **decrescente** (il più recente in cima), in home, archivio e RSS. ### 2.4 Modello (post esistente) In `blog/` del repo privato ci sono i post già pubblicati: usarli come riferimento per struttura e frontmatter. ## 3. Workflow di pubblicazione ### 3.1 Procedura standard (deploy automatico) ```sh # SUL SERVER (copia di lavoro del repo PRIVATO) ssh root@194.164.167.80 cd /opt/astro-blog-content git pull origin main # crea o modifica il post nano blog/.md # versiona e pubblica: il push fa partire il deploy automatico git add blog/.md git commit -m "Nuovo post: " git push origin main ``` Fatto: il runner ricostruisce l'immagine e ricrea il container da solo (qualche decina di secondi). Verificare l'esito con il par. 4. ### 3.2 Procedura per l'agente AI (Hermes/opencode) Stessi passi, via strumenti: 1. `git pull` in `/opt/astro-blog-content`. 2. Creare il file Markdown `blog/.md` con frontmatter corretto (par. 2). 3. `git add` + `git commit` + `git push origin main` (deploy automatico). 4. **Verificare sempre** il risultato (par. 4) e riportarlo all'utente. ### 3.3 Fallback manuale (solo in emergenza) Se l'automazione non funziona, deploy a mano dal server: ```sh cd /opt/astro-blog git pull origin main git -C /opt/astro-blog-content pull origin main rm -f src/content/blog/*.md cp /opt/astro-blog-content/blog/*.md src/content/blog/ podman build -t astro-blog:latest . systemctl restart container-astro-blog.service sleep 5 systemctl is-active container-astro-blog.service ``` Il container è gestito da systemd (`container-astro-blog.service`): il restart lo ricrea con l'immagine appena costruita. ## 4. Verifica della pubblicazione ```sh # nuovo post raggiungibile? (via VPN, senza password) curl -s -o /dev/null -w "%{http_code}\n" http://100.64.0.2:8083/posts// # home e archivio (via VPN) curl -s -o /dev/null -w "%{http_code}\n" http://100.64.0.2:8083/ curl -s -o /dev/null -w "%{http_code}\n" http://100.64.0.2:8083/archivio/ # feed RSS (contiene il nuovo post?) curl -s http://100.64.0.2:8083/rss.xml | grep -c "" # sul web: deve chiedere il login Authelia (302/401) curl -s -o /dev/null -w "%{http_code}\n" https://blog.194.164.167.80.nip.io/ # esito del run CI journalctl -u forgejo-runner -n 30 # oppure UI: https://git.194.164.167.80.nip.io/forgejo-admin/astro-blog-content/actions ``` ## 5. Regole editoriali - **Lingua**: italiano. Tono semplice e diretto, stile "appunti". - **Date**: sempre esatte al secondo, fuso `Europe/Rome` con offset (vedi 2.2). - **Description**: 1-2 frasi, utile per lista e RSS. - **Tags**: usare un vocabolario coerente e riusare i tag esistenti (`meta`, `infrastruttura`, ...). Evitare tag inventati per ogni post. - **Immagini**: il layout attuale non prevede gallerie; gli asset statici possono stare in `public/` del repo del codice e riferirsi con percorso assoluto (`/nome.png`). - **Niente segreti**: non pubblicare password, chiavi, token o dati sensibili. Il blog sul web è protetto da login, ma la prudenza resta la regola. - **Attribuzione**: `author` di default `forgejo-admin` (o il nome del redattore). - **Coerenza**: se si modifica un post già pubblicato, aggiornare `pubDate` solo se il contenuto è stato riscritto in modo significativo. ## 6. Problemi frequenti | Sintomo | Causa probabile | Rimedio | |---|---|---| | Il push non fa partire il deploy | runner spento o errore CI | `journalctl -u forgejo-runner`; UI `/actions` | | Post non visibile dopo il push | deploy fallito in CI | console del run; correggere e ri-pushare | | `404` su `/posts//` | slug/nome file diverso da quanto atteso | verificare il nome del file | | Build fallita con errore `zod`/frontmatter | campo mancante o `pubDate` non valido | correggere il frontmatter (2.2) | | Slug duplicato | due file generano lo stesso slug | rinominare uno dei file | | Blog `502` su tutto | socket Podman di Traefik | vedi TRAEFIK-FORGEJO-BLOG.md (Nota operativa socket) | | Home ok ma post vecchi | deploy non eseguito (CI fallita) | fallback manuale (3.3) | ## 7. Riferimenti - Documentazione operativa del server: `/root/README.md` e `/root/*.md`. - Deploy/blog (architettura): `/root/TRAEFIK-FORGEJO-BLOG.md`. - Automazione CI: `/root/FORGEJO-ACTIONS.md`. - Repo codice (pubblico): `https://git.194.164.167.80.nip.io/forgejo-admin/astro-blog`. - Repo articoli (privato): `https://git.194.164.167.80.nip.io/forgejo-admin/astro-blog-content`. - Astro content collections: https://docs.astro.build (schema e Markdown).