Déploiement d’une application Rails sur Ubuntu 14.04 avec Capistrano, Nginx et Puma

introduction

Rails est un framework d’applications Web open source écrit en Ruby. Il adhère à la philosophie «Convention sur la configuration» en faisant l’hypothèse qu’il existe la «meilleure» façon de faire les choses. Cela vous permet d’écrire moins de code tout en faisant plus sans avoir à passer par des fichiers de configuration sans fin.

Nginx est un serveur HTTP hautes performances, un proxy inverse et un équilibreur de charge connu pour son accent mis sur la simultanéité, la stabilité, l’évolutivité et une faible consommation de mémoire. Comme Nginx, Puma est un autre serveur Web extrêmement rapide et simultané, doté d’une mémoire très réduite, mais conçu pour les applications Web Ruby.

Capistrano est un outil d’automatisation de serveurs distants qui se concentre principalement sur les applications Web Ruby. Il est utilisé pour déployer de manière fiable des applications Web sur un nombre illimité de machines distantes en scriptant des flux de travail arbitraires sur SSH et en automatisant des tâches courantes telles que la précompilation d’actifs et le redémarrage du serveur Rails.

Dans ce didacticiel, nous allons installer Ruby et Nginx sur un droplet DigitalOcean Ubuntu et configurer Puma et Capistrano dans notre application Web. Nginx sera utilisé pour capturer les demandes des clients et les transmettre au serveur Web Puma exécutant Rails. Nous utiliserons Capistrano pour automatiser les tâches de déploiement courantes. Ainsi, chaque fois que nous devons déployer une nouvelle version de notre application Rails sur le serveur, nous pouvons le faire à l’aide de quelques commandes simples.

Conditions préalables

Pour suivre ce tutoriel, vous devez disposer des éléments suivants:

  • Ubuntu 14.04 x64 Droplet

  • Un utilisateur non root nommé + deploy + avec des privilèges sudo (Présentation du serveur initial avec Ubuntu 14.04 explique comment configurer cela.)

  • L’application Working Rails hébergée dans un référentiel git distant prêt à être déployé

En option, pour une sécurité accrue, vous pouvez désactiver la connexion root via SSH et modifier le numéro de port SSH, comme décrit dans https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04 [ Configuration initiale du serveur avec Ubuntu 14.04].

Toutes les commandes de ce tutoriel doivent être exécutées en tant qu’utilisateur + deploy +. Si un accès root est requis pour la commande, il sera précédé de + sudo +.

Étape 1 - Installation de Nginx

Une fois que le VPS est sécurisé, nous pouvons commencer à installer des packages. Mettez à jour les fichiers d’index du paquet:

sudo apt-get update

Ensuite, installez Nginx:

sudo apt-get install curl git-core nginx -y

Étape 2 - Installation des bases de données

Installez la base de données que vous utiliserez dans votre application Rails. Comme il existe de nombreuses bases de données parmi lesquelles choisir, nous ne les couvrirons pas dans ce guide. Vous pouvez voir les instructions pour les plus importantes ici:

Veillez également à vérifier:

Étape 3 - Installation de RVM et de Ruby

Ruby n’est pas installé directement. Au lieu de cela, nous utiliserons un gestionnaire de versions Ruby. Il y en a beaucoup parmi lesquels choisir (rbenv, chruby, etc.), mais nous utiliserons RVM pour ce tutoriel. RVM vous permet d’installer et de gérer facilement plusieurs rubis sur le même système et d’utiliser celui qui convient en fonction de votre application. Cela rend la vie beaucoup plus facile lorsque vous devez mettre à niveau votre application Rails pour utiliser un rubis plus récent.

Avant d’installer RVM, vous devez importer la clé GPG RVM:

gpg --keyserver hkp://keys.gnupg.net --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3

Ensuite, installez RVM pour gérer nos rubis:

curl -sSL https://get.rvm.io | bash -s stable

Cette commande utilisant + curl pour télécharger le script d’installation RVM à partir de` + https: // get.rvm.io`. L’option + -sSL + est composée de trois drapeaux:

  • + -s + indique à Curl de télécharger le fichier en 'mode silencieux'

  • + -S + indique à Curl d’afficher un message d’erreur en cas d’échec

  • + -L + indique à Curl de suivre toutes les redirections HTTP lors de la récupération du script d’installation

Une fois téléchargé, le script est redirigé vers + bash. L’option + -s + passe + stable + en tant qu’argument du script d’installation RVM pour télécharger et installer la version stable de RVM.

Nous devons charger le script RVM (en tant que fonction) pour pouvoir commencer à l’utiliser. Nous devons ensuite exécuter la commande + Requirements + pour installer automatiquement les dépendances et les fichiers nécessaires au bon fonctionnement de RVM et de Ruby:

source ~/.rvm/scripts/rvm
rvm requirements

Nous pouvons maintenant installer le Ruby de notre choix. Nous installerons les derniers + Ruby 2.2.1 + (au moment de la rédaction) comme notre Ruby par défaut:

rvm install 2.2.1
rvm use 2.2.1 --default

Étape 4 - Installation de Rails et de Bundler

Une fois que Ruby est configuré, nous pouvons commencer à installer Rubygems. Nous allons commencer par installer le gem Rails qui permettra à votre application Rails de s’exécuter, puis nous installerons + bundler + qui pourra lire le + Gemfile + de votre application et installer automatiquement tous les gems requis.

Pour installer Rails et Bundler:

gem install rails -V --no-ri --no-rdoc
gem install bundler -V --no-ri --no-rdoc

Trois drapeaux ont été utilisés:

  • + -V + (sortie détaillée): Imprime des informations détaillées sur l’installation de Gem

  • + - no-ri + - (ignore la documentation Ri): n’installe pas Ri Docs, ce qui permet d’économiser de l’espace et de rendre l’installation rapide

  • + - no-rdoc + - (Ignore les RDocs): n’installe pas les RDocs, économise de l’espace et accélère l’installation

Étape 5 - Configuration des clés SSH

Puisque nous voulons configurer des déploiements sans heurts, nous utiliserons les clés SSH pour l’autorisation. Commencez par serrer la main de GitHub, Bitbucket ou de tout autre Git Remote hébergeant la base de code de votre application Rails:

Ne vous inquiétez pas si vous recevez un message + Autorisation refusée (publickey) +. Générez maintenant une clé SSH (une paire de clés publique / privée) pour votre serveur:

ssh-keygen -t rsa

Ajoutez la clé publique nouvellement créée (+ ~ / .ssh / id_rsa.pub +) aux clés de déploiement de votre référentiel:

Si toutes les étapes ont été complétées correctement, vous devriez maintenant pouvoir "cloner +" votre dépôt git (via le protocole SSH, pas HTTP) sans entrer votre mot de passe:

git clone

Si vous avez besoin d’un exemple d’application pour les tests, vous pouvez créer l’application de test suivante spécialement créée pour ce tutoriel: Sample Rails App sur GitHub

La commande + git clone + créera un répertoire portant le même nom que votre application. Par exemple, un répertoire nommé + testapp_rails + sera créé.

Nous clonons uniquement pour vérifier si nos clés de déploiement fonctionnent, nous n’avons pas besoin de cloner ou d’extraire notre référentiel à chaque fois que nous appliquons de nouvelles modifications. Nous laisserons Capistrano gérer tout cela pour nous. Vous pouvez maintenant supprimer ce répertoire cloné si vous le souhaitez.

Ouvrez un terminal sur votre ordinateur local. Si vous n’avez pas de clé SSH pour votre ordinateur local, créez-en une également. Dans votre session de terminal locale:

ssh-keygen -t rsa

Ajoutez votre clé SSH locale au fichier Authorized Keys de votre Droplet (n’oubliez pas de remplacer le numéro de port par votre numéro de port personnalisé):

cat ~/.ssh/id_rsa.pub | ssh -p  deploy@ 'cat >> ~/.ssh/authorized_keys'

Étape 6 - Ajout de configurations de déploiement dans l’application Rails

Sur votre ordinateur local, créez des fichiers de configuration pour Nginx et Capistrano dans votre application Rails. Commencez par ajouter ces lignes au + Gemfile + dans l’application Rails:

Gemfile

group :development do
   gem 'capistrano',         require: false
   gem 'capistrano-rvm',     require: false
   gem 'capistrano-rails',   require: false
   gem 'capistrano-bundler', require: false
   gem 'capistrano3-puma',   require: false
end

gem 'puma'

Utilisez + bundler + pour installer les gems que vous venez de spécifier dans votre + Gemfile +. Entrez la commande suivante pour regrouper votre application Rails:

bundle

Après avoir groupé, exécutez la commande suivante pour configurer Capistrano:

cap install

Cela va créer:

  • + Capfile + dans le répertoire racine de votre application Rails

  • Fichier + deploy.rb + dans le répertoire + config +

  • Répertoire + deploy dans le répertoire` + config`

Remplacez le contenu de votre + Capfile + par ce qui suit:

Capfile

# Load DSL and Setup Up Stages
require 'capistrano/setup'
require 'capistrano/deploy'

require 'capistrano/rails'
require 'capistrano/bundler'
require 'capistrano/rvm'
require 'capistrano/puma'

# Loads custom tasks from `lib/capistrano/tasks' if you have any defined.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

Ce fichier + Capfile + charge certaines tâches prédéfinies dans vos fichiers de configuration Capistrano pour faciliter vos déploiements, tels que:

  • Choisir le bon rubis

  • Actifs de pré-compilation

  • Clonage de votre référentiel Git au bon emplacement

  • Installer de nouvelles dépendances lorsque votre Gemfile a changé

Remplacez le contenu de + config / deploy.rb + par ce qui suit, en mettant à jour les champs marqués en rouge avec vos paramètres app et Droplet:

config / deploy.rb

# Change these
server , port: , roles: [:web, :app, :db], primary: true

set :repo_url,
set :application,
set :user,
set :puma_threads,    [4, 16]
set :puma_workers,    0

# Don't change these unless you know what you're doing
set :pty,             true
set :use_sudo,        false
set :stage,           :production
set :deploy_via,      :remote_cache
set :deploy_to,       "/home/#{fetch(:user)}/apps/#{fetch(:application)}"
set :puma_bind,       "unix://#{shared_path}/tmp/sockets/#{fetch(:application)}-puma.sock"
set :puma_state,      "#{shared_path}/tmp/pids/puma.state"
set :puma_pid,        "#{shared_path}/tmp/pids/puma.pid"
set :puma_access_log, "#{release_path}/log/puma.error.log"
set :puma_error_log,  "#{release_path}/log/puma.access.log"
set :ssh_options,     { forward_agent: true, user: fetch(:user), keys: %w(~/.ssh/id_rsa.pub) }
set :puma_preload_app, true
set :puma_worker_timeout, nil
set :puma_init_active_record, true  # Change to false when not using ActiveRecord

## Defaults:
# set :scm,           :git
# set :branch,        :master
# set :format,        :pretty
# set :log_level,     :debug
# set :keep_releases, 5

## Linked Files & Directories (Default None):
# set :linked_files, %w{config/database.yml}
# set :linked_dirs,  %w{bin log tmp/pids tmp/cache tmp/sockets vendor/bundle public/system}

namespace :puma do
 desc 'Create Directories for Puma Pids and Socket'
 task :make_dirs do
   on roles(:app) do
     execute "mkdir #{shared_path}/tmp/sockets -p"
     execute "mkdir #{shared_path}/tmp/pids -p"
   end
 end

 before :start, :make_dirs
end

namespace :deploy do
 desc "Make sure local git is in sync with remote."
 task :check_revision do
   on roles(:app) do
     unless `git rev-parse HEAD` == `git rev-parse origin/master`
       puts "WARNING: HEAD is not the same as origin/master"
       puts "Run `git push` to sync changes."
       exit
     end
   end
 end

 desc 'Initial Deploy'
 task :initial do
   on roles(:app) do
     before 'deploy:restart', 'puma:start'
     invoke 'deploy'
   end
 end

 desc 'Restart application'
 task :restart do
   on roles(:app), in: :sequence, wait: 5 do
     invoke 'puma:restart'
   end
 end

 before :starting,     :check_revision
 after  :finishing,    :compile_assets
 after  :finishing,    :cleanup
 after  :finishing,    :restart
end

# ps aux | grep puma    # Get puma pid
# kill -s SIGUSR2 pid   # Restart puma
# kill -s SIGTERM pid   # Stop puma

Ce fichier + deploy.rb + contient des valeurs par défaut saines qui fonctionnent prêtes à l’emploi pour vous aider à gérer les versions de vos applications et à effectuer automatiquement certaines tâches lorsque vous effectuez un déploiement:

  • Utilise + production + comme environnement par défaut pour votre application Rails

  • Gère automatiquement plusieurs versions de votre application

  • Utilise des options SSH optimisées

  • Vérifie si vos télécommandes git sont à jour

  • Gère les journaux de votre application

  • Précharge l’application en mémoire lors de la gestion des travailleurs Puma

  • Démarre (ou redémarre) le serveur Puma après la fin du déploiement

  • Ouvre un socket sur le serveur Puma à un emplacement spécifique de votre version.

Vous pouvez modifier toutes les options en fonction de vos besoins. Maintenant, Nginx doit être configuré. Créez + config / nginx.conf + dans le répertoire de votre projet Rails, et ajoutez-y ce qui suit (encore une fois, en le remplaçant par vos paramètres):

config / nginx.conf

upstream puma {
 server unix:///home//apps//shared/tmp/sockets/-puma.sock;
}

server {
 listen 80 default_server deferred;
 # server_name example.com;

 root /home//apps//current/public;
 access_log /home//apps//current/log/nginx.access.log;
 error_log /home//apps//current/log/nginx.error.log info;

 location ^~ /assets/ {
   gzip_static on;
   expires max;
   add_header Cache-Control public;
 }

 try_files $uri/index.html $uri @puma;
 location @puma {
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header Host $http_host;
   proxy_redirect off;

   proxy_pass http://puma;
 }

 error_page 500 502 503 504 /500.html;
 client_max_body_size 10M;
 keepalive_timeout 10;
}

Comme le fichier précédent, ce + nginx.conf + contient les valeurs par défaut qui fonctionnent avec les configurations de votre fichier + deploy.rb +. Cela écoute le trafic sur le port 80 et transmet la demande à votre socket Puma, écrit les journaux nginx dans la version 'actuelle' de votre application, compresse tous les actifs et les met en cache dans le navigateur avec une date d’expiration maximale, sert les pages HTML du public. dossier en tant que fichiers statiques, et définit les valeurs maximales par défaut + Taille du corps du client + et + Request Timeout +.

Étape 7 - Déploiement de votre application Rails

Si vous utilisez votre propre application Rails, validez les modifications que vous venez de faire et transmettez-les à distance de votre ordinateur local:

git add -A
git commit -m "Set up Puma, Nginx & Capistrano"
git push origin master

De nouveau, à partir de votre ordinateur local, effectuez votre premier déploiement:

cap production deploy:initial

Cela poussera votre application Rails sur le Droplet, installera tous les joyaux requis pour votre application et démarrera le serveur Web Puma. Cela peut prendre entre 5 et 15 minutes, selon le nombre de pierres précieuses utilisées par votre application. Vous verrez les messages de débogage au cours de ce processus.

Si tout se passe bien, nous sommes maintenant prêts à connecter votre serveur Web Puma au proxy inverse Nginx.

Sur la droplet, liez de manière reliée + nginx.conf au répertoire` + sites-enabled`:

sudo rm /etc/nginx/sites-enabled/default
sudo ln -nfs "/home//apps//current/config/nginx.conf" "/etc/nginx/sites-enabled/"

Redémarrez le service Nginx:

sudo service nginx restart

Vous devriez maintenant pouvoir pointer votre navigateur Web sur votre IP de serveur et voir votre application Rails en action!

Déploiements normaux

Chaque fois que vous apportez des modifications à votre application et que vous souhaitez déployer une nouvelle version sur le serveur, validez les modifications, transmettez à votre télécommande git comme d’habitude et exécutez la commande + deploy +:

git add -A
git commit -m "Deploy Message"
git push origin master
cap production deploy

Conclusion

D’accord, vous exécutez maintenant une application Rails sur votre Droplet avec Puma en tant que serveur Web, ainsi que Nginx et Capistrano configurés avec les paramètres de base. Vous devriez maintenant jeter un coup d’œil aux autres documents pouvant vous aider à optimiser vos configurations pour tirer le meilleur parti de votre application Rails:

Related