[RUBY] Einfache Bereitstellung mit Capistrano + AWS (EC2) + Rails

Einführung

Ich habe Capistrano verwendet, um meine eigene Rails-App bereitzustellen.

Grundsätzlich habe ich auf den folgenden Artikel verwiesen. (Capistrano-Ausgabe) Der höflichste AWS-Kommentar der Welt. Bis Sie die Rails-App mit EC2 zu AWS bringen

In diesem Artikel habe ich die mit Fehlern gefüllten Teile zusammen mit dem Referenzartikel zusammengefasst. Ich hoffe, Sie finden ihn hilfreich.

Zu erstellende Datei

Lokale Seite

Serverseitig (EC2)

Quellcode

Gemfile Liste der zu installierenden Edelsteine.

(local)Gemfile


group :development, :test do
 gem 'capistrano'
 gem 'capistrano-bundler'
 gem 'capistrano-rails'
 gem 'capistrano-rbenv'
end

group :production, :staging do
  gem 'unicorn'
end

In anderer Literatur wird möglicherweise das gem'capistrano3-Einhorn 'verwendet, es wird hier jedoch nicht für detaillierte Einstellungen verwendet.

Capfile

Dies ist die Einstellungsdatei für den gesamten Capistrano.

(local)Capfile


require 'capistrano/setup'
require 'capistrano/deploy'
require 'capistrano/rbenv'
require 'capistrano/bundler'
require 'capistrano/rails/assets'
require 'capistrano/rails/migrations'
#Legen Sie fest, dass die Datei gelesen werden soll, die die Aufgabe beschreibt. Geben Sie den Ort und die Erweiterung an.
Dir.glob('lib/capistrano/tasks/*.rake').each { |r| import r }

Im Referenzartikel lautet die letzte Zeile "~ / *. Rb", in der aktuellen Version ist Rake die Standardeinstellung. Verwenden Sie diese Option.

Beachten Sie, dass das Dateiformat von lib / capistrano / task / unicorn.rake, das Sie später erstellen werden, **. Rake ** ist. Lassen Sie uns das festgelegte Dateiformat auf dasselbe Dateiformat einstellen. (Ich bin hier ein wenig festgefahren.)

config/deploy/production.rb

Dies ist eine Datei, die die Einstellungen der Produktionsumgebung beschreibt.

(local)config/deploy/production.rb


#Beschreiben der IP-Adresse des EC2-Servers, des Benutzernamens für die Anmeldung am EC2-Server und der Rolle des Servers.
server '**.***.***.***', user: 'yuki', roles: %w[app db web]

#Beschreiben der wichtigsten Informationen für die SSH-Anmeldung beim Server, der bereitgestellt werden soll
set :ssh_options, keys: '~/.ssh/app_key_rsa'

config/deploy.rb

Beschreiben der Einstellungen, die sowohl für die Produktionsumgebung als auch für die Stading-Umgebung gelten.

(local)config/deploy.rb


#Feste Version von Capistrano
lock '3.14.1'

#Anwendungsname, der bereitgestellt werden soll
set :application, 'golfour'

#Git-Repository zum Klonen
set :repo_url, '[email protected]:app/app_aws.git'

#Der Zweig, der bereitgestellt werden soll. Die Standardeinstellung muss nicht Master sein.
set :branch, 'master'

#Das Verzeichnis, in dem bereitgestellt werden soll.
set :deploy_to, '/var/www/rails/app'

# secret_base_Zum Lesen des Schlüssels hinzugefügt
set :linked_files, %w[config/master.key]

#Eine Datei mit einem symbolischen Link.
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/settings.yml', '.env')

#Ein Ordner mit symbolischen Links.
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')

#Die Anzahl der zu behaltenden Versionen. Speichern Sie bis zu 5 Verlauf.
set :keep_releases, 5

#Ruby-Version
set :rbenv_ruby, '2.5.1'

#Die Ebene des auszugebenden Protokolls.
set :log_level, :debug

namespace :deploy do
  desc 'Restart application'
  task :restart do
    invoke 'unicorn:restart'
  end

  desc 'Create database'
  task :db_create do
    on roles(:db) do |_host|
      with rails_env: fetch(:rails_env) do
        within current_path do
          execute :bundle, :exec, :rake, 'db:create'
        end
      end
    end
  end

  desc 'Run seed'
  task :seed do
    on roles(:app) do
      with rails_env: fetch(:rails_env) do
        within current_path do
          execute :bundle, :exec, :rake, 'db:seed'
        end
      end
    end
  end

  after :publishing, :restart

  after :restart, :clear_cache do
    on roles(:web), in: :groups, limit: 3, wait: 10 do
    end
  end
end

Die folgenden zwei Codes werden zusätzlich zum Referenzartikel hinzugefügt.

Hier zu symbolischen Links (Dateien, die Sie nicht öffnen möchten, z. B. Einstellung in gitignore)

# secret_base_Zum Lesen des Schlüssels hinzugefügt
set :linked_files, %w[config/master.key]

#Eine Datei mit einem symbolischen Link.
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/settings.yml', '.env')

lib/capistrano/tasks/unicorn.rake

Eine Datei, die die Einhorn-Setup-Aufgabe beschreibt.

(local)lib/capistrano/tasks/unicorn.rake


#Geben Sie die Einhorn-PID-Datei und das Konfigurationsdateiverzeichnis an
namespace :unicorn do
  task :environment do
    set :unicorn_pid,    "#{current_path}/tmp/pids/unicorn.pid"
    set :unicorn_config, "#{current_path}/config/unicorn/production.rb"
  end

  #Methode, um Einhorn zu starten
  def start_unicorn
    within current_path do
      execute :bundle, :exec, :unicorn, "-c #{fetch(:unicorn_config)} -E #{fetch(:rails_env)} -D"
    end
  end

  #Methode, um Einhorn zu stoppen
  def stop_unicorn
    execute :kill, "-s QUIT $(< #{fetch(:unicorn_pid)})"
  end

  #Methode zum Neustart des Einhorns
  def reload_unicorn
    execute :kill, "-s USR2 $(< #{fetch(:unicorn_pid)})"
  end

  #Methode, um Unicron zu töten
  def force_stop_unicorn
    execute :kill, "$(< #{fetch(:unicorn_pid)})"
  end

  #Aufgabe, Einhorn zu starten
  desc 'Start unicorn server'
  task start: :environment do
    on roles(:app) do
      start_unicorn
    end
  end

  #Aufgabe, Einhorn zu stoppen
  desc 'Stop unicorn server gracefully'
  task stop: :environment do
    on roles(:app) do
      stop_unicorn
    end
  end

  #Wenn Unicorn bereits ausgeführt wird, starten Sie es neu. Wenn nicht, starten Sie die Task
  desc 'Restart unicorn server gracefully'
  task restart: :environment do
    on roles(:app) do
      if test("[ -f #{fetch(:unicorn_pid)} ]")
        reload_unicorn
      else
        start_unicorn
      end
    end
  end

  #Aufgabe, Einhorn zu töten
  desc 'Stop unicorn server immediately'
  task force_stop: :environment do
    on roles(:app) do
      force_stop_unicorn
    end
  end
end

Wie ich in Capfile erklärt habe, beachten Sie bitte, dass es sich um unicorn.rake handelt. Wenn es in .rb in Capfile festgelegt ist, ist es unicorn.rb.

config/unicorn/production.rb Dies ist die Einhorn-Konfigurationsdatei.

(local)config/unicorn/production.rb



#Anzahl der Arbeiter. Siehe unten
$worker = 2
#Entscheiden Sie, wie viele Sekunden vergangen sind, bevor Sie den Worker entfernen
$timeout = 30
#Beachten Sie, dass Ihr aktueller Anwendungsname angehängt ist.
$app_dir = '/var/www//rails/golfour/current'
#Geben Sie die Portnummer an, an der die Anforderung empfangen werden soll. Siehe unten
$listen = File.expand_path 'tmp/sockets/.unicorn.sock', $app_dir
#Verzeichnis der PID-Verwaltungsdatei
$pid = File.expand_path 'tmp/pids/unicorn.pid', $app_dir
#Verzeichnis der Dateien, die Fehlerprotokolle ausspucken
$std_log = File.expand_path 'log/unicorn.log', $app_dir

#Definiert, damit das oben Gesagte angewendet wird
worker_processes  $worker
working_directory $app_dir
stderr_path $std_log
stdout_path $std_log
timeout $timeout
listen  $listen
pid $pid

#Legen Sie fest, ob eine Hot-Bereitstellung erfolgen soll
preload_app true

#Definieren Sie, was vor der Gabelung zu tun ist. Siehe unten
before_fork do |server, _worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.connection.disconnect!
  old_pid = "#{server.config[:pid]}.oldbin"
  if old_pid != server.pid
    begin
      Process.kill 'QUIT', File.read(old_pid).to_i
    rescue Errno::ENOENT, Errno::ESRCH
    end
  end
end

#Definieren Sie, was nach der Gabelung zu tun ist. Siehe unten
after_fork do |_server, _worker|
  defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
end

shared/config/settings.yml

(server)shared/config/settings.yml


production:
  secret_key_base: jr934ugr89vwredvu9iqfj394vj9edfjcvnxii90wefjc9weiodjsc9o i09fiodjvcijdsjcwejdsciojdsxcjdkkdsv 
(#Fügen Sie die generierte Zufallszahl ein)

shared/config/database.yml

(server)shared/config/database.yml



default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>

development:
  <<: *default
  database: golfour_development
  username: yuki
  password: password
  host: db
  socket: /tmp/mysql.sock

test:
  <<: *default
  database: golfour_test
  username: yuki
  password: password
  host: db-test
  socket: /tmp/mysql.sock

production:
  <<: *default
  database: <%= ENV['DB_NAME'] %>
  username: <%= ENV['DB_USERNAME'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host: <%= ENV['DB_HOSTNAME'] %>

shared/.env

Beschreiben Sie hier die in datacbase.yml verwendeten Umgebungsvariablen.

(server)shared/.env


DB_NAME=*****
DB_USERNAME=*****
DB_PASSWORD=*****
DB_HOSTNAME=*****

/etc/nginx/conf.d/app.conf

conf:(server)/etc/nginx/conf.d/app.conf


#Verzeichniseinstellungen für verschiedene Protokolle
  error_log  /var/www/rails/mumu/current/log/nginx.error.log;
  access_log /var/www/rails/mumu/current/log/nginx.access.log;
#Maximale Kapazität zum Empfangen der Verarbeitung
  client_max_body_size 2G;
  upstream app_server {
#Einhorn-Sockelpfad zum Arbeiten
    server unix:/var/www/rails/mumu/current/tmp/sockets/.unicorn.sock fail_timeout=0;
  }
  server {
    listen 80;
    server_name 127.0.0.1; #Ändern Sie Ihre eigene IP-Adresse!
#Wartezeit für die nächste Anfrage (Sekunden)
    keepalive_timeout 5;
#Verzeichnis zum Lesen statischer Dateien
    root /var/www/rails/mumu/current/public;
#Cache-Verzeichnis
    try_files $uri/index.html $uri.html $uri @app;
    location @app {
      # HTTP headers
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;
      proxy_pass http://app_server;
    }
#Wo soll die Fehlerseite platziert werden?
    error_page 500 502 503 504 /500.html;
    location = /500.html {
      root /var/www/rails/mumu/current/public;
    }
  }

Befehl bereitstellen

bundle exec cap production deploy

Fehlerliste

Mangel an Gedächtnis

Tritt nach dem Ausführen einer Bereitstellung auf. Es wurde durch unzureichenden Speicher von EC2 verursacht.

console


virtual memory exhausted

Lösung: Erstellen Sie eine Auslagerungsdatei

Dies ist eine Methode zum Verstärken des Speichers, so dass er verwendet werden kann, indem der nicht verwendete Speicher vorübergehend an einen anderen Ort verschoben wird. Wenn Sie auf den folgenden Artikel verweisen, können Sie ihn problemlos implementieren.

Referenz: Was ist eine Auslagerungsdatei [Rails] Bereitstellen auf EC2 mit Capistrano: Fehlerbehebung bei unzureichendem virtuellen Speicher von EC2

Missing secret_key_base for 'production' environment

Dies ist auch ein Fehler, der beim Ausführen der Bereitstellung aufgetreten ist.

Die Ursache war, dass die Datei master.key fehlte. Die secret_key_base wird zunächst in der Datei credentials.yml.enc aufgeführt. Diese Datei war jedoch verschlüsselt und ich brauchte master.key, um sie zu lesen, aber ich bekam eine Fehlermeldung, weil ich sie nicht hatte.

Lösung

・ Erstellen Sie shared / master.key

Auf diese Weise verschwand der Fehler.

Referenz: Die automatische Bereitstellung mit Capistrano führt zu dem Fehler "Fehlende secret_key_base für 'Produktions'-Umgebung"

Recommended Posts

Einfache Bereitstellung mit Capistrano + AWS (EC2) + Rails
Ich habe versucht, die automatische Bereitstellung mit CircleCI + Capistrano + AWS (EC2) + Rails durchzuführen
[Rails] Nginx, Puma-Umgebungsbereitstellung und Serverstudie [AWS EC2]
Rails auf EC2 starten (manuelle Bereitstellung)
Rails Die AWS-Bereitstellung wird nicht berücksichtigt
[EC2 / Vue / Rails] EC2-Bereitstellungsverfahren für Vue + Rails
[Rails] Aufbau einer AWS EC2-Instanzumgebung
[Rails] Zusammenfassung der AWS-Bereitstellungsfehler
Verwenden von Java mit AWS Lambda-Implementierung-Stop / Launch EC2
[Rails] Bildbeitrag von CarrierWave [AWS EC2]
[AWS] Veröffentlichen Sie die Rails-App mit Nginx + Puma
Stellen Sie Rails mit AWS Copilot für ECS Fargate bereit
Rezept für die Bereitstellung von Rails-Apps unter AWS EC2
Erstellen Sie eine EC-Site mit Rails5 ⑤ ~ Kundenmodell ~
Erstellen Sie eine EC-Site mit Rails 5 ⑩ ~ Erstellen Sie eine Bestellfunktion ~
Mit Rails + Docker einfach Hallo Welt anzuzeigen
Erstellen einer EC-Site mit Rails 5 ⑨ ~ Erstellen einer Warenkorbfunktion ~
Erstellen Sie eine EC-Site mit Rails5 ④ ~ Kopf- und Fußzeile ~
Erstellen Sie eine EC-Site mit Rails5 seed ~ Startdateneingabe ~
Starten Sie EC2 Rails
[Rails 6] Laufzeitfehler mit $ Rails s
Rails Heroku-Bereitstellungsverfahren
Gerät mit Schienen handhaben
[Rails] Lernen mit Rails Tutorial
Stellen Sie RAILS auf EC2 bereit
[Schienen] Heroku-Bereitstellungsablauf
[Schienen] Test mit RSpec
[Rails] Entwicklung mit MySQL
Unterstützt Mehrsprachigkeit mit Rails!
Erstellen des ersten LINEbot mit AWS Cloud9 (Rails + Heroku-Bereitstellung)
Was tun, wenn während der automatischen Bereitstellung auf EC2 mit Capistrano ein SSH-Schlüsselauthentifizierungsfehler auftritt?