Docker: Node.js

Come utilizzare e distribuire un'app Node.js con Docker

👋 Benvenuti nella documentazione di Stackhero!

Stackhero offre una soluzione Docker cloud CaaS (Containers as a Service) pronta all'uso che fornisce numerosi vantaggi, tra cui:

  • Distribuisci facilmente i tuoi container in produzione con un semplice docker-compose up.
  • Nome di dominio personalizzabile protetto con HTTPS (ad esempio, https://api.tua-azienda.com, https://www.tua-azienda.com, https://backoffice.tua-azienda.com).
  • Prestazioni ottimali e sicurezza robusta grazie a una VM privata e dedicata.
  • Aggiornamenti senza sforzo con un solo clic.

Risparmia tempo e semplifica la tua vita: bastano 5 minuti per provare la soluzione di hosting cloud Docker CaaS di Stackhero e distribuire i tuoi container in produzione!

Questa guida offre una solida base per sviluppare un'app Node.js e distribuirla in produzione rapidamente e facilmente.

Non è richiesta alcuna conoscenza preliminare di Docker. Tutto è configurato per garantire un'esperienza fluida; è sufficiente avere Docker installato sul proprio computer.

Questa documentazione è progettata sia per principianti che per utenti esperti che desiderano distribuire un'applicazione Node.js utilizzando tecnologie moderne e scalabili senza complicazioni inutili.

Le caratteristiche principali di questa soluzione includono:

  • 💪 Configurazione facile con il minimo sforzo
  • 🐳 Utilizzo di Docker per ambienti di sviluppo e produzione
  • 🔄 Ricaricamento automatico di Node.js al cambio di codice usando nodemon
  • 🚀 Distribuzione in produzione con un solo comando
  • 🔒 Gestione dei certificati TLS per una crittografia HTTPS sicura
  • 🚧 Supporto per piattaforme di staging e preproduzione
  • 🧱 Architettura modulare e scalabile

Se Docker non è ancora installato sul tuo computer, puoi scaricarlo dal sito ufficiale di Docker. Per verificare che Docker funzioni correttamente, apri un terminale ed esegui docker version. Dovresti vedere le informazioni sulla versione senza errori.

Dopo aver installato Docker, clona il seguente repository boilerplate:

git clone https://github.com/stackhero-io/nodejsWithDockerGettingStarted/
cd nodejsWithDockerGettingStarted

Quindi, avvia la piattaforma di sviluppo eseguendo make development-start o visualizza tutti i comandi disponibili con make help.

Per avviare la piattaforma di sviluppo, esegui:

make development-start

Questo comando costruisce l'immagine Docker, la esegue e avvia lo script dev definito in my-app/package.json (equivalente a eseguire npm run dev).

In questo esempio, viene creata una semplice API REST utilizzando Express. Puoi visualizzare l'API navigando su http://localhost:5000. La pagina dovrebbe mostrare "Hello World".

Successivamente, apri il file my-app/src/app.js nel tuo IDE preferito e modifica la seguente riga:

res.send('Hello World');

Cambiala in:

res.send('Updated!');

Salva il file. Il codice Node.js si ricaricherà automaticamente e un aggiornamento di http://localhost:5000 rifletterà la risposta API aggiornata.

Congratulazioni - ora hai una piattaforma di sviluppo completamente operativa!

Se hai bisogno di installare pacchetti aggiuntivi, puoi eseguire make development-shell per accedere alla shell del container. Una volta all'interno, usa NPM con npm install <package> o Yarn con yarn add <package> per installare i pacchetti desiderati.

Se hai un progetto Node.js esistente che desideri integrare con Docker, segui questi passaggi:

  1. Crea una nuova directory chiamata my-app all'interno del tuo progetto.

  2. Sposta tutti i file del tuo progetto nella directory my-app, escludendo i file .gitignore e .git.

  3. Copia docker, secrets e Makefile dal boilerplate nella directory principale del tuo progetto.

  4. Modifica il file .gitignore nel tuo progetto e aggiungi le seguenti righe:

    node_modules/
    secrets/*.production
    secrets/*.staging
    

Questo boilerplate presume che la tua app ascolti sulla porta 5000. Se preferisci un'altra porta, puoi modificare il file docker/docker-compose.development.yml e poi rilanciare l'ambiente con make development-start.

Se desideri specificare una versione diversa di Node.js, segui questi passaggi:

  1. Apri il file docker/my-app.dockerfile, che definisce l'immagine Docker per la tua app.
  2. Trova la prima riga che legge FROM node:<version>-alpine.
  3. Sostituisci <version> con la versione di Node.js scelta. Si consiglia di utilizzare la versione Long-Term Support (LTS). Puoi controllare l'ultima versione LTS sul sito di Node.js. Ad esempio, per utilizzare l'ultima versione LTS (attualmente 22), aggiorna la riga a FROM node:22-alpine. Se preferisci un numero di versione specifico, puoi usare qualcosa come FROM node:22.13.0-alpine.
  4. Salva le modifiche nel Dockerfile.

Imposta le variabili d'ambiente per la piattaforma di sviluppo nel file secrets/my-app.development.

Per la produzione, usa il file secrets/my-app.production.

Non commettere il file secrets/my-app.production nel tuo repository Git! Questo file contiene informazioni sensibili ed è ignorato di default nel .gitignore del boilerplate per evitare condivisioni accidentali.

Se la tua app Node.js deve memorizzare file (ad esempio, caricamenti utente), considera l'uso di un servizio di object storage come MinIO. Un servizio di object storage aiuta la tua applicazione a scalare senza problemi riducendo i potenziali problemi.

Se preferisci memorizzare file localmente, assicurati di utilizzare sempre un volume Docker. Memorizzare file direttamente in un container può portare a perdita di dati. Questo boilerplate fornisce un volume montato su /persistent per memorizzare i file in modo sicuro.

Non memorizzare mai dati persistenti al di fuori della directory /persistent a meno che tu non abbia creato volumi personalizzati e sia certo della configurazione. Memorizzare file al di fuori di /persistent comporterà una perdita di dati!

Puoi facilmente modificare questo boilerplate per aggiungere un ambiente di staging. Per farlo:

  1. Crea una copia di docker/docker-compose.production.yml e chiamala docker/docker-compose.staging.yml. Questo file definisce i container e la configurazione per il tuo ambiente di staging.
  2. Crea il file di secrets secrets/my-app.staging contenente qualsiasi informazione sensibile richiesta per lo staging, come password di database o chiavi API.
  3. Nel Makefile, trova la sezione etichettata "Staging platform" e decommentala.

Infine, esegui make help per visualizzare i nuovi comandi di staging ora disponibili.

Se non hai ancora un servizio Stackhero for Docker, puoi crearne uno facilmente dal tuo dashboard Stackhero. Sarà attivato in circa 2 minuti.

Se sei nuovo su Stackhero, puoi provare l'hosting cloud di container Docker gratuitamente per un mese.

Prima di distribuire la tua app in produzione, devi preparare alcuni file di configurazione:

  1. Copia secrets/global.production.example in secrets/global.production.
  2. Modifica secrets/global.production e sostituisci <XXXXXX>.stackhero-network.com con il nome host del tuo servizio Docker dal tuo dashboard Stackhero.
  3. Copia secrets/my-app.production.example in secrets/my-app.production.
  4. Modifica secrets/my-app.production e inserisci le tue credenziali.
  5. Aggiorna docker/docker-compose.production.yml sostituendo <XXXXXX>.stackhero-network.com con il nome host del tuo servizio Docker.

Distribuire in produzione è semplice: esegui:

make production-deploy

Questo comando crea un container Docker, trasferisce i dati del tuo progetto e li invia al tuo servizio Docker in produzione. Apri il tuo browser e naviga verso il nome host del tuo servizio Docker (ad esempio, https://<XXXXXX>.stackhero-network.com). Dovresti vedere la tua API REST rispondere "Hello World".

Puoi anche usare make production, che distribuisce i tuoi container e mostra i log in tempo reale.

Per monitorare il tuo ambiente di produzione o risolvere problemi, puoi visualizzare i tuoi log usando questi comandi:

  • Per trasmettere i log in diretta, esegui: make production-logs-live
  • Per recuperare tutti i log memorizzati, esegui: make production-logs
  • Per recuperare i log di un giorno specifico (sostituisci YYYY-MM-DD con la data desiderata), esegui: make production-logs | grep "YYYY-MM-DD"

Se desideri utilizzare un nome di dominio diverso da https://<XXXXXX>.stackhero-network.com, Stackhero for Docker integra Traefik per semplificare la gestione dei domini. Traefik gestisce il routing HTTP e la crittografia TLS (HTTPS) per te.

Ecco alcuni esempi per personalizzare i tuoi nomi di dominio:

  • Per servire api.my-company.com tramite il tuo container my-app sulla porta 5000 con crittografia TLS, aggiorna il file docker/docker-compose.production.yml sostituendo la sezione labels con:

        labels:
          - "traefik.enable=true" # Abilita Traefik per instradare il traffico verso questo container
          - "traefik.http.routers.my-app.rule=Host(`api.my-company.com`)" # Definisci l'host
          - "traefik.http.routers.my-app.tls.certresolver=letsencrypt" # Usa letsencrypt per i certificati TLS
          - "traefik.http.services.my-app.loadbalancer.server.port=5000" # Specifica la porta 5000
    
  • Per servire my-company.com tramite il tuo container my-app sulla porta 5000 e reindirizzare tutte le richieste da www.my-company.com a my-company.com, aggiorna la sezione labels nello stesso file con:

        labels:
          - "traefik.enable=true"
          - "traefik.http.routers.my-app.rule=Host(`my-company.com`) || Host(`www.my-company.com`)" # Includi entrambi i domini
          - "traefik.http.routers.my-app.tls.certresolver=letsencrypt"
          - "traefik.http.services.my-app.loadbalancer.server.port=5000" # Specifica la porta 5000
    
          # Reindirizza www.my-company.com a my-company.com:
          - "traefik.http.routers.my-app.middlewares=redirect-www"
          - "traefik.http.middlewares.redirect-www.redirectregex.regex=^https://www.my-company.com/(.*)"
          - "traefik.http.middlewares.redirect-www.redirectregex.replacement=https://my-company.com/$${1}"
          - "traefik.http.middlewares.redirect-www.redirectregex.permanent=true"
    

Non dimenticare di configurare il DNS per my-company.com e www.my-company.com in modo che ciascuno punti come CNAME al tuo servizio Docker su https://<XXXXXX>.stackhero-network.com.