+++
title = "Hello World!"
summary = "Come costruire il proprio blog usando Hugo e Cloudflare Pages"
date = "2024-04-22"

tags = ["Hugo", "Cloudflare", "Pages", "Wrangler"]
categories = ["Tutorial"]
+++

L' *Hello World* è il primo programma che un developer scrive per verificare
che il suo setup funzioni correttamente.

Come "Hello World" par il mio blog ho voluto mostrare come ho creato questo
sito, partendo dallo *Static Site Generator* di mia scelta -
[Hugo](https://gohugo.io/) - e concludendo mostrando come ho hostato il tutto
su Cloudflare utilizzando [Pages](https://pages.cloudflare.com/).

### Disclaimer

{{< alert icon="triangle-exclamation" cardColor="#e6d237" iconColor="#1d3557"
textColor="#1d3557" >}}
Cloudflare? [**Absolutely proprietary**](/img/absolutely_proprietary.jpg)!
{{< /alert >}}

Potrebbe sembrare abbastanza paradossale che un appassionato di open source,
privacy e sovranità dei propri dati personali si metta ad hostare il proprio
sito su Cloudflare[^1] e farci tutorial a riguardo.

[^1]: [old.reddit.com - ELI5 why CloudFlare is depicted as evil, and what's
    wrong with using their DNS
    (1.1.1.1)](https://old.reddit.com/r/privacy/comments/d52kop/)

Vorrei precisare che questo è un setup provvisorio, adatto anche a chi non ha
la possibilita di *self-hostare* un sito, sia per motivi di sicurezza che per
motivi di CGNAT[^2] (*dannato IPv4*).

[^2]: [en.wikipedia.org - Carrier-grade
    NAT](https://en.wikipedia.org/wiki/Carrier-grade_NAT)

Per chi fosse interessato, è in programma un articolo su come fare il
forwarding delle porte anche attraverso il CGNAT, però per ora continuiamo ad
usare quel maledetto di Cloudflare.

## Creare un sito con Hugo

Per gestire tutti i contenuti su questo sito uso [Hugo](https://gohugo.io/), un
generatore di siti statici che mi permette di scrivere pagine ed articoli in un
semplice linguaggio di markup, come Markdown. Hugo poi prenderà i contenuti ed
un tema e li combinerà, producendo HTML, CSS e JavaScript statici.

Per cominciare, bisogna [installare
Hugo](https://github.com/gohugoio/hugo/releases/latest) e creare un nuovo
progetto:

```shell
hugo new site <site-name>
cd <site-name>
git init
```

Se vuoi visualizzare il tuo sito in un server di sviluppo:

```shell
hugo server
```

Adesso all'URL <http://localhost:1313/> dovresti vedere una pagina *404: Page
Not Found*. Per sistemare questo problema dobbiamo installare un tema.

### Scegliere un tema

Per avere un'idea di quali temi possiamo installare possiamo andare nella
[sezione "Themes"](https://themes.gohugo.io/) del sito di Hugo. Ovviamente
nulla ci vieta di crearci il nostro tema da zero, in rete ci sono diversi
tutorial a riguardo.

Per una questione di semplicità, per questo tutorial andrò a scegliere il [tema
PaperMod](https://github.com/adityatelange/hugo-PaperMod/).

Per aggiungere un tema bisogna prima scaricarlo come sottomodulo Git nella
directory `themes/`:

```shell
git submodule add --depth=1 https://github.com/adityatelange/hugo-PaperMod.git themes/papermod
```

Poi bisogna specificare il tema che Hugo deve usare nel file di configurazione:

```shell
echo "theme = 'papermod'" >> hugo.toml
```

Se riavviamo il *dev server* dovremmo vedere una pagina simile a questa:

![Homepage del blog con il tema PaperMod](images/01-papermod.jpg "La homepage
del nostro blog col tema PaperMod")

Il nostro sito comincia finalmente ad avere un po' di colore, ma è ancora
troppo spoglio e generico per i miei gusti.

### Personalizzare il sito

Per rendere il sito meno generico bisogna modificare i file di configurazione.
Ad esempio all'interno del file `hugo.toml` possiamo modificare le prime
variabili:

```toml
baseURL = 'https://example.org/'
languageCode = 'en-us'
title = 'My New Hugo Site'
theme = 'papermod'
```

Per configurare a fondo il sito è necessario consultare la documentazione del
tema scelto, ad esempio [questa è la documentazione per il tema
PaperMod](https://adityatelange.github.io/hugo-PaperMod/).

Purtroppo non c'è una documentazione comune per tutti i temi, quindi bisogna
prendersi un po' di tempo e leggersi la documentazione del proprio tema.

### Aggiungere degli articoli

Ora il nostro blog ha un bell'aspetto, ma al momento è un po' vuoto. Possiamo
risolvere creando il nostro primo articolo:

```shell
hugo new content posts/<article-name>.md
```

Con questo comando Hugo copierà il file `archetypes/default.md` nel percorso
`contents/posts/`, lo rinominerà e scambierà le variabili contenute
al suo interno:

```toml
+++
title = 'Test Article'
date = 2024-04-22T00:00:00+02:00
draft = true
+++
```

Vorrei far notare la variabile `draft = true` nel preambolo del nostro
articolo: quando questa è impostata a `true` Hugo nasconderà l'articolo in fase
di compilazione, in modo che si possa compilare tutto il sito senza che ci si
debba preoccupare di visualizzare degli articoli incompleti.

Possiamo comunque mostrare le bozze quando eseguiamo il *dev server* passando
l'argomento `--buildDrafts` al comando `hugo server`.

Ora possiamo iniziare a scrivere il nostro post utilizzando il [linguaggio
Markdown](https://commonmark.org/):

![Un articolo di prova](images/02-article.jpg "Ecco un articolo di prova")

Una volta finito di scrivere i nostri articoli possiamo compilare il nostro
blog utilizzando il comando:

```shell
hugo
```

I risultati della compilazione si possono trovare nella directory `public/`.

## Pubblicare il sito con Cloudflare Pages

Ora che abbiamo un sito compilato staticamente possiamo pubblicarlo su una
piattaforma come [Cloudflare Pages](https://pages.cloudflare.com/).

Esistono tante piattaforme che permettono di pubblicare pagine statiche, come
[GitHub Pages](https://pages.github.com/) o [Vercel](https://vercel.com/). Ho
scelto Cloudflare Pages solo per comodità, dato che in passato avevo registrato
presso Cloudflare il dominio "nicolabelluti.me" per utilizzare [Cloudflare
Tunnel](https://www.cloudflare.com/products/tunnel/), sul quale arriverà presto
un articolo[^3].

[^3]: Si, so che Cloudflare Tunnel non è altro che un
    [MITM](https://en.wikipedia.org/wiki/Man-in-the-middle_attack), arriverà
    anche un articolo sul come sostituire Cloudflare Tunnel con una propria
    VPN Wireguard.

Per creare un sito con Cloudflare Pages, bisogna recarsi nella [Dashboard di
Cloudflare](https://dash.cloudflare.com/) e navigare su `Workers & Pages`
cliccare su `Pages`.

Creare un nuovo progetto, dargli un nome e salvarlo senza caricare alcun file.

![Qua bisogna inserire il nome del progetto](images/03-pages-creation.jpg "Qua
bisogna inserire il nome del progetto")

Ora se torniamo indietro alla voce `Workers & Pages` della barra laterare,
dovreste vedere il nuovo progetto.

In caso voleste inserire il vostro dominio, potete farlo nella sezione `Custom
domains` del progetto. Assicuratevi di inserire sia il dominio base che il
sottodominio `www.`.

Ora siamo pronti per pubblicare il sito! Per farlo basta recarsi nella sezione
`Deployments` e cliccare su `Upload assets`.

![Il pulsante "Upload assets"](images/04-upload-assets.jpg "Il pulsante
\"Upload assets\". Possiamo notare una scritta in piccolo sotto il bottone...")

### Pubblicare il sito usando Wrangler

Fare il login sulla Dashboard di Cloudflare e aggiornare il sito manualmente
ogni volta che dobbiamo aggiornare qualcosa può essere un po'... sub-optimale.

Per questo motivo possiamo usare uno strumento molto comodo per caricare in
automatico tutti i nostri file dalla linea di comando: il suo nome è Wrangler
CLI.

Possiamo installarlo tramite `npm` con:

```shell
npm install -g wrangler
```

Per utilizzarlo ci servirà una chiave API, in modo che Wrangler CLI possa
aggiornare il sito per nostro conto.

Per creare una chiave bisogna andare nella sezione "[My
Profile](https://dash.cloudflare.com/profile)" della Dashboard di Cloudflare
per poi recarsi in `API Tokens` > `Create Token` e poi `Create Custom Token` in
fondo alla pagina.

Il token deve avere i seguenti parametri:

* **Name**: Chiamalo come vuoi, io lo chiamerò "blog"
* **Permissions**: `Account` > `Cloudflare Pages` > `Edit`
* **Account Resources**: `Include` > *La mail del tuo account*
* **Client IP Address Filtering**: *opzionale*
* **TTL**: *opzionale, ma consiglio **caldamente** di impostarlo*

![Parametri del token API](images/05-api-token.jpg "Ecco tutti i parametri che
dovete aver impostato")

Clicca su `Continue to summary` > `Create Token` e salva il token API.

{{< alert >}}
**Salva il token in un posto sicuro, verrà mostrato solo questa volta**
{{< /alert >}}

Infine, bisogna copiare l'account ID tornando nella [Dashboard di
Cloudflare](https://dash.cloudflare.com/) e aprendo il proprio dominio.
L'account ID si può trovare nella barra laterale destra, sotto la sezione
"API".

Ora, con la chiave API e l'account ID possiamo eseguire Wrangler con:

```shell
hugo  # Bisogna prima compilare il sito

export CLOUDFLARE_ACCOUNT_ID=<Il tuo account ID>
export CLOUDFLARE_API_TOKEN=<Il token API>
npx wrangler pages deploy 'public/' --project-name=<Il nome del progetto>
```
