Più potente di qualsiasi documento di specifiche: “fammelo solo vedere un attimo”
Quando mi sono ritrovato unico sviluppatore in un progetto SI per la pubblica amministrazione, il muro più alto non era la tecnologia. Era l”incertezza’. L’ambiente ideale, in cui il design segue specifiche dei requisiti scritte con cura, semplicemente non esisteva. I referenti, con poche conoscenze di sviluppo, spesso non sapevano nemmeno cosa volessero finché non vedevano la schermata davanti.
“Mmm, sul disegno non riesco a capirlo… non posso provare a cliccarci sopra davvero?”
Ogni volta che completavo una funzionalità la lanciavo in locale (sul mio computer), facevo screenshot, ci appiccicavo annotazioni in penna rossa e spedivo via email un ‘file report (HWP/PPT)’. Ma con sole foto statiche il referente non si accontentava.
“Ah, era meglio la versione di prima. Ripristinala, per favore.” “Cosa succede se premo questo bottone? Mandami un video.”
Ieri preferiva A, oggi vuole B. Modifica il codice in locale, nuovo screenshot, riscrivi il report: loop infinito. La situazione si era completamente ribaltata: scrivevo report più di quanto sviluppassi.
Ho capito disperatamente: ‘non devo continuare a mandare screenshot del mio schermo, mi serve un parco giochi (un server di sviluppo) in cui il referente entri, clicchi quanto vuole e provi a romperlo’.

L’occasione capita per caso: la riscoperta di un server abbandonato
Per fortuna, durante la scissione aziendale, al nostro team è stato assegnato un server inutilizzato (un computer vuoto). Le caratteristiche non erano un granché, ma aveva Linux installato e un IP pubblico collegato: una risorsa preziosa.
“Capo, posso usare io questo server che avanza? Vorrei trasformarlo in un server di verifica per i referenti.”
Permesso accordato. Su questo server vuoto ho riversato tutta la tecnologia imparata fino a quel momento, iniziando a costruire il ‘mio piccolo impero infrastrutturale’. È stata la sintesi di mesi di fatica (la serie Works on My Machine & The Pipeline).
- GitLab (repository del codice): installo un repository privato per gestire il codice in tutta sicurezza.
- Docker Registry (repository delle immagini): creo un magazzino tutto nostro in cui conservare le immagini Docker buildate.
- Portainer (gestione dei container): per uno come me, che ha paura della CLI, permette di gestire Docker da un’interfaccia grafica (GUI).
- Nginx (web server): metto all’ingresso un portinaio che smista il traffico delle richieste tra frontend e backend.

La soluzione: separazione totale degli ambienti (Dev vs Prod)
Ora avevo due palcoscenici (Server). Per assecondare i capricci del referente proteggendo il server di produzione, ho separato la strategia di deploy.
- Server di sviluppo (Development): ‘un laboratorio dove sperimentare liberamente’
- Il referente non fa nemmeno in tempo a chiedere “allora, è pronto?”.
- Appena il codice arriva sul branch
develop, la pipeline parte all’istante e scatta il deploy automatico. - Il referente può collegarsi in qualsiasi momento all’URL del server di sviluppo, provare le funzionalità e lasciare il suo feedback.
- Server di produzione (Production): ‘il santuario di ciò che è verificato’
- Il deploy avviene solo quando il referente dichiara: “Questa funzionalità è quella definitiva!”.
- Il codice viene unito (Merge) nel branch
mastere il deploy parte solo quando io, su GitLab, premo il ‘pulsante di approvazione del deploy’ (Manual).
[Code Verification] Mettere ordine con deploy condizionali
GitLab CI consente di specificare percorsi di deploy diversi per ciascun branch. Implementando questa strategia in codice, ecco il risultato.
stages:
- build
- deploy
# 1. Build (comune)
build_job:
stage: build
script:
- ./gradlew build
- docker build -t my-reg/app:$CI_COMMIT_SHA .
- docker push my-reg/app:$CI_COMMIT_SHA
# 2. Deploy sul server di sviluppo (automatico)
# Appena il codice arriva sul branch 'develop', si fa il deploy senza chiedere nulla.
deploy_to_dev:
stage: deploy
script:
- ssh user@dev-server "docker service update --image my-reg/app:$CI_COMMIT_SHA app-dev"
only:
- develop
# 3. Deploy in produzione (approvazione manuale)
# Anche se il codice arriva sul branch 'master', non viene deployato finche non premo il pulsante.
deploy_to_prod:
stage: deploy
script:
- ssh user@prod-server "docker service update --image my-reg/app:$CI_COMMIT_SHA app-prod"
only:
- master
when: manual # Punto chiave! Si esegue solo quando 'una persona preme il pulsante'.
Punti chiave:
only: - develop: il branch di sviluppo va sempre in deploy automatico. Qui la velocità è tutto.when: manual: per il branch di produzione c’è una sicura: una persona ricontrolla ancora una volta e solo allora preme il pulsante.
Per concludere: finalmente un vero ‘da solo ce la faccio’
Adesso, anche per uno sviluppatore solo come me, c’è un sistema completo.
- Locale (Local): sviluppo delle funzionalità sul mio computer.
- Sviluppo (Dev): basta un
git pushe dopo 5 minuti la modifica è sul server di sviluppo. Il referente la verifica di persona. - Produzione (Prod): si raccolgono solo le funzionalità approvate e si fa il deploy in sicurezza con un solo clic.
Quel me dei primi tempi, che teneva aperto lo strumento di cattura schermo e annotava file Hangul facendo nottate, non esiste più. Quando il referente mi dice “puoi modificare questa cosa?”, posso rispondere “certo, ho corretto e l’ho caricato sul server di sviluppo, dai un’occhiata” e bermi il caffè con calma. Perché è il sistema a lavorare al posto mio.
Con questo cala il sipario sul lungo progetto [Re: Booting]. Dalle basi di informatica a Linux, Docker e la pipeline CI/CD. Spero che queste conoscenze, accumulate sbattendo la testa al muro partendo da zero, siano una piccola luce per i ‘full stack developer per necessità’ che da qualche parte stanno ancora combattendo da soli.


