Hosting gratuito per NodeJS? Ci siamo quasi

Visto che ho ricevuto molte richieste tramite Corso JavaScript, su come iniziare a programmare e pubblicare dei progetti con JavaScript / NodeJS ho deciso di scrivere questo post e spero che possa essere utile.

enter image description here Heroku può essere anche essere controllato via Dashboard Web, ma il terminale è meno dispersivo

Molti hanno iniziato a programmare e a pubblicare i propri lavori attraverso Altervista, un hosting gratuito per PHP oppure attraverso CPanel, ed è comprensibile. Tuttavia per NodeJS le cose funzionano un po' diversamente e nonostante sia improbabile trovare un hosting gratuito NodeJS è comunque possibile avvicinarsi a qualcosa di analogo.

La tecnologia che consiglio per mettere in produzione un'applicazione NodeJS è Docker o comunque Linux Container, tuttavia se si cerca qualcosa di gratis ed immediato questa è la via che consiglio.

La PaaS Heroku e le sue limitazioni

Heroku è la prima Platform as a Service ad avere riscosso un certo successo ed è anche il modo più veloce e con meno manutenzione che ci permette di mostrare qualcosa al mondo :) senza dover diventare sistemisti, in quanto ci dobbiamo preoccupare solo del nostro codice applicativo e lasciamo in gestione a loro il sistema operativo (Linux), i suoi aggiornamenti, la messa in sicurezza, la sua configurazione, database, backup.. e tanti aspetti che almeno all'inizio non fanno la differenza.

Ecco i limiti principali di Heroku gratuito:

  • Le applicazioni su Heroku non gestiscono file statici, es. upload di immagini, file,.. o meglio se abbiamo questa necessità bisogna appoggiarsi a un server di terze parti: Amazon S3 o altro fornitore, per avere la persistenza.

  • La nostra applicazione NodeJS (o un'altra tecnologia) chiamata anche Dyno viene "spenta" quando non viene utilizzata per più di 10 minuti (o comunque un tot di tempo), questo significa che a volte bisogna aspettare qualche secondo prima che il nostro sito sia nuovamente visibile. Si risolve passando a un piano a pagamento.

  • Il database Postgres può avere massimo un cero numero di record. Si risolve passando a un piano a pagamento.

Prerequisiti

Se già siete riusciti a sviluppare qualcosa in NodeJS avete già l'occorrente: npm, nodejs, git, dovete solo installare Heroku CLI, il comando da terminale che vi permette di interagire con l'hosting.

Applicazione NodeJS d'esempio + Database: Ghost

Potrei scrivere un esempio in NodeJS, ma preferisco utilizzare un'applicazione reale. Ghost è una sorta di Wordpress sviluppata in NodeJS, quindi un'applicazione reale per fare blog e che memorizza i post in un database Postgres. Probabilmente quello che il 99% dei siti e applicazioni fanno. Se utilizzate MongoDB, Redis o un altro db la procedura sarà comunque molto simile.

Scompattate il file .zip che avete scaricato da Ghost e assicuratevi che la struttura sia analoga. Tutti i comandi che eseguiremo saranno dati dall'interno della cartella del progetto ghost-corso-javascript.

❯ mkdir ghost-corso-javascript
❯ cd ghost-corso-javascript
❯ ls
Gruntfile.js        PRIVACY.md          config.example.js   core                npm-shrinkwrap.json  
LICENSE             README.md           content             index.js            package.json  

Inizializzazione del progetto Heroku / NodeJS

Create un file Procfile, questo file descrive come deve partire la vs applicazione sul server remote.

web: npm start --production  

Ora ci autentichiamo con i dati di registrazione che abbiamo ottenuto da Heroku. È necessario farlo una sola volta.

❯ heroku login
...

Perfetto, ora siamo pronti a creare, modificare o monitorare le nostre applicazioni su Heroku, senza necessariamente usare il browser.

Quindi creiamo la nostra prima applicazione pubblica, il nome e le password ci vengono generate in automatico da Heroku e possiamo anche verificarlo nella dashboard web.

❯ heroku create
Creating app... done, ⬢ intense-crag-21138  
❯ heroku addons:add heroku-postgresql:hobby-dev --app intense-crag-21138
Creating heroku-postgresql:hobby-dev on ⬢ intense-crag-21138... free  
Database has been created and is available  
 ! This database is empty. If upgrading, you can transfer
 ! data from another database with pg:copy
Created postgresql-rugged-11532 as DATABASE_URL  
Use heroku addons:docs heroku-postgresql to view documentation  

Ovviamente i nomi generati per voi saranno diversi, ma in questo caso:

  • intense-crag-21138 è il nome dell' app
  • postgresql-rugged-11532 è il nome del database

Sarà vostra cura mantenere segrete le password associate.

Bene, ora abbiamo un'applicazione vuota e un database associato. Dobbiamo inizializzare un progetto git (l'upload e le modifiche utilizzeranno questa convenzione).
Poi dobbiamo ottenere l'url del database e associare il progetto git al repository git locale a quello remoto. Così come mostrato nei comandi sottostanti.

❯ git init
❯ heroku config --app intense-crag-21138                                      
=== intense-crag-21138 Config Vars
DATABASE_URL: postgres://vxwuvgbqigvmhp:_cDFRk8HgoNXRDT7Q8IIeI-lJ7@ec2-54-243-249-56.compute-1.amazonaws.com:5432/df0vo3enil32je  
DATABASE_URL: postgres://user:password@host:port/dbname  
❯ heroku git:remote -a intense-crag-21138
set git remote heroku to https://git.heroku.com/intense-crag-21138.git  

Di tutte le modifiche fatte finora la nostra applicazione Ghost non è a conoscenza, quindi ora dobbiamo farle conoscere i parametri di produzione quando partirà in modalità production.

Quindi costruiamo il nostro config.js così come suggerito nell'esempio e andiamo a modificare la parte "production" con i dati che abbiamo in possesso.
Come potete vedere in produzione, in questo caso, si può utilizzare addirittura un db diverso (Postgres) rispetto a quello usato in sviluppo (SQLite) e partendo dalla dburl che siamo in possesso ricaviamo: host, user, password e il nome del database.

❯ cp config.example.js config.js
    production: {
        url: 'http://intense-crag-21138.herokuapp.com',
        mail: {},
        database: {
            client: 'postgres',
            connection: {
                host: 'ec2-54-243-249-56.compute-1.amazonaws.com',
                user: 'vxwuvgbqigvmhp',
                password: '_cDFRk8HgoNXRDT7Q8IIeI-lJ7',
                database: 'df0vo3enil32je',
                port: '5432'
            },
            debug: false
        },

        server: {
            host: '0.0.0.0',
            port: process.env.PORT
        }
    },

Ci siamo quasi, ora dobbiamo solo più aggiungere le modifiche a git e pubblicare online i cambiamenti. Questi 3 comandi sono quelli che utilizzeremo ogni volta che vogliamo sincronizzare il codice locale con il codice remoto.

❯ git add .
❯ git commit -m "Guarda mamma, ho l'app NodeJS online"
❯ git push heroku master
Counting objects: 491, done.  
Delta compression using up to 4 threads.  
Compressing objects: 100% (468/468), done.  
...
remote: -----> Discovering process types  
remote:        Procfile declares types -> web  
remote:  
remote: -----> Compressing...  
remote:        Done: 53.5M  
remote: -----> Launching...  
remote:        Released v4  
remote:        https://intense-crag-21138.herokuapp.com/ deployed to Heroku  
remote:  
remote: Verifying deploy... done.  
To https://git.heroku.com/intense-crag-21138.git  
 * [new branch]      master -> master

Congratulazioni, la vostra app NodeJS + Database è visibile a tutti su internet! Nel log si vede che è riconosciuta come app NodeJS, vengono ricevuti i cambiamenti e il sito punta alla nuova versione.

Bello, ma come si fa a sapere se sta funzionando correttamente?

Manutenzione e debugging

Non potendo gestire il server direttamente, Heroku ci mette comunque a disposizione dei tool per fare il deploy e capire come sta funzionando dietro le quinte.

Uptime. Con il seguente comando sappiamo da quanto tempo è attiva la nostra app e in che modalità.

❯ heroku ps
Free dyno hours quota remaining this month: 550h 0m (100%)  
For more information on dyno sleeping and how to upgrade, see:  
https://devcenter.heroku.com/articles/dyno-sleeping

=== web (Free): npm start --production (1)
web.1: up 2016/10/17 18:36:58 +0200 (~ 6m ago)  

Sta funzionando correttamente? Con i seguenti comandi possiamo vedere i log e/o riavviare la nostra istanza di app remota.

❯ heroku logs
..
❯ heroku restart
Restarting dynos on ⬢ intense-crag-21138... done  

corso javascript