Skip to content

Instantly share code, notes, and snippets.

@benob
Created April 13, 2021 13:28
Show Gist options
  • Save benob/1fa7793f65414ea6fc70e3f474aaacc4 to your computer and use it in GitHub Desktop.
Save benob/1fa7793f65414ea6fc70e3f474aaacc4 to your computer and use it in GitHub Desktop.
Déploiement site nodejs sur raspberry pi 4 à la maison

Hébergement d'un site nodejs sur Raspberry PI 4

Dernière mise à jour : avril 2021.

Nécessite :

  • Raspberry pi 4
  • alimentation usb
  • cable réseau (optionnel si vous utilisez du wifi)
  • carte SD >= 4GB pour ubuntu
  • lecteur de carte SD
  • ordinateur pour écrire la carte SD et faire ensuite des ssh
  • connexion internet avec ip publique (si possible fixe) et redirection de ports configurable
  • connaissance de la ligne de commande

Installation d'ubuntu

Voir aussi https://ubuntu.com/tutorials/how-to-install-ubuntu-on-your-raspberry-pi

Télécharger l'image d'ubuntu pour raspberry pi 4 à l'addresse suivante https://ubuntu.com/download/raspberry-pi

Décompresser le fichier

$ 7z x ubuntu-20.04.2-preinstalled-server-arm64+raspi.img.xz

Copie l'image sur une carte SD (>= 4GB). Attention, ça écase tout ce qu'il y avait dessus.

$ sudo dd if=ubuntu-20.04.2-preinstalled-server-arm64+raspi.img of=/dev/mmcblk0 bs=16M && sync

Notez le "sync" qui s'assure que les données soient effectivement écrites.

Configuration du réseau

Soit utiliser brancher cable ethernet (rien besoin de modifier), soit utiliser le wifi. Pour celà, sur l'ordinateur de départ, introduire la carte sd puis dans la partition system-boot, éditer le fichier network-config :

ethernets:
  eth0:
    dhcp4: true
    optional: true

wifis:
  wlan0:
  dhcp4: true
  optional: true
  access-points:
    <nom du réseau wifi>:
      password: "<mot de passe du wifi>"

Laisser booter le temps que l'installation se termine (5 minutes).

Il faut ensuite déterminer l'addresse ip du raspberry pi. Sur un ordi sur le même réseau, tapez :

$ arp -na | grep -i "dc:a6:32"
? (192.168.1.13) at dc:a6:32:8c:ae:71 [ether] on wlo1

Ici, l'addresse est 192.168.1.13.

Si ça ne donne rien, on peut aussi utiliser l'interface de son routeur internet qui liste les périfériques connectés.

Après ça il est possible de faire un ssh sur le respberry pi :

$ ssh ubuntu@192.168.1.13

Le mot de passe par défaut est "ubuntu".

Mise à jour des paquets sur la raspberry pi :

$ sudo apt update
$ sudo apt upgrade

Puis redémarrer.

Configuration du routeur

Il faut créer une redirection de port de l'adresse IP publique de la box internet vers l'addresse IP privée de la raspberry PI.

Par exemple :

IP internet  (port)   ->    IP raspberry PI (port)
241.36.29.139 (443)    ->    192.168.1.13 (443)
241.36.29.139 (80)     ->    192.168.1.13 (80)
  • Comment connaître l'addresse IP de sa box internet?

Voir : https://whatismyipaddress.com, https://www.what-is-my-ipv4.com

  • Comment configurer la redirection de port ?

Tutoriels pour freebox, orange, sfr : https://pixelboys.fr/regroupement-creer-une-redirection-de-port/

Tutoriel pour bouygues : https://www.youtube.com/watch?v=aJ0I52JdoQY

Il faut au moins rediriger les ports 80 (http) et 443 (https) pour pouvoir créer le certificat Let's Encrypt.

Création d'un nom de domaine

Freenom permet d'obtenir un nom de domaine gratuit pour une durée de 1 an.

Aller sur https://www.freenom.com.

Créer un compte. Enregistrer un nouveau domaine. Vérifier la disponibilité d'un nom (ici on utilisera tutorielwebamu.tk)

Choisir de configurer une entrée DNS, configurer un sous-domaine comme www.tutorielwebamu.tk Et faites pointer le tout vers l'addresse ip de votre box (ici 241.36.29.139)

Allez vérifier dans l'interface de gestion :

Services > mes domaines > tutorielwebamu > gérer le domaine > gérer le DNS freenom

Là vous devez voir au moins une entrée de type A avec comme cible votre addresse IP. La TTL indique le nombre de secondes nécessaire pour la mise à jour. Pour tester on peut mettre une valeur à 300 (10 minutes), mais une fois que tout est bon il faut mettre une valeur plus grande, genre 3600 (1h).

Au bout de 10 minutes, vous pouvez tester le nom de domaine :

$ nlsookup www.tutorielwebamu.tk
Server:		127.0.0.53
Address:	127.0.0.53#53

Non-authoritative answer:
Name:	tutorielwebamu.tk
Address: 241.36.29.139

Vérifier que ça renvoie la bonne addresse.

Installation de nginx

Voir https://ubuntu.com/tutorials/install-and-configure-nginx

À faire une fois connecté en ssh au raspberry pi.

$ sudo apt install nginx
  • Mise en place d'une configuration par défaut qui sert les fichiers du répertoire /var/www/tutorial en HTTP sur le port 80.

Supprimer le fichier par défaut /etc/nginx/sites-enabled/default. Dans un fichier /etc/nginx/sites-enabled/tutorielwebamu, mettre :

server {
       listen 80;
       listen [::]:80;

       server_name www.tutorielwebamu.tk;

       root /var/www/tutorial;
       index index.html;

       location / {
               try_files $uri $uri/ =404;
       }
}

Créez le dossier /var/www/tutorial et ajoutez un fichier /var/www/tutorial/index.html pour tester.

Redémarrer nginx :

$ sudo service nginx restart

Et tester dans un navigateur :

Notez que pour l'instant tout ça passe par le port 80 en HTTP.

Création du certificat TLS/SSL avec Let's Encrypt

Utiliser les instructions sur https://certbot.eff.org/lets-encrypt/ubuntufocal-nginx.

À faire une fois connecté en ssh à la raspberry pi.

Pour résumer :

$ sudo snap install core
$ sudo snap refresh core

$ sudo apt-get remove certbot

$ sudo snap install --classic certbot
$ sudo ln -s /snap/bin/certbot /usr/bin/certbot

$ sudo certbot --nginx

Entrez votre nom de domaine complet, ici www.tutorielwebamu.tk (normalement il le détecte automatiquement).

Le certificat se trouve ensuite ici :

/etc/letsencrypt/live/www.tutorielwebamu.tk/fullchain.pem

La clé privée est ici :

/etc/letsencrypt/live/www.tutorielwebamu.tk/fullchain.pem

Pour tester le renouvellement :

$ sudo certbot renew --dry-run

Maintenant visitez https://www.tutorielwebamu.tk/ qui doit afficher le contenu du site et dire que la connexion est sécurisée.

La configuration que certbot a généré :

server {
    server_name www.tutorielwebamu.tk;

    root /var/www/html;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }

    # il écoute sur le port 443 (https)

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
    listen 443 ssl; # managed by Certbot

    # le certificat et la clé
    ssl_certificate /etc/letsencrypt/live/www.tutorielwebamu.tk/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/www.tutorielwebamu.tk/privkey.pem; # managed by Certbot

    # options par défaut
    include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

# il écoute aussi sur le port 80 (http) et redirge le client vers https
server {
    if ($host = www.tutorielwebamu.tk) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    listen [::]:80;

    server_name www.tutorielwebamu.tk;
    return 404; # managed by Certbot
}

Installation de nodejs

À faire une fois connecté en ssh à la raspberry pi.

$ curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
$ sudo apt-get install -y nodejs

Création d'un serveur minimal express

$ npm install express

dans server.js :

const express = require('express');
let app = express();

app.get('/', (req, res) => {
  res.send('<h1>Salut depuis nodejs</h1>');
});

app.listen(3000, '0.0.0.0');

Lancer le serveur avec node server.js.

Verifier que ça marche depuis votre navigateur (en utilisant l'ip de votre raspberry pi) : http://192.168.1.13:3000/. Notez que c'est sur le réseau local et que la connexion est non cryptée (comme HTTP).

Configuration de nginx comme Reverse Proxy

Voir https://www.tecmint.com/nginx-as-reverse-proxy-for-nodejs-app/.

Reprendre /etc/nginx/sites-enabled/tutorielwebamu, changer la partie "location" :

location / {
    proxy_set_header   X-Forwarded-For $remote_addr;
    proxy_set_header   Host $http_host;
    proxy_pass http://127.0.0.1:3000;
}

Ça veut dire que toutes les requêtes doivent être renvoyée à localhost sur le port 3000 (là où tourne nodejs). En plus il réécrit les entêtes pour raconter ce qui se passe.

Redémarrer nginx :

$ sudo service nginx restart

Tester avec l'url https://www.tutorielwebamu.tk/. Notez que si node ne tourne pas, ça renvoie l'erreur 502 Bad Gateway.

Bonus : configurer node pour qu'il redemmarre tout seul

https://desertbot.io/blog/nodejs-git-and-pm2-headless-raspberry-pi-install

Bonus : configurer avec docker

https://www.crybit.com/dockerize-your-nodejs-app/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment