Bereitstellen einer Rails-App unter Ubuntu 14.04 mit Capistrano, Nginx und Puma

Einführung

Rails ist ein in Ruby geschriebenes Open Source-Webanwendungsframework. Es folgt der "Convention over Configuration" -Philosophie und geht davon aus, dass es die "beste" Art gibt, Dinge zu tun. Auf diese Weise können Sie weniger Code schreiben und gleichzeitig mehr erreichen, ohne endlose Konfigurationsdateien durchlaufen zu müssen.

Nginx ist ein Hochleistungs-HTTP-Server, ein Reverse-Proxy und ein Load-Balancer, der für seine Fokussierung auf Parallelität, Stabilität, Skalierbarkeit und geringen Speicherverbrauch bekannt ist. Wie Nginx ist Puma ein weiterer extrem schneller und gleichzeitiger Webserver mit sehr geringem Speicherbedarf, der jedoch für Ruby-Webanwendungen entwickelt wurde.

Capistrano ist ein Tool zur Remote-Server-Automatisierung, das sich hauptsächlich auf Ruby-Webanwendungen konzentriert. Es wird verwendet, um Web-Apps zuverlässig auf einer beliebigen Anzahl von Remotecomputern bereitzustellen, indem beliebige Workflows über SSH skriptgesteuert werden und allgemeine Aufgaben wie das Vorkompilieren von Assets und das Neustarten des Rails-Servers automatisiert werden.

In diesem Tutorial installieren wir Ruby und Nginx auf einem DigitalOcean Ubuntu Droplet und konfigurieren Puma und Capistrano in unserer Web-App. Nginx wird verwendet, um Client-Anfragen zu erfassen und sie an den Puma-Webserver weiterzuleiten, auf dem Rails ausgeführt wird. Wir werden Capistrano verwenden, um allgemeine Bereitstellungsaufgaben zu automatisieren. Jedes Mal, wenn wir eine neue Version unserer Rails-App auf dem Server bereitstellen müssen, können wir dies mit ein paar einfachen Befehlen tun.

Voraussetzungen

Um diesem Tutorial folgen zu können, müssen Sie Folgendes haben:

Optional können Sie aus Sicherheitsgründen die Root-Anmeldung über SSH deaktivieren und die SSH-Portnummer ändern, wie unter https://www.digitalocean.com/community/tutorials/initial-server-setup-with-ubuntu-14-04 [beschrieben. Erstes Server-Setup mit Ubuntu 14.04].

Alle Befehle in diesem Tutorial sollten als "+ deploy " - Benutzer ausgeführt werden. Wenn für den Befehl root-Zugriff erforderlich ist, wird vor ` sudo +` angezeigt.

Schritt 1 - Nginx installieren

Sobald der VPS sicher ist, können wir mit der Installation von Paketen beginnen. Aktualisieren Sie die Paketindexdateien:

sudo apt-get update

Dann installieren Sie Nginx:

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

Schritt 2 - Installieren von Datenbanken

Installieren Sie die Datenbank, die Sie in Ihrer Rails-App verwenden werden. Da Sie aus zahlreichen Datenbanken auswählen können, werden diese in diesem Handbuch nicht behandelt. Hier finden Sie Anweisungen für die wichtigsten:

Beachten Sie auch Folgendes:

Schritt 3 - Installieren von RVM und Ruby

Wir werden Ruby nicht direkt installieren. Stattdessen verwenden wir einen Ruby-Versionsmanager. Es gibt viele davon zur Auswahl (rbenv, chruby usw.), aber wir werden RVM für dieses Tutorial verwenden. Mit RVM können Sie auf einfache Weise mehrere Rubine auf demselben System installieren und verwalten und den richtigen Rubin entsprechend Ihrer App verwenden. Dies erleichtert das Leben erheblich, wenn Sie Ihre Rails-App aktualisieren müssen, um einen neueren Rubin zu verwenden.

Vor der Installation von RVM müssen Sie den RVM-GPG-Schlüssel importieren:

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

Dann installieren Sie RVM, um unsere Rubies zu verwalten:

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

Dieser Befehl verwendet "+ curl", um das RVM-Installationsskript von "+ https: // get.rvm.io" herunterzuladen. Die Option + -sSL + besteht aus drei Flags:

  • "+ -s +" weist Curl an, die Datei im "Silent Mode" herunterzuladen.

  • + -S + weist curl an, eine Fehlermeldung anzuzeigen, wenn dies fehlschlägt

  • + -L + weist curl an, alle HTTP-Weiterleitungen zu befolgen, während das Installationsskript abgerufen wird

Nach dem Herunterladen wird das Skript an "+ bash" weitergeleitet. Die Option "+ -s " übergibt " stable +" als Argument an das RVM-Installationsskript, um die stabile Version von RVM herunterzuladen und zu installieren.

Wir müssen das RVM-Skript (als Funktion) laden, damit wir es verwenden können. Anschließend müssen wir den Befehl "+ requirements +" ausführen, um die erforderlichen Abhängigkeiten und Dateien automatisch zu installieren, damit RVM und Ruby ordnungsgemäß funktionieren:

source ~/.rvm/scripts/rvm
rvm requirements

Wir können jetzt den Ruby unserer Wahl installieren. Wir werden den neuesten "+ Ruby 2.2.1 +" (zum Zeitpunkt des Schreibens) als unseren Standard-Ruby installieren:

rvm install 2.2.1
rvm use 2.2.1 --default

Schritt 4 - Rails und Bundler installieren

Sobald Ruby eingerichtet ist, können wir mit der Installation von Rubygems beginnen. Wir beginnen mit der Installation des Rails-Gems, mit dem Ihre Rails-Anwendung ausgeführt werden kann, und installieren dann "+ bundler ", das das " Gemfile +" Ihrer App lesen und automatisch alle erforderlichen Gems installieren kann.

So installieren Sie Rails und Bundler:

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

Es wurden drei Flaggen verwendet:

  • + -V + (Ausführliche Ausgabe): Gibt detaillierte Informationen zur Installation von Gem aus

  • + - no-ri + - (Überspringt die Ri-Dokumentation): Ri Docs wird nicht installiert, wodurch Platz gespart und die Installation beschleunigt wird

  • + - no-rdoc + - (Überspringt RDocs): RDocs werden nicht installiert, wodurch Speicherplatz gespart und die Installation beschleunigt wird

Schritt 5 - SSH-Schlüssel einrichten

Da wir reibungslose Bereitstellungen einrichten möchten, verwenden wir SSH-Schlüssel für die Autorisierung. Schütteln Sie zuerst die Hand mit GitHub, Bitbucket oder einer anderen Git-Fernbedienung, auf der sich die Codebasis für Ihre Rails-App befindet:

Machen Sie sich keine Sorgen, wenn Sie die Meldung "+ Permission denied (publickey) +" erhalten. Generieren Sie jetzt einen SSH-Schlüssel (ein Public / Private Key Pair) für Ihren Server:

ssh-keygen -t rsa

Fügen Sie den neu erstellten öffentlichen Schlüssel (+ ~ / .ssh / id_rsa.pub +) zu den Bereitstellungsschlüsseln Ihres Repositorys hinzu:

Wenn alle Schritte korrekt ausgeführt wurden, sollten Sie jetzt in der Lage sein, Ihr Git-Repository (über das SSH-Protokoll, nicht über HTTP) zu klonen, ohne Ihr Passwort einzugeben:

git clone

Wenn Sie eine Beispiel-App zum Testen benötigen, können Sie die folgende, speziell für dieses Tutorial erstellte Test-App verwenden: Sample Rails App on GitHub

Der Befehl + git clone + erstellt ein Verzeichnis mit demselben Namen wie Ihre App. Beispielsweise wird ein Verzeichnis mit dem Namen "+ testapp_rails +" erstellt.

Wir klonen nur, um zu überprüfen, ob unsere Bereitstellungsschlüssel funktionieren. Wir müssen unser Repository nicht jedes Mal klonen oder abrufen, wenn wir neue Änderungen vornehmen. Wir lassen Capistrano das alles für uns erledigen. Sie können dieses geklonte Verzeichnis jetzt löschen, wenn Sie möchten.

Öffnen Sie ein Terminal auf Ihrem lokalen Computer. Wenn Sie keinen SSH-Schlüssel für Ihren lokalen Computer haben, erstellen Sie ebenfalls einen. In Ihrer lokalen Terminalsitzung:

ssh-keygen -t rsa

Fügen Sie Ihren lokalen SSH-Schlüssel zur Authorized Keys-Datei Ihres Droplets hinzu (denken Sie daran, die Portnummer durch Ihre benutzerdefinierte Portnummer zu ersetzen):

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

Schritt 6 - Hinzufügen von Bereitstellungskonfigurationen in der Rails-App

Erstellen Sie auf Ihrem lokalen Computer Konfigurationsdateien für Nginx und Capistrano in Ihrer Rails-Anwendung. Beginnen Sie mit dem Hinzufügen dieser Zeilen zum + Gemfile + in der Rails-App:

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'

Verwenden Sie "+ bundler ", um die Edelsteine ​​zu installieren, die Sie gerade in Ihrem " Gemfile +" angegeben haben. Geben Sie den folgenden Befehl ein, um Ihre Rails-App zu bündeln:

bundle

Führen Sie nach dem Bündeln den folgenden Befehl aus, um Capistrano zu konfigurieren:

cap install

Dadurch wird Folgendes erstellt:

  • + Capfile + im Stammverzeichnis Ihrer Rails-App

  • + deploy.rb + Datei im + config + Verzeichnis

  • "+ deploy" -Verzeichnis im "+ config" -Verzeichnis

Ersetzen Sie den Inhalt Ihres + Capfile + durch den folgenden:

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 }

Diese + Capfile + lädt einige vordefinierte Aufgaben in Ihre Capistrano-Konfigurationsdateien, um Ihre Bereitstellungen problemlos zu gestalten, wie zum Beispiel automatisch:

  • Auswahl des richtigen Rubins

  • Assets vorkompilieren

  • Klonen Sie Ihr Git-Repository an den richtigen Ort

  • Installieren neuer Abhängigkeiten, wenn sich Ihr Gemfile geändert hat

Ersetzen Sie den Inhalt von "+ config / deploy.rb +" durch die folgenden, indem Sie die rot markierten Felder mit Ihren App- und Droplet-Parametern aktualisieren:

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

Diese Datei + deploy.rb + enthält einige vernünftige Standardeinstellungen, die sofort einsatzbereit sind, um Sie bei der Verwaltung Ihrer App-Releases zu unterstützen und einige Aufgaben automatisch auszuführen, wenn Sie eine Bereitstellung vornehmen:

  • Verwendet "+ production +" als Standardumgebung für Ihre Rails-App

  • Verwaltet automatisch mehrere Versionen Ihrer App

  • Verwendet optimierte SSH-Optionen

  • Überprüft, ob Ihre Git-Fernbedienungen auf dem neuesten Stand sind

  • Verwaltet die Protokolle Ihrer App

  • Lädt die App im Speicher vor, wenn Sie Puma-Mitarbeiter verwalten

  • Startet (oder startet) den Puma-Server nach Abschluss einer Bereitstellung neu

  • Öffnet einen Socket zum Puma-Server an einem bestimmten Ort in Ihrer Version

Sie können alle Optionen entsprechend Ihren Anforderungen ändern. Nun muss Nginx konfiguriert werden. Erstellen Sie "+ config / nginx.conf +" in Ihrem Rails-Projektverzeichnis und fügen Sie Folgendes hinzu (ebenfalls durch Ihre Parameter ersetzt):

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;
}

Wie die vorherige Datei enthält auch diese Datei "+ nginx.conf " Standardeinstellungen, die bei den Konfigurationen in Ihrer Datei " deploy.rb " sofort verwendet werden können. Dieser überwacht den Datenverkehr auf Port 80 und leitet die Anforderung an Ihren Puma-Socket weiter. Er schreibt Nginx-Protokolle in die 'aktuelle' Version Ihrer App, komprimiert alle Assets und speichert sie mit maximalem Ablauf im Browser zwischen, bedient die HTML-Seiten in der Öffentlichkeit Ordner als statische Dateien und legt das Standardmaximum für " Client Body Size " und " Request Timeout +" fest.

Schritt 7 - Bereitstellen Ihrer Rails-Anwendung

Wenn Sie Ihre eigene Rails-App verwenden, übernehmen Sie die Änderungen, die Sie gerade vorgenommen haben, und übertragen Sie sie von Ihrem lokalen Computer aus:

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

Führen Sie auf Ihrem lokalen Computer erneut die erste Bereitstellung durch:

cap production deploy:initial

Dadurch wird Ihre Rails-App auf das Droplet übertragen, alle erforderlichen Juwelen für Ihre App installiert und der Puma-Webserver gestartet. Dies kann zwischen 5 und 15 Minuten dauern, abhängig von der Anzahl der Edelsteine, die Ihre App verwendet. Während dieses Vorgangs werden Debug-Meldungen angezeigt.

Wenn alles reibungslos funktioniert, können wir Ihren Puma-Webserver jetzt mit dem Nginx-Reverse-Proxy verbinden.

Verknüpfen Sie auf dem Droplet die + nginx.conf mit dem` + sites-enabled` Verzeichnis:

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

Starten Sie den Nginx-Dienst neu:

sudo service nginx restart

Sie sollten nun in der Lage sein, Ihren Webbrowser auf Ihre Server-IP zu verweisen und Ihre Rails-App in Aktion zu sehen!

Normale Bereitstellungen

Wann immer Sie Änderungen an Ihrer App vornehmen und eine neue Version auf dem Server bereitstellen möchten, übernehmen Sie die Änderungen, übertragen Sie sie wie gewohnt auf Ihre Git-Fernbedienung und führen Sie den Befehl + deploy + aus:

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

Fazit

Okay, jetzt würden Sie eine Rails-App auf Ihrem Droplet ausführen, wobei Puma als Webserver sowie Nginx und Capistrano mit den Grundeinstellungen konfiguriert sind. Sie sollten sich jetzt andere Dokumente ansehen, mit denen Sie Ihre Konfigurationen optimieren können, um das Maximum aus Ihrer Rails-Anwendung herauszuholen:

Related