introduction
Les applications Web sont souvent conçues avec trois niveaux distincts:
-
Le premier niveau est lepresentation layer, ce que voit l'utilisateur.
-
Vient ensuite lesapplication layer, qui fournissent lesbusiness logic de l'application.
-
Enfin, ledata layer stocke les données nécessaires à l'application.
Dans une applicationRuby on Rails, cela mappe de manière lâche vers un serveur Web pour la couche de présentation, un serveur Rails pour la couche application et une base de données pour la couche de données. Dans cette configuration, la couche d'application communique avec la couche de données pour extraire des données pour l'application, qui sont ensuite affichées à l'utilisateur par le biais de la couche de présentation.
Bien qu'il soit possible d'installer toutes ces applications sur un seul serveur, le fait de placer chaque couche sur son propre serveur facilite la mise à l'échelle de l'application. Par exemple, si le serveur Rails devenait un goulot d'étranglement, vous pourriez ajouter davantage de serveurs d'applications sans affecter les deux autres couches.
Dans ce didacticiel, vous allez déployer une application Rails dans une configuration à trois niveaux en installant un ensemble unique de logiciels sur trois serveurs distincts, en configurant chaque serveur et ses composants pour qu'ils communiquent et fonctionnent ensemble et en sécurisant les connexions entre eux avec des tunnels SSH. Pour la pile logicielle, vous utiliserezNginx comme serveur Web sur la couche de présentation,Puma comme serveur d'application Rails sur la couche application, etPostgreSQL comme base de données sur la couche de données .
Conditions préalables
Pour compléter ce didacticiel, vous devrez activer trois serveurs Ubuntu 16.04. Nommez cesweb-server,app-server etdatabase-server, et chacun doit avoir le réseau privé activé.
Chacun des trois serveurs doit avoir un utilisateur non root avec les privilègessudo
ainsi qu'un pare-feu configuré pour autoriser les ocnnections SSH (que vous pouvez configurer en utilisant nosInitial Server Setup guide). Dans le contexte de ce tutoriel, l'utilisateursudo
sur chaque serveur est nommésammy.
De plus, chacun des trois serveurs a ses propres exigences de configuration:
-
Sur lesweb-server:
-
Installez et configurez le serveur Web Nginx. Pour ce faire, suivez notre tutoriel surHow to Install Nginx on Ubuntu 16.04.
-
-
Sur lesapp-server:
-
Installez Node.js en utilisant le PPA officiel, comme expliqué dansHow To Install Node.js on Ubuntu 16.04. Quelques fonctionnalités de Rails, telles que le pipeline d’actifs, dépendent d’un JavaScript Runtime et Node.js fournit cette fonctionnalité.
-
Installez le framework Ruby on Rails. Pour ce faire, suivez notre guide surHow to Install Ruby on Rails with rbenv on Ubuntu 16.04. Au fur et à mesure que vous suivez ce didacticiel, veillez à installer la dernière version de Ruby qui, au moment de la rédaction de cet article, est Ruby 2.5.1.
-
Installez PostgreSQL, comme indiqué dans la première section de notre tutorielHow To Use PostgreSQL with Your Ruby on Rails Application on Ubuntu 14.04. Cette section décrit également comment installer
libpq-dev
, un autre package requis pour cette configuration à trois niveaux. -
Déployez une application Rails à l'aide de Puma. Si vous n'avez pas d'application à déployer, suivez notre guide surHow To Deploy a Rails App with Puma and Nginx pour déployer un exemple d'application. Notez que dans la section «Installer le plug-in rbenv-vars» de ce prérequis, vous devez définir l'utilisateur et le mot de passe de la base de données pour refléter les valeurs que vous utilisez lorsque vous installez PostgreSQL sur lesdatabase-server. De plus, vous devez autoriser le port
3000
à travers votre pare-feu pour que la section «Créer une base de données de production» fonctionne. Enfin, vous n'avez pas besoin de suivre les deux dernières étapes de ce didacticiel préalable, à savoir «Créer un script Puma Upstart» et «Installer et configurer Nginx».
-
-
Sur lesdatabase-server:
-
Installez et configurez le logiciel de base de données PostgreSQL. Suivez notre guide surHow To Install and Use PostgreSQL on Ubuntu 16.04 pour savoir comment procéder. En suivant ce didacticiel prérequis, créez un rôle PostgreSQL pour votre application Rails avec les autorisations
superuser
ainsi qu'une base de données portant le même nom que le rôle PostgreSQL. Tout au long de ce didacticiel, le rôle et la base de données PostgreSQL sont tous deux appeléssammy. -
Définissez un mot de passe pour le rôle PostgreSQL nouvellement créé. Ignorez la première commande dans le "https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-puma-and-nginx-on-ubuntu-14-04#create -production-database-user [Créer un utilisateur de la base de données de production] »du didacticiel Puma (que vous avez également utilisé pour configurer lesapp-server), et suivez les commandes restantes de cette section pour changer le mot de passe de l'utilisateur de la base de données . Notez que le nom du rôle PostgreSQL et le mot de passe que vous avez défini pour lesdatabase-server doivent être identiques à ceux que vous avez définis lors de l’installation PostgreSQL deapp-server.
-
[[step-1 -—- creation-a-user-for-the-ssh-tunnels]] == Étape 1 - Création d'un utilisateur pour les tunnels SSH
LesSSH tunnels sont des connexions chiffrées qui peuvent envoyer des données d'un port sur un serveur vers un port sur un autre serveur, donnant l'impression qu'un programme d'écoute sur le second serveur s'exécute sur le premier. Avoir un utilisateur dédié pour les tunnels SSH permet d'améliorer la sécurité de votre configuration: si un intrus accède à l'utilisateur desammyur l'un de vos serveurs, il ne pourra pas accéder aux autres serveurs des trois. configuration de niveau. De même, si un intrus devait accéder à l'utilisateur detunnel, il ne pourra ni modifier les fichiers dans le répertoire de l'application Rails ni utiliser la commandesudo
.
Sur chaque serveur, créez un utilisateur supplémentaire nommétunnel. La seule fonction de l’utilisateur detunnel est de créer des tunnels SSH pour faciliter la communication entre les serveurs, donc, contrairement àsammy, ne donnez pas les privilèges àtunnelsudo
. De plus, l'utilisateur detunnelne doit pas avoir accès en écriture au répertoire de l'application Rails. Exécutez la commande suivante sur chaque serveur pour ajouter l'utilisateurtunnel:
sudo adduser tunnel
Sur la machineweb-server, basculez vers l'utilisateurtunnel.
sudo su tunnel
En tant qu'utilisateurtunnel, générez une paire de clés SSH:
ssh-keygen
Enregistrez la clé à l'emplacement par défaut et ne créez pas de phrase de passe pour les clés, car cela pourrait compliquer l'authentification ultérieurement lorsque vous créez des tunnels SSH entre les serveurs.
Après avoir créé la paire de clés, revenez à l'utilisateursammy:
exit
Maintenant, passez auxapp-server et exécutez à nouveau les mêmes commandes:
sudo su tunnel
ssh-keygen
exit
Vous avez maintenant configuré tous les utilisateurs dont vous aurez besoin pour la suite du didacticiel. Net, vous apporterez quelques modifications au fichier/etc/hosts
pour chaque utilisateurtunnel afin de rationaliser le processus de création des tunnels SSH.
[[step-2 -—- configuring-the-hosts-file]] == Étape 2 - Configuration du fichier Hosts
Tout au long de ce didacticiel, vous devez souvent vous référer aux adresses IP desapp-server ou desdatabase-server dans une commande. Plutôt que de devoir mémoriser et taper ces adresses IP à chaque fois, vous pouvez ajouter les adresses IP privées deapp-server etdatabase-server au fichier/etc/hosts
de chaque serveur. Cela vous permettra d'utiliser leurs noms dans les commandes suivantes à la place de leurs adresses et facilitera le processus de configuration des tunnels SSH.
Veuillez noter que, pour simplifier les choses, ce didacticiel vous demande d’ajouter les adresses IP privées deapp-server etdatabase-server au fichier/etc/hosts
sur chacun des trois serveurs. Bien qu’il ne soit techniquement pas nécessaire d’ajouter les adresses IP privées deapp-server oudatabase-server à leurs propres fichiershosts
, cela ne posera aucun problème. La méthode décrite ici a été choisie simplement pour la rapidité et la commodité.
Tout d'abord, recherchez les adresses IP privées de vosapp-server etdatabase-server. Si vous utilisez des gouttelettes DigitalOcean, accédez à votre Panneau de configuration et cliquez sur le nom de ces gouttelettes. Sur l'une de leurs pages spécifiques à Droplet, les adresses IP publique et privée sont affichées en haut de la page.
Ensuite, sur chaque serveur, ouvrez le fichier/etc/hosts
avec votre éditeur de texte préféré et ajoutez les lignes suivantes:
sudo nano /etc/hosts
/etc/hosts
. . .
app-server_private_ip app-server
database-server_private_ip database-server
En ajoutant ces lignes à ce fichier sur chaque serveur, vous pouvez utiliser les nomsapp-server etdatabase-server dans des commandes qui vous obligeraient généralement à utiliser les adresses IP de ces serveurs. Vous utiliserez cette fonctionnalité pour configurer les clés SSH afin que chacun de vos utilisateurstunnel puisse se connecter à vos autres serveurs.
[[step-3 -—- setting-up-ssh-logins]] == Étape 3 - Configuration des connexions SSH
Maintenant que vous avez un utilisateurtunnel et un fichier/etc/hosts
mis à jour sur vos trois serveurs, vous êtes prêt à commencer à créer des connexions SSH entre eux.
Au cours de cette étape, considérez les trois niveaux comme une pyramide, avec lesdatabase-server en bas, lesapp-server au milieu et lesweb-server en haut. Lesapp-server doivent pouvoir se connecter auxdatabase-server afin d'accéder aux données nécessaires à l'application Rails, et lesweb-server doivent pouvoir se connecter auxapp-server donc il a quelque chose à présenter aux utilisateurs.
Ainsi, il vous suffit d'ajouter la clé publique SSH de chaque utilisateurtunnel au serveur «en dessous», ce qui signifie que vous devez ajouter la clé publique de l'utilisateurweb-servertunnel au serveurapp-server et ajoutez la clé publique de l'utilisateurapp-servertunnel auxdatabase-server. Cela vous permettra d’établir des tunnels SSH chiffrés entre les niveaux et d’empêcher les oreilles indiscrètes du réseau de lire le trafic qui les sépare.
Pour commencer ce processus, copiez la clé publique de l'utilisateurtunnel sur lesweb-server, située à/home/tunnel/.ssh/id_rsa.pub
, dans le fichier/home/tunnel/.ssh/authorized_keys
sur lesapp-server.
Sur lesweb-server, affichez la clé publique de l'utilisateurtunnel dans le terminal avec la commande suivante:
sudo cat /home/tunnel/.ssh/id_rsa.pub
Sélectionnez la sortie texte et copiez-la dans le presse-papier de votre système.
SSH dans lesapp-server dans une session de terminal distincte et basculer vers l'utilisateur du tunnel:
sudo su tunnel
Ajoutez la clé dans le presse-papiers de votre système au fichierauthorized_keys
sur lesapp-server. Vous pouvez utiliser la commande suivante pour le faire en une seule étape. N'oubliez pas de remplacertunnel_ssh_publickey_copied_from_web_server
par la clé publique dans le presse-papiers de votre système:
echo "tunnel_ssh_publickey_copied_from_web-server" >> /home/tunnel/.ssh/authorized_keys
Après cela, modifiez les autorisations sur le fichierauthorized_keys
pour empêcher tout accès non autorisé à celui-ci:
chmod 600 /home/tunnel/.ssh/authorized_keys
Revenez ensuite à l'utilisateursammy:
exit
Ensuite, affichez la clé publique de l'utilisateurtunnel sur leapp-server - situé à/home/tunnel/.ssh/id_rsa.pub
- et collez-la dans le fichier/home/tunnel/.ssh/authorized_keys
sur ledatabase-server:
sudo cat /home/tunnel/.ssh/id_rsa.pub
sudo su tunnel
Étant donné que vous n’avez pas généré de paire de clés SSH sur lesdatabase-server, vous devrez créer le dossier/home/tunnel/.ssh
et ajuster ses autorisations:
mkdir /home/tunnel/.ssh
chmod 700 /home/tunnel/.ssh
Ajoutez ensuite la clé publique deapp-server au fichierauthorized_keys
et ajustez ses autorisations:
echo "tunnel_ssh_publickey_copied_from_app-server" >> /home/tunnel/.ssh/authorized_keys
chmod 600 /home/tunnel/.ssh/authorized_keys
Revenez ensuite à l'utilisateursammy:
exit
Ensuite, testez la première connexion en utilisant SSH pour vous connecter auxapp-server de votreweb-server en tant qu'utilisateurtunnel:
sudo su tunnel
ssh tunnel@app-server
La première fois que vous vous connectez duweb-server auapp-server, vous verrez un message vous demandant de confirmer que la machine à laquelle vous vous connectez est fiable. Tapez "yes" pour accepter l'authenticité desapp-server:
OutputThe authenticity of host '111.111.11.111 (111.111.11.111)' can't be established.
ECDSA key fingerprint is fd:fd:d4:f9:77:fe:73:84:e1:55:00:ad:d6:6d:22:fe.
Are you sure you want to continue connecting (yes/no)? yes
Vous verrez la bannière de bienvenue desapp-server et l'invite de commande montrera que vous êtes connecté auxapp-server. Cela confirme que la connexion SSH duweb-server auapp-server fonctionne correctement.
Quittez la connexion SSH vers leapp-server, puis quittez l’utilisateurtunnel pour revenir à l’utilisateursammy de votreweb-server:
exit
exit
Ensuite, suivez ces mêmes étapes pour tester la connexion SSH duapp-server audatabase-server:
sudo su tunnel
ssh tunnel@database-server
Acceptez également l'authenticité desdatabase-server. Lorsque vous verrez la bannière de bienvenue et l'invite de commande dudatabase-server, vous saurez que la connexion SSH duapp-server audatabase-server fonctionne comme prévu.
Quittez la connexion SSH vers lesdatabase-server, puis quittez l'utilisateurtunnel:
exit
exit
Les connexions SSH que vous avez configurées à l’étape constituent la base des tunnels SSH qui permettront des communications sécurisées entre vos trois niveaux de serveur. Cependant, dans leur forme actuelle, ces connexions sont susceptibles de s’effondrer et ne sont donc pas aussi fiables qu’elles pourraient l’être. En installant des logiciels supplémentaires et en configurant le tunnel pour qu'il fonctionne en tant que service, vous pouvez toutefois atténuer ces vulnérabilités.
[[step-4 -—- setting-up-a-persistent-ssh-tunnel-to-the-database-server]] == Étape 4 - Configuration d'un tunnel SSH persistant vers le serveur de base de données
Lors de la dernière étape, vous avez accédé à l'invite de commande sur un serveur distant à partir d'un serveur local. Un tunnel SSH vous permet de faire beaucoup plus que cela en mettant en tunnel le trafic des ports de l'hôte local aux ports de l'hôte distant. Ici, vous utiliserez un tunnel SSH pour crypter la connexion entre vosapp-server et lesdatabase-server.
Si vous avez suivi toutes les conditions préalables pour ce tutoriel, vous aurez installé PostgreSQL sur lesapp-server et lesdatabase-server. Pour éviter un conflit dans les numéros de port, vous devez configurer le tunnel SSH entre ces serveurs pour transférer les connexions du port5433
desapp-server au port5432
sur lesdatabase-server. Plus tard, vous reconfigurerez votre application Rails (hébergée sur vosapp-server) pour utiliser l'instance de PostgreSQL exécutée sur lesdatabase-server.
En commençant en tant qu'utilisateursammy sur leapp-server, passez à l'utilisateurtunnel que vous avez créé à l'étape 1:
sudo su tunnel
Exécutez la commandessh
avec les indicateurs et options suivants pour créer le tunnel entre lesapp-server etdatabase-server:
ssh -f -N -L 5433:localhost:5432 tunnel@database-server
-
L'option
-f
envoiessh
en arrière-plan. Cela vous permet d'exécuter de nouvelles commandes dans votre invite existante pendant que le tunnel continue de s'exécuter en arrière-plan. -
L'option
-N
indique àssh
de ne pas exécuter de commande à distance. Ceci est utilisé ici car vous ne voulez transférer que les ports. -
L'option
-L
est suivie de la valeur de configuration5433:localhost:5432
. Cela spécifie que le trafic provenant du port5433
du côté local (lesapp-server) est transmis au port5432
delocalhost sur le serveur distant (lesdatabase-server). Notez quelocalhost ici est du point de vue du serveur distant. -
La dernière partie de la commande,
tunnel@database-server
, spécifie l'utilisateur et le serveur distant auxquels se connecter.
Après avoir établi le tunnel SSH, revenez à l'utilisateursammy:
exit
À ce stade, le tunnel est en cours d'exécution, mais rien ne le surveille pour s'assurer qu'il reste en place. Si le processus se bloque, le tunnel sera interrompu, l'application Rails ne sera plus en mesure de communiquer avec sa base de données et vous commencerez à voir des erreurs.
Supprimez le tunnel que vous avez créé pour l'instant, car nous allons créer une configuration plus fiable. Comme la connexion est en arrière-plan, vous devrez trouver son ID de processus pour la tuer. Étant donné que chaque tunnel est créé par l’utilisateurtunnel, vous pouvez trouver son ID de processus en répertoriant les processus en cours et en filtrant la sortie pour le mot-clé «tunnel»:
ps axu | grep tunnel
Cela retournera quelque chose comme la sortie ci-dessous:
Outputtunnel 21814 0.0 0.1 44920 692 ? Ss 14:12 0:00 ssh -f -N -L 5433:localhost:5432 tunnel@database-server
sammy 21816 0.0 0.2 12916 1092 pts/0 S+ 14:12 0:00 grep --color=auto tunnel
Arrêtez le processus en exécutant la commandekill
suivie de son ID de processus:
sudo kill 21814
Pour maintenir une connexion SSH persistante entre le serveur d'applications et la base de données, installezautossh
. autossh
est un programme qui démarre et surveille une connexion SSH, et le redémarre si la connexion meurt ou cesse de passer du trafic:
sudo apt-get install autossh
systemd
is the default init system on Ubuntu, ce qui signifie qu'il gère les processus après le démarrage du système. Vous pouvez utilisersystemd
pour créer un service qui gérera et démarrera automatiquement votre tunnel SSH au redémarrage du serveur. Pour ce faire, créez un fichier appelédb-tunnel.service
dans le répertoire/lib/systemd/system/
, l'emplacement standard où les fichiers d'unité desystemd
sont stockés:
sudo nano /lib/systemd/system/db-tunnel.service
Ajoutez le contenu suivant au nouveau fichier pour configurer un service poursystemd
à gérer:
/lib/systemd/system/db-tunnel.service
[Unit]
Wants=network-online.target
After=network-online.target
[Service]
User=tunnel
WorkingDirectory=/home/tunnel
ExecStart=/bin/bash -lc 'autossh -N -L 5433:localhost:5432 tunnel@database-server'
Restart=always
StandardInput=null
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
KillMode=process
[Install]
WantedBy=multi-user.target
La ligne clé ici estExecStart
. Ceci spécifie le chemin d'accès complet à la commande et les arguments à exécuter pour démarrer le processus. Ici, il démarre un nouveau shellbash
puis exécute le programmeautossh
.
Enregistrez et fermez le fichier, puis rechargez la configuration desystemd
pour vous assurer qu'elle récupère le nouveau fichier de service:
sudo systemctl daemon-reload
Activez le servicedb-tunnel
pour que le tunnel vers lesdatabase-server démarre automatiquement à chaque démarrage du serveur:
sudo systemctl enable db-tunnel.service
Ensuite, démarrez le service:
sudo systemctl start db-tunnel.service
Exécutez à nouveau la commande suivante pour vérifier si le tunnel est actif:
ps axu | grep tunnel
Dans la sortie, vous verrez qu'il y a plus de processus en cours d'exécution cette fois carautossh
surveille maintenant le tunnel:
Outputtunnel 25925 0.0 0.1 4376 704 ? Ss 14:45 0:00 /usr/lib/autossh/autossh -N -L 5432:localhost:5432 tunnel@database-server
tunnel 25939 0.2 1.0 44920 5332 ? S 14:45 0:00 /usr/bin/ssh -L 61371:127.0.0.1:61371 -R 61371:127.0.0.1:61372 -N -L 5432:localhost:5432 tunnel@database-server
sammy 25941 0.0 0.2 12916 1020 pts/0 S+ 14:45 0:00 grep --color=auto tunnel
Maintenant que le tunnel est opérationnel, vous pouvez tester la connexion auxdatabase-server avecpsql
pour vous assurer qu'il fonctionne correctement.
Démarrez le clientpsql
et dites-lui de se connecter àlocalhost
. Vous devez également spécifier le port5433
pour vous connecter via le tunnel SSH à l'instance PostgreSQL sur lesdatabase-server. Spécifiez le nom de la base de données que vous avez créé précédemment et entrez le mot de passe que vous avez créé pour l'utilisateur de la base de données lorsque vous y êtes invité:
psql -hlocalhost -p5433 sammy
Si vous voyez quelque chose comme la sortie suivante, la connexion à la base de données a été configurée correctement:
Outputpsql (9.5.10)
SSL connection (protocol: TLSv1.2, cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256, compression: off)
Type "help" for help.
sammy=#
Pour fermer l'invite PostgreSQL, tapez\q
puis appuyez surENTER
.
Enfin, vous disposez d'un tunnel SSH persistant et fiable qui crypte le trafic entre vosapp-server etdatabase-server. Les fonctionnalités de sécurité du tunnel sont essentielles, car c'est via ce tunnel que l'application Rails sur vosapp-server communiquera avec l'instance PostgreSQL sur vosdatabase-server.
[[step-5 -—- configuring-rails-to-use-a-remote-database]] == Étape 5 - Configuration des rails pour utiliser une base de données distante
Maintenant que le tunnel duapp-server audatabase-server est configuré, vous pouvez l'utiliser comme canal sécurisé pour que votre application Rails se connecte via le tunnel à l'instance PostgreSQL sur ledatabase-server .
Ouvrez le fichier de configuration de la base de données de l’application:
nano /home/sammy/appname/config/database.yml
Mettez à jour la sectionproduction
pour que le numéro de port soit spécifié en tant que variable d'environnement. Cela devrait maintenant ressembler à quelque chose comme ça:
/home/sammy/appname/config/database.yml
. . .
production:
<<: *default
host: localhost
adapter: postgresql
encoding: utf8
database: appname_production
pool: 5
username: <%= ENV['APPNAME_DATABASE_USER'] %>
password: <%= ENV['APPNAME_DATABASE_PASSWORD'] %>
port: <%= ENV['APPNAME_DATABASE_PORT'] %>
Enregistrez et fermez ce fichier, puis ouvrez le fichier.rbenv-vars
dans le répertoire de l'application et éditez les variables d'environnement:
nano /home/sammy/appname/.rbenv-vars
Si vous définissez un nom et un mot de passe différents pour le rôle PostgreSQL sur lesdatabase-server, remplacez-les maintenant (dans l'exemple ci-dessous, le rôle PostgreSQL est nommésammy). Ajoutez également une nouvelle ligne pour spécifier le port de la base de données. Après avoir apporté ces modifications, votre fichier.rbenv-vars
devrait ressembler à ceci:
/home/sammy/appname/.rbenv-vars
SECRET_KEY_BASE=secret_key_base
APPNAME_DATABASE_USER=sammy
APPNAME_DATABASE_PASSWORD=database_password
APPNAME_DATABASE_PORT=5433
Enregistrez et fermez ce fichier lorsque vous avez terminé.
Étant donné que vous utilisez maintenant l'instance PostgreSQL sur lesdatabase-server au lieu de celle desapp-serverur lesquels vous avez déployé votre application Rails, vous devrez à nouveau configurer la base de données.
Sur lesapp-server, accédez au répertoire de votre application et exécutez la commanderake
pour configurer la base de données:
[.note] #Note: Cette commande feranot migrer toutes les données de la base de données existante vers la nouvelle. Si vous avez déjà des données importantes sur votre base de données, vous devez les sauvegarder, puis les restaurer plus tard.
#
cd /home/sammy/appname
rake db:setup
Une fois cette commande terminée, votre application Rails commencera à communiquer avec l'instance PostgreSQL sur lesdatabase-server via un tunnel SSH chiffré. La prochaine chose à faire est de configurer Puma en tant que servicesystemd
pour le rendre plus facile à gérer.
[[step-6 -—- configuration-et-démarrage-puma]] == Étape 6 - Configuration et démarrage de Puma
De la même manière que vous avez configuré le servicedb-tunnel
à l'étape 4, vous configurerezsystemd
pour exécuter Puma (le logiciel serveur que vous avez installé sur leapp-server dans le cadre des conditions préalables) en tant que service . L'exécution de Puma en tant que service lui permet de démarrer automatiquement au démarrage du serveur ou de redémarrer automatiquement en cas de panne, ce qui renforce la robustesse de votre déploiement.
Créez un nouveau fichier appelépuma.service
dans le répertoire/lib/systemd/system/
:
sudo nano /lib/systemd/system/puma.service
Ajoutez le contenu suivant, qui a été adapté dePuma’s systemd
documentation, au nouveau fichier. Assurez-vous de mettre à jour les valeurs en surbrillance dans les directivesUser
,WorkingDirectory
etExecStart
pour refléter votre propre configuration:
/lib/systemd/system/puma.service
[Unit]
Description=Puma HTTP Server
After=network.target
[Service]
# Foreground process (do not use --daemon in ExecStart or config.rb)
Type=simple
# Preferably configure a non-privileged user
User=sammy
# The path to the puma application root
# Also replace the "" place holders below with this path.
WorkingDirectory=/home/sammy/appname
# Helpful for debugging socket activation, etc.
# Environment=PUMA_DEBUG=1
Environment=RAILS_ENV=production
# The command to start Puma.
ExecStart=/home/sammy/.rbenv/bin/rbenv exec bundle exec puma -b tcp://127.0.0.1:9292
Restart=always
[Install]
WantedBy=multi-user.target
Enregistrez et fermez le fichier. Rechargez ensuitesystemd
, activez le service Puma et démarrez Puma:
sudo systemctl daemon-reload
sudo systemctl enable puma.service
sudo systemctl start puma.service
Après cela, confirmez que Puma est en cours d’exécution en vérifiant le statut du service:
sudo systemctl status puma.service
S'il est en cours d'exécution, vous verrez une sortie semblable à celle-ci:
Outputpuma.service - Puma HTTP Server
Loaded: loaded (/lib/systemd/system/puma.service; enabled; vendor preset: enabled)
Active: active (running) since Tue 2017-12-26 05:35:50 UTC; 1s ago
Main PID: 15051 (bundle)
Tasks: 2
Memory: 31.4M
CPU: 1.685s
CGroup: /system.slice/puma.service
└─15051 puma 3.11.0 (tcp://127.0.0.1:9292) [appname]
Dec 26 05:35:50 app systemd[1]: Stopped Puma HTTP Server.
Dec 26 05:35:50 app systemd[1]: Started Puma HTTP Server.
Dec 26 05:35:51 app rbenv[15051]: Puma starting in single mode...
Dec 26 05:35:51 app rbenv[15051]: * Version 3.11.0 (ruby 2.4.3-p205), codename: Love Song
Dec 26 05:35:51 app rbenv[15051]: * Min threads: 5, max threads: 5
Dec 26 05:35:51 app rbenv[15051]: * Environment: production
Ensuite, utilisezcurl
pour accéder et imprimer le contenu de la page Web afin de vérifier qu'elle est correctement diffusée. La commande suivante indique àcurl
de visiter le serveur Puma que vous venez de démarrer surapp-server sur le port9292
:
curl localhost:9292/tasks
Si vous voyez quelque chose comme le code ci-dessous, cela confirme que Puma et la connexion à la base de données fonctionnent correctement:
Output...
Tasks
Title
Note
...
Une fois que vous pouvez confirmer que votre application Rails est servie par Puma et est correctement configurée pour utiliser une instance PostgreSQL distante sur lesdatabase-server, vous pouvez passer à la configuration du tunnel SSH entre lesweb-server et le app-server.
[[step-7 -—- setting-up-and-persisting-the-ssh-tunnel-to-the-app-server]] == Étape 7 - Configuration et persistance du tunnel SSH sur le serveur d'applications
Maintenant que leapp-server est opérationnel, vous pouvez le connecter auweb-server. Comme pour le processus que vous avez suivi à l'étape 4, vous allez le faire en configurant un autre tunnel SSH. Ce tunnel permettra à Nginx sur lesweb-server de se connecter en toute sécurité via une connexion cryptée à Puma sur lesapp-server.
Commencez par installerautossh
sur leweb-server:
sudo apt-get install autossh
Créez un nouveau fichier appeléapp-tunnel.service
dans le répertoire/lib/systemd/system/
:
sudo nano /lib/systemd/system/app-tunnel.service
Ajoutez le contenu suivant à ce fichier. Encore une fois, la ligne clé est celle qui commence parExecStart
. Ici, cette ligne redirige le port9292
sur leweb-server vers le port9292
sur leapp-server où Puma écoute:
/lib/systemd/system/app-tunnel.service
[Unit]
StopWhenUnneeded=true
Wants=network-online.target
After=network-online.target
[Service]
User=tunnel
WorkingDirectory=/home/tunnel
ExecStart=/bin/bash -lc 'autossh -N -L 9292:localhost:9292 tunnel@app-server'
Restart=always
StandardInput=null
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=%n
KillMode=process
[Install]
WantedBy=multi-user.target
[.note] #Note: Le numéro de port dans la ligneExecStart
est le même que celui configuré pour Puma à l'étape précédente.
#
Rechargezsystemd
pour qu'il lit le nouveau fichier de service, puis activez et démarrez le serviceapp-tunnel
:
sudo systemctl daemon-reload
sudo systemctl enable app-tunnel.service
sudo systemctl start app-tunnel.service
Vérifiez que le tunnel est en place:
ps axu | grep tunnel
Vous devriez voir quelque chose qui ressemble à la sortie ci-dessous:
Outputtunnel 19469 0.0 0.1 4376 752 ? Ss 05:45 0:00 /usr/lib/autossh/autossh -N -L 9292:localhost:9292 tunnel@app-server
tunnel 19482 0.5 1.1 44920 5568 ? S 05:45 0:00 /usr/bin/ssh -L 54907:127.0.0.1:54907 -R 54907:127.0.0.1:54908 -N -L 9292:localhost:9292 tunnel@app-server
sammy 19484 0.0 0.1 12916 932 pts/0 S+ 05:45 0:00 grep --color=auto tunnel
Cette liste de processus filtrée montre queautossh
est en cours d'exécution et qu'il a démarré un autre processusssh
qui crée le tunnel chiffré réel entreweb-server etapp-server.
Votre deuxième tunnel est maintenant en place et crypte la communication entre vosweb-server etapp-server. Pour que votre application Rails à trois niveaux soit opérationnelle, il ne vous reste plus qu'à configurer Nginx pour qu'il transmette les demandes à Puma.
[[step-8 -—- configuring-nginx]] == Étape 8 - Configuration de Nginx
À ce stade, toutes les connexions et tunnels SSH requis ont été configurés et chacun de vos trois niveaux de serveur peut communiquer entre eux. La dernière pièce de ce casse-tête consiste à configurer Nginx pour qu'il envoie des demandes à Puma afin de rendre la configuration entièrement fonctionnelle.
Sur lesweb-server, créez un nouveau fichier de configuration Nginx à/etc/nginx/sites-available/appname
:
sudo nano /etc/nginx/sites-available/appname
Ajoutez le contenu suivant dans le fichier. Ce fichier de configuration Nginx est similaire à celui que vous avez utilisé si vous avez suivi notre guide surHow To Deploy a Rails App with Puma and Nginx. La principale différence est l'emplacement de l'application en amont; au lieu d'utiliser le fichier socket local, cette configuration pointe Nginx vers le tunnel SSH écoutant sur le port9292
:
/etc/nginx/sites-available/appname
upstream app {
server 127.0.0.1:9292;
}
server {
listen 80;
server_name localhost;
root /home/sammy/appname/public;
try_files $uri/index.html $uri @app;
location @app {
proxy_pass http://app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
Enregistrez et fermez ce fichier, puis activez le site et activez les modifications.
Tout d'abord, supprimez le site par défaut:
sudo rm /etc/nginx/sites-enabled/default
Accédez au répertoire Nginxsites-enabled
:
cd /etc/nginx/sites-enabled
Créez unsymbolic link dans le répertoiresites-enabled
dans le fichier que vous venez de créer dans le répertoiresites-available
:
sudo ln -s /etc/nginx/sites-available/appname appname
Testez votre configuration Nginx pour les erreurs de syntaxe:
sudo nginx -t
Si des erreurs sont signalées, revenez en arrière et vérifiez votre fichier avant de continuer.
Lorsque vous êtes prêt, redémarrez Nginx pour qu’il lise votre nouvelle configuration:
sudo systemctl restart nginx
Si vous avez suivi le tutoriel Puma dans les prérequis, vous auriez installé Nginx et PostgreSQL sur lesapp-server. Tous les deux ont été remplacés par des instances distinctes s'exécutant sur les deux autres serveurs, ces programmes sont donc redondants. Par conséquent, vous devez supprimer ces packages desapp-server:
sudo apt remove nginx
sudo apt remove postgresql
Après avoir supprimé ces packages, veillez à mettre à jour vos règles de pare-feu pour empêcher tout trafic indésirable d’accéder à ces ports.
Votre application Rails est maintenant en production. Accédez à l'adresse IP publique de votreweb-server dans un navigateur Web pour le voir en action:
http://web-server_public_IP/tasks
Conclusion
En suivant ce tutoriel, vous avez déployé votre application Rails sur une architecture à trois niveaux et sécurisé les connexions de vosweb-server vers lesapp-server, et desapp-server vers ledatabase-server avec des tunnels SSH cryptés.
Avec les divers composants de votre application sur des serveurs distincts, vous pouvez choisir les spécifications optimales pour chaque serveur en fonction de la quantité de trafic que votre site reçoit. La première étape consiste à surveiller les ressources consommées par le serveur. Consultezour guide on CPU monitoring pour obtenir des instructions sur la façon de surveiller l'utilisation du processeur de vos serveurs. Si vous constatez que l'utilisation du processeur ou de la mémoire sur un niveau est très élevée, vous pouvez redimensionner le serveur sur ce niveau uniquement. Pour plus de conseils sur le choix d'une taille de serveur, consultez notre guide surChoosing the Right Droplet for Your Application.
Comme étape suivante immédiate, vous devez également sécuriser la connexion de vos utilisateurs auxweb-server en installant un certificat SSL sur lesweb-server. Consultez lesNginx Let’s Encrypt tutorial pour obtenir des instructions. De plus, si vous souhaitez en savoir plus sur l'utilisation des tunnels SSH, consultezthis guide.