Dev Blog

Sviluppo remoto: Code-Server, Coolify e Hetzner - le peggiori trappole architetturali

Come sviluppatore software freelance e consulente IT, la flessibilità è tutto. Che stia lavorando su complessi backend Java Spring Boot, realizzando frontend JavaScript o renderizzando visualizzazioni Three.js, l’ambiente di sviluppo deve essere fluido, riproducibile e accessibile ovunque.

Per questo ho abbandonato il classico approccio all’hosting e trasferito la mia infrastruttura su un server Hetzner dedicato, completamente orchestrato da Coolify. Il cuore del sistema è un’istanza remota di VS Code (Code-Server).

In teoria è una configurazione da sogno. In pratica, sono incappato in trappole architetturali che mi hanno quasi fatto impazzire. Ecco gli ostacoli principali e come evitarli in modo elegante.

Trappola 1: l’illusione del proxy delle porte (ovvero lo schermo nero della morte)

VS Code nel browser offre una funzione apparentemente geniale: il port forwarding integrato. Quando avvii un server di test locale, per esempio sulla porta 4096, l’IDE crea automaticamente un tunnel verso un URL come https://la-tua-ide.it/proxy/4096/.

Per lo sviluppo puramente backend, come un’API REST Spring Boot che restituisce solo JSON, è fantastico. Nessuna regola del firewall e accesso diretto.

Tuttavia, non appena avvii un frontend moderno con Vue, React o Vite, oppure uno strumento con interfaccia grafica, ti ritrovi davanti a uno schermo nero e a infiniti errori 404 nella console.

Il motivo: I framework moderni compilano usando percorsi assoluti, per esempio <script src="/main.js">. Il browser ignora completamente la sottodirectory /proxy/4096/, cerca i file nella radice del server e fallisce.

La soluzione: Traefik e sottodomini

L’unica architettura pulita consiste nell’ignorare completamente il tunnel integrato di VS Code. Utilizziamo invece il reverse proxy Traefik di Coolify:

  1. Crea presso il provider del dominio un record wildcard (*.tuodominio.it) che punti al server Hetzner.
  2. In Coolify, aggiungi ai domini del container un nuovo sottodominio con la porta interna: https://dev.tuodominio.it:4096.
  3. Traefik gestisce automaticamente il certificato SSL e instrada l’URL pubblico pulito, senza suffisso della porta, direttamente nel container. Il frontend viene caricato correttamente.

Trappola 2: l’equivoco di localhost (502 Bad Gateway)

Hai configurato il sottodominio in Coolify e non vedi l’ora di aprire l’anteprima, ma ricevi un gelido 502 Bad Gateway. Traefik funziona, ma il container blocca la connessione.

Questo accade quando il server interno, per esempio Five Server o uno strumento personalizzato, ascolta per impostazione predefinita su 127.0.0.1. Nel mondo Docker, significa che il servizio comunica solo con se stesso all’interno del container. Quando il proxy Traefik bussa dall’esterno, la porta resta chiusa.

La soluzione: Devi obbligare il server di test ad ascoltare su tutte le interfacce di rete. Se lo avvii dal terminale, usa --hostname=0.0.0.0 oppure imposta la variabile d’ambiente HOST="0.0.0.0". Se utilizzi un’estensione di VS Code come Five Server, modifica settings.json:

{
  "fiveServer.host": "0.0.0.0",
  "fiveServer.port": 5500
}

Trappola 3: l’amnesia di Docker («Restart» oggi, sparito domani)

Configuri con cura il tuo .bashrc con alias utili, generi una chiave SSH per GitHub, arresti il container tramite Coolify e il giorno dopo fai clic su «Deploy». Improvvisamente è sparito tutto. Gli alias sono stati cancellati e Git richiede nuovamente le password.

Non è un bug, ma una funzionalità. Un container arrestato appare per breve tempo con l’opzione «Restart». Durante la notte, la garbage collection di Coolify ripulisce il server ed elimina completamente il container inattivo. Facendo clic su «Deploy», il container viene ricostruito dall’immagine di base e tutto ciò che non era persistente va perso.

La struttura corretta

Non affidarti mai allo spazio di archiviazione effimero del container. Usa obbligatoriamente bind mount o volumi Docker per tutto ciò che deve rimanere.

volumes:
  - type: bind
    source: /opt/appdata/workspace # Il tuo codice
    target: /workspace
  - type: bind
    source: /opt/appdata/config    # Impostazioni VS Code, chiavi SSH e .bashrc
    target: /config

Trappola 4: configurazione CORS dietro il reverse proxy

L’ultima trappola scatta spesso durante lo sviluppo full stack. Il frontend si trova su https://dev.tuodominio.it e invia richieste al backend Spring. Per abitudine, includi la porta nella tua CorsConfiguration:

// ERRATO se davanti è presente un reverse proxy!
configuration.setAllowedOriginPatterns(
    Arrays.asList("https://dev.tuodominio.it:5500")
);

Il backend blocca nuovamente la richiesta. Perché? La porta 5500 è soltanto un’istruzione di routing interna a Coolify. Verso l’esterno, il browser comunica in modo trasparente con il proxy Traefik tramite la porta HTTPS standard 443. Di conseguenza, imposta l’header Origin semplicemente su https://dev.tuodominio.it.

Rimuovi la porta dalla configurazione del backend e gli errori CORS scompariranno.


Conclusione: Una configurazione personale con Coolify e Code-Server su Hetzner richiede inizialmente un po’ di pazienza e una solida conoscenza di Docker. Tuttavia, quando il routing è configurato correttamente, i volumi sono montati e le porte sono giuste, disponi di un IDE cloud privato ad alte prestazioni che non ha nulla da invidiare alle tradizionali soluzioni SaaS.