Da zero a server gratis, la mia esperienza con Oracle Cloud Infrastructure Always Free
Tempo di lettura: 13 min
In questa articolo voglio spiegare passo passo come ho creato una macchina virtuale completamente gratuita e per sempre usando Oracle Cloud Infrastructure (OCI), sfruttando il piano Always Free.
Registrazione
Per prima cosa sono andata sul sito ufficiale https://www.oracle.com/it/cloud/.
La schermata iniziale è questa:
Ho cliccato su “Prova OCI gratuitamente” e poi su “Richiedi una prova gratuita”.
A questo punto verrà mostrata la schermata di registrazione:

A un certo punto chiederà di verificare l’identità usando una carta di credito.
Lo so, purtroppo non si può fare altrimenti. Io l'ho caricata perché serve solo per confermare che sei una persona reale e non un bot. Ho usato questo servizio e non mi è mai stato tolto un euro.
Ah cosa importante, non accetta carte prepagate o temporanee, ma serve una carta di credito “vera” (ho letto su Reddit che in alcuni casi vanno anche le carte di debito, ma non sempre).
Bisogna fare anche attenzione a inserire lo stesso indirizzo di residenza associato alla carta, altrimenti la verifica potrebbe fallire. Nel mio caso è andato tutto liscio al primo colpo, ma comunque si può riprovare nel caso non andasse a buon fine.
Viene anche chiesto di scegliere dove posizionare il server fisico e nel mio caso ho scelto Milano. Attenzione che questa scelta non può essere modificata in seguito. Io consiglio di scegliete quella più vicina a voi o ai vostri clienti per avere meno latenza.
Creazione di un'instanza
Una volta fatta tutta la registrazione ed essere entrati dentro Oracle Cloud Infrastructure, ho potuto creare la macchina virtuale.
Informazioni base
In alto a sinistra c'è un menu. Bisogna cliccarci e cercare la sezione Compute → Instances, poi cliccare su Create instance.
La schermata è questa:

Qui in realtà non c’è molto da toccare.
Nel mio caso avevo solo un Availability Domain (AD-1 a Milano), quindi ho lasciato tutto così com’era.
Adesso viene la parte in cui bisogna un po' smanettare.
Cliccare su “Change image”, perché vogliamo usare Ubuntu aggiornato e soprattutto l’architettura ARM (che è quella gratuita).



Selezionare:
- Ubuntu (ultima versione disponibile, nel mio caso 24.04)
- Architettura aarch64 (ARM)
Poi confermare cliccando su “Select image”.
Appena verrà confermata, Oracle imposterà automaticamente una macchina compatibile (Ampere).

A questo punto cliccare su “Change shape”:

Qui possiamo impostare quanto deve essere potente la macchina.
La cosa bella del piano Always Free di Oracle Cloud Infrastructure è che dà un po’ di libertà: a disposizione ci sono fino a 4 OCPU e 24 GB di RAM, ma possono essere distribuiti come si preferisce.
Nel mio caso, ho scelto di andare sul semplice con una sola VM con tutte le risorse disponibili. Quindi seleziono VM.Standard.A1.Flex, imposto 4 OCPU e lascio fare a lui per la RAM, che viene adattata automaticamente.

Security
Qui ho lasciato tutto com’è perchè OCI configura già le regole base, quindi non serve toccare nulla a meno di esigenze particolari.

Networking
Questa è una di quelle parti che, quando l'ho vista prima volta mi è sembrata super complicata ahahaha ma in realtà non è niente di che. Visto che era la mia prima macchina virtuale, ho selezionato “Create a new virtual cloud network” e ho lasciato il resto inalterato.

In questo modo, è come se avessi detto ad Oracle di fare un bel po’ di lavoro al posto mio. In pratica, lui crea automaticamente tutta l’infrastruttura di rete necessaria per far funzionare la macchina. Non solo “una rete”, ma proprio tutti i pezzi che normalmente bisognerebbe configurare a mano.
Infatti, dietro le quinte:
- crea una rete virtuale privata (VCN), che è come una piccola rete locale tutta tua dentro il cloud
- dentro questa rete crea una subnet, cioè una “porzione” in cui verrà inserita la tua VM
- aggiunge un internet gateway, che permette alla macchina di comunicare con internet (sia in entrata che in uscita)
- imposta delle regole firewall di base, ad esempio per permettere l’accesso SSH
Se avessi dovuto configurare tutto questo a mano, ci avrei messo decisamente più tempo (e sicuramente avrei sbagliato qualcosa ahahaha).
Chiavi SSH
A questo punto mi ha chiesto le chiavi SSH, cioè il metodo con cui poi mi collegherò alla macchina.
Nell'opzione automatica, Oracle genererà una coppia di chiavi e le farà scaricare e salvare:
- su Linux / macOS nella cartella
~/.ssh/ - su Windows in
C:\Users\TUO_UTENTE\.ssh\

Io essendo un po' più pratica, ho preferito generare le chiavi da sola e caricare sulla piattaforma solo la chiave pubblica. In questo modo ho potuto generare una chiave che utilizza una passphrase che è comodo avendo MacOS e il Touch ID. È la soluzione più “pulita”, ma per iniziare non è assolutamente necessaria.
Storage
L’ultima cosa che ho dovuto configurare è lo storage, cioè lo spazio su disco della macchina.
Il piano Always Free di Oracle Cloud Infrastructure mette a disposizione fino a 200 GB totali, che puoi distribuire come vuoi tra le varie VM.
Di default OCI assegna una dimensione di 50GB al disco della macchina, che nella maggior parte dei casi va già bene. Io però ho scelto di usare tutti i 200GB cliccando su “Specify a custom boot volume size” e modificando il valore:

Riepilogo
Arrivata a questo punto, Oracle mi ha mostrato un riepilogo di tutto quello che ho configurato. Poi ho cliccato su Create.
E qui arriva la parte frustrante ahaha, la creazione fallirà quasi sicuramente con questo errore:
Risorse non disponibili / Out of Capacity
Questo è l'unica rottura del piano Always Free perché ha priorità di allocazione delle risorse molto bassa, quindi quando i server sono pieni, la richiesta viene rifiutata.
Comunque non mi sono scoraggiata e soprattutto non ho rifatto tutta la configurazione ogni volta.
Salvare la configurazione (Stack)
Per evitare di rifare tutto da zero, ho salvato questa configurazione come uno stack.
L'opzione è in basso, indicata come “Save as stack”, il nome che gli ho dato è My-Always-Free-VM.

In pratica ho salvato tutta la configurazione della macchina in un file Terraform, famoso in ambito DevOps.
Riprovare con lo stack
Lo stack verrà salvato in Developer Services → Resource Manager → Stacks.
Per riprovare basta cliccare sul nome My-Always-Free-VM e poi in alto a destra c'è Actions → Apply:

A quel punto partirà un job che proverà di nuovo a creare la macchina con le stesse impostazioni. Per controllare se è andato a buon fine basta andare nella sezione Jobs.
Automatizzazione
A questo punto, dopo aver fatto qualche tentativo a distanza di qualche ora, da buon ingegnere informatico mi sono chiesta se ci fosse un modo di automatizzare questa cosa.
Infatti il problema è che non si sa quando le risorse saranno disponibili. Potrebbe funzionare subito… oppure dopo cento tentativi. Avevo anche letto che le ore notturne (dalle 2:00 alle 7:00) aumentano la probabilità di assegnamento, ma col cavolo che mi sveglio a quelle ore per riprovare ahhaha.
Proprio per questo ho deciso di automatizzare tutto e lasciare che sia uno script a riprovare per me.
Creare una API Key
Per farlo, la prima cosa che bisogna fare è permettere al mio computer di “parlare” con Oracle Cloud Infrastructure tramite API.
Quindi la prima cosa da fare è creare una API Key.
Ho cliccato sul tuo profilo (in alto a destra) → User Settings:

Poi, nella sezione Tokens and Keys ho creato una nuova API key:

A questo punto OCI ti farà generare una coppia di chiavi. Le ho scaricate e salvate nello stesso punto delle vecchie chiavi SSH.
Subito dopo mi sono state mostrate alcune informazioni importanti (tipo OCID, fingerprint, tenancy, ecc.).
Ho cliccato quindi su Copy e le ho salvate sulle note, perché mi sarebbero servite a breve.
Installare la CLI di OCI
Ora ho installato la CLI (command line interface), cioè lo strumento che permette di interagire con OCI da terminale.
Su Linux modo più semplice è usare lo script ufficiale:
1bash -c "$(curl -L https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.sh)"Su MacOS è ancora più facile perché si può installare con brew:
1brew install oci-cliE poi ho seguito le istruzioni a schermo.
Su Windows ci sono due opzioni:
- usare PowerShell con lo script ufficiale
- oppure installarla tramite pip
Con PowerShell il comnado è questo:
1powershell -ExecutionPolicy Bypass -Command "Invoke-WebRequest -Uri https://raw.githubusercontent.com/oracle/oci-cli/master/scripts/install/install.ps1 -OutFile install.ps1; .\install.ps1"Configurazione della CLI
Una volta installata la CLI, l'ho configurata con il comando:
1oci setup configMi è stato chiesto di inserire le informazioni che prima avevo salvato nelle note:
- User OCID
- Tenancy OCID
- Region
- percorso (assoluto) della chiave privata della API Key
Alla fine, verrà creato automaticamente un file di configurazione:
- su Linux / macOS →
~/.oci/config - su Windows →
C:\Users\TUO_UTENTE\.oci\config
Questo file contiene tutte le credenziali per usare OCI da terminale.
Script di automazione della richiesta
L’idea è semplice: invece di stare lì a cliccare Apply ogni volta sperando che le risorse siano disponibili, questo script prova automaticamente a creare la macchina, e se non ci riesce… aspetta e riprova.
1#!/bin/bash
2set -uo pipefail
3
4# Configuration
5STACK_ID="YOUR_STACK_ID"
6DELAY=450 # delay between attempts in seconds (7.5 min)
7MAX_ATTEMPTS=0 # 0 = infinite
8LOG_FILE="oci-retry.log"
9THROTTLE_MIN=900 # min backoff when throttled (20 min)
10THROTTLE_MAX=3600 # max backoff when throttled (1 hour)
11
12export OCI_CLI_SUPPRESS_FILE_PERMISSIONS_WARNING=True
13
14attempt=0
15throttle_backoff=$THROTTLE_MIN
16echo "Starting automation for Oracle Stack $STACK_ID..." | tee -a "$LOG_FILE"
17
18while true; do
19 attempt=$((attempt + 1))
20 echo "--------------------------------------------" | tee -a "$LOG_FILE"
21 echo "[$(date -Iseconds)] Attempt #$attempt (throttle_backoff=${throttle_backoff}s)" | tee -a "$LOG_FILE"
22
23 RAW_OUTPUT=$(oci resource-manager job create-apply-job \
24 --stack-id "$STACK_ID" \
25 --execution-plan-strategy "AUTO_APPROVED" \
26 --wait-for-state SUCCEEDED \
27 --wait-for-state FAILED \
28 --wait-for-state CANCELED \
29 --max-wait-seconds 1800 \
30 2>&1)
31
32 # Strip any CLI status lines before the JSON object
33 JOB_JSON=$(echo "$RAW_OUTPUT" | awk '/^{/{flag=1} flag')
34
35 STATE=$(echo "$JOB_JSON" | jq -r '.data."lifecycle-state" // empty' 2>/dev/null)
36 JOB_ID=$(echo "$JOB_JSON" | jq -r '.data.id // empty' 2>/dev/null)
37
38 if [[ -z "$STATE" ]]; then
39 # Handle rate limiting explicitly
40 if echo "$RAW_OUTPUT" | grep -qiE "TooManyRequests|status.*429"; then
41 echo "Rate limited by OCI. Sleeping for $throttle_backoff seconds." | tee -a "$LOG_FILE"
42 sleep "$throttle_backoff"
43 # Exponential backoff, capped
44 throttle_backoff=$(( throttle_backoff * 2 ))
45 if [[ $throttle_backoff -gt $THROTTLE_MAX ]]; then
46 throttle_backoff=$THROTTLE_MAX
47 fi
48 continue
49 fi
50
51 echo "OCI CLI error (no parseable state):" | tee -a "$LOG_FILE"
52 echo "$RAW_OUTPUT" | tee -a "$LOG_FILE"
53 # Auth / stack-id / syntax errors: no point hammering. Bail out.
54 if echo "$RAW_OUTPUT" | grep -qiE "NotAuthenticated|NotAuthorized|InvalidParameter|stack .* not found"; then
55 echo "Fatal error, aborting." | tee -a "$LOG_FILE"
56 exit 1
57 fi
58 sleep $(( DELAY + RANDOM % 60 ))
59 continue
60 fi
61
62 # API call succeeded: gradually decrease backoff (halve it, floor at THROTTLE_MIN)
63 if [[ $throttle_backoff -gt $THROTTLE_MIN ]]; then
64 throttle_backoff=$(( throttle_backoff / 2 ))
65 if [[ $throttle_backoff -lt $THROTTLE_MIN ]]; then
66 throttle_backoff=$THROTTLE_MIN
67 fi
68 echo "API call succeeded, decreasing throttle_backoff to ${throttle_backoff}s" | tee -a "$LOG_FILE"
69 fi
70
71 echo "Job $JOB_ID -> $STATE" | tee -a "$LOG_FILE"
72
73 if [[ "$STATE" == "SUCCEEDED" ]]; then
74 echo "SUCCESS: instance created!" | tee -a "$LOG_FILE"
75 # MacOS notification
76 # osascript -e 'display notification "Oracle VM Created Successfully!" with title "OCI Stack Alert" sound name "Crystal"'
77 exit 0
78 fi
79
80 # Pull the logs to distinguish capacity errors from real failures
81 LOGS=$(oci resource-manager job get-job-logs --job-id "$JOB_ID" --all 2>/dev/null \
82 | jq -r '.data[]?.message' 2>/dev/null)
83
84 if echo "$LOGS" | grep -qiE "Out of host capacity|TooManyRequests|LimitExceeded|capacity"; then
85 echo "Capacity/quota issue, will retry." | tee -a "$LOG_FILE"
86 else
87 echo "Job failed for a non-capacity reason. Last log lines:" | tee -a "$LOG_FILE"
88 echo "$LOGS" | tail -n 20 | tee -a "$LOG_FILE"
89 exit 2
90 fi
91
92 if [[ $MAX_ATTEMPTS -gt 0 && $attempt -ge $MAX_ATTEMPTS ]]; then
93 echo "Max attempts reached, giving up." | tee -a "$LOG_FILE"
94 exit 3
95 fi
96
97 sleep $(( DELAY + RANDOM % 60 ))
98doneFunziona così:
- prende l'OCID stack ID, si trova in Developer Services → Resource Manager → Stacks, poi basta cliccare sul nome e all'interno della schermata si trova l'ID.
- prova a lanciare la creazione tramite CLI di Oracle Cloud Infrastructure
- controlla il risultato del tentativo
- se la creazione fallisce perché non ci sono risorse disponibili, aspetta e riprova
- se invece il problema è un errore serio (tipo credenziali sbagliate), si ferma subito
Un dettaglio interessante è che se Oracle limita le richieste (per via del rate limit), lo script non insiste subito, ma:
- aspetta un po’
- poi aumenta gradualmente il tempo di attesa
- e riprova con più calma
In pratica si adatta da solo alla situazione.
Fine
E a questo punto… non resta davvero altro da fare se non lasciarlo girare. Può volerci anche parecchio tempo, a volte giorni, quindi qui serve solo un po’ di pazienza e lasciare che il processo faccia il suo corso.
Una cosa interessante che ho letto su Reddit è che Oracle Cloud Infrastructure potrebbe deallocare automaticamente le risorse se la macchina rimane inutilizzata per troppo tempo (ad esempio se l’utilizzo resta sotto il 10% per più di 7 giorni).
Non è qualcosa che ho verificato personalmente, ma è comunque un comportamento plausibile per un piano Always Free.
Per questo motivo sto già pensando di farmi uno script leggero (probabilmente in Rust) da installare direttamente sulla VM, che:
- monitora l’utilizzo delle risorse
- e, se la macchina è troppo “ferma”, genera un piccolo carico artificiale per evitare che venga spenta o liberata
L’idea è semplicemente mantenere la VM “attiva” senza sprecarla, ma senza nemmeno esagerare.

