[RUBY] Ich habe versucht, die automatische Bereitstellung mit CircleCI + Capistrano + AWS (EC2) + Rails durchzuführen

Einführung

Neulich habe ich Capistrano verwendet, um mein eigenes Portfolio auf AWS bereitzustellen, und habe versucht, es automatisch in Kombination mit CircleCI bereitzustellen.

Es ist ungefähr 4 Monate her, seit ich angefangen habe, Programmieren zu lernen, aber ich konnte es in ungefähr einer Woche implementieren.

** Ich möchte CircleCI / CD in mein Portfolio aufnehmen! Ich hoffe, es wird für diejenigen hilfreich sein, die ** sagen.

Wenn Sie Vorschläge haben, würde ich mich freuen, wenn Sie einen Kommentar abgeben könnten.

Annahme

--Rails App erstellt --CIrcleCI hat bereits automatisierte Tests eingeführt

CircleCI und Capistrano sind in einem separaten Artikel zusammengefasst.

Führen Sie SystemSpec (RSpec) und Rubocop auf CircleCI aus) Einfache Bereitstellung mit Capistrano + AWS (EC2) + Rails

Verfahren

Sie müssen mehrere Einstellungen vornehmen, also machen wir es Schritt für Schritt.

  1. Registrieren Sie den privaten ssh-Schlüssel in CircleCI, damit Sie auf die EC2-Instanz von AWS zugreifen können.
  2. Legen Sie Umgebungsvariablen in der CircleCI-Konsole fest
  3. Bearbeiten Sie .circleci / config.yml, um sicherzustellen, dass Sie eine SSH-Verbindung haben
  4. Führen Sie die Capistrano-Bereitstellung aus, wenn Sie sie an Github senden
  5. Stellen Sie die Capistrano-Bereitstellung so ein, dass sie nur ausgeführt wird, wenn der Github-Zweig Master ist

1. Registrieren Sie den privaten SSH-Schlüssel in CircleCI

Nachdem Sie das Projekt ausgewählt haben, das auf der CIrcleCI-Benutzeroberfläche verwendet werden soll, wählen Sie "Projekteinstellungen >> SSH-SCHLÜSSEL >> SSH-Schlüssel hinzufügen" und geben Sie den "Hostnamen" und den "privaten Schlüssel" ein.

Host Name beschreibt die Domain oder IP. Ich habe appname.com geschrieben, weil ich meine eigene Domain hatte.

Privater Schlüssel beschreibt den Inhalt des privaten Schlüssels, Hier sind jedoch zwei Punkte zu beachten, daher werde ich sie erläutern. (Ich blieb hier für ein paar Tage stecken ...)

Vorsichtsmaßnahmen bei der Registrierung eines privaten Schlüssels

1. ** Beschreiben Sie den Inhalt des privaten Schlüssels, der bei der lokalen Anmeldung bei EC2 verwendet wird **

Wenn Sie Ihre eigene App erstellen und für AWS bereitstellen, sollten Sie über mehrere private Schlüssel verfügen, z. B. den AWS-Zugriffsschlüssel und den privaten Schlüssel für die Verknüpfung mit Github. Daher fragen Sie sich möglicherweise, welchen privaten Schlüssel Sie verwenden sollen. (Ich war ratlos ...)

Der erforderliche Schlüssel ist ** der private Schlüssel, mit dem Sie sich lokal bei EC2 anmelden **.

Wenn der private Schlüssel in ~ / .ssh gespeichert ist, überprüfen Sie die Liste der privaten Schlüssel mit dem folgenden Befehl.

(local)


[~]$ cd ~/.ssh
[.ssh]$ ls

In meinem Fall verwende ich den folgenden Befehl, wenn ich mich lokal bei EC2 anmelde.

(local)


[~]$ ssh appname_rsa

In diesem Fall können Sie den Inhalt des privaten Schlüssels kopieren, indem Sie den folgenden Befehl auf dem Terminal eingeben.

(local)


[~]$ pbcopy < ~/.ssh/appname_rsa

Fügen Sie den kopierten Inhalt in "Privater Schlüssel" ein.

Und wenn der Anfang der Beschreibung "----- BEGIN RSA PRIVATE KEY -----" lautet, ist dies in Ordnung ist.

Wenn es sich um ----- BEGIN OPENSSH PRIVATE KEY ----- handelt, fahren Sie mit der nächsten Notiz fort.

2. ** Das Dateiformat des privaten Schlüssels muss das PEM-Format sein **

Es gibt zwei SSH-Schlüsseldateiformate, "OPENSSH" und "PEM", und das in CircleCI festzulegende SSH-Schlüsseldateiformat wird als "PEM" angegeben.

Sie können am Anfang des Inhalts des privaten Schlüssels erkennen, wie das Dateiformat unterschieden werden soll. Für OPENSSH:----- BEGIN OPENSSH PRIVATE KEY ----- Für PEM:----- BEGIN RSA PRIVATE KEY -----

Wenn der private Schlüssel, mit dem Sie sich lokal bei EC2 anmelden, im Format "OPENSSH" vorliegt, müssen Sie einen privaten Schlüssel im Format "PEM" erstellen und festlegen, damit Sie sich bei EC2 anmelden können.

Ich habe es im OPENSSH-Format erstellt und den privaten Schlüssel neu erstellt, indem ich die folgenden Schritte ausgeführt habe.

So erstellen Sie einen privaten Schlüssel im PEM-Format und legen die Anmeldung fest

Generieren Sie zunächst den Schlüssel lokal.

(local)


[~]$ cd .ssh
[.ssh]$ ssh-keygen -m pem
(#Erstellen Sie einen öffentlichen Schlüssel)
-----------------------------
Enter file in which to save the key ():appname_rsa 
(#Geben Sie hier den Namen der Datei ein)
Enter passphrase (empty for no passphrase): 
(#Treten Sie ein, wie es ist, ohne etwas zu tun)
Enter same passphrase again: 
(#Treten Sie ein, wie es ist, ohne etwas zu tun)
-----------------------------

[.ssh]$ ls
#「appname_rsa "und" appname_rsa.Bestätigen Sie, dass "Pub" generiert wurde
[.ssh]$ cat appname_rsa.pub
(#Geben Sie den Inhalt des Schlüssels am Terminal aus → ssh-rsa~~~~Kopieren Sie nach lokal)

Legen Sie als Nächstes den zuvor auf der Serverseite (EC2) erstellten öffentlichen Schlüssel fest.

(server)


[yuki|~]$ mkdir .ssh
[yuki|~]$ chmod 700 .ssh
[yuki|~]$ cd .ssh
[yuki|.ssh]$ vim authorized_keys
(#vim öffnet sich)
-----------------------------
ssh-rsa sdfjerijgviodsjcIKJKJSDFJWIRJGIUVSDJFKCNZKXVNJSKDNVMJKNSFUIEJSDFNCJSKDNVJKDSNVJNVJKDSNVJKNXCMXCNMXNVMDSXCKLMKDLSMVKSDLMVKDSLMVKLCA [email protected]
(#Fügen Sie den Inhalt des zuvor kopierten Schlüssels ein)
-----------------------------
[yuki|.ssh]$ chmod 600 authorized_keys
[yuki|.ssh]$ exit
[ec2-user|~]$ exit

Wenn Sie fertig sind, kehren Sie zu Ihren Einheimischen zurück und legen Sie fest, welche Kommunikation für die Authentifizierung verwendet werden soll.

(local)


[~]$ cd .ssh
[.ssh]$ vim config
(#Starten Sie Vim und bearbeiten Sie die Konfigurationsdatei)

#Fügen Sie Folgendes hinzu
Host appname_rsa
Hostname EC2 Elastic IP(#Entsprechend Ihren Einstellungen)
  Port 22
  User yuki (#EC2-Benutzername)
  IdentityFile ~/.ssh/appname_rsa (#Private Schlüsseleinstellung)
-----------------------------

Dies ermöglicht die SSH-Kommunikation unter Verwendung des privaten Schlüssels im PEM-Format. Geben Sie den folgenden Befehl lokal ein und versuchen Sie, sich tatsächlich anzumelden.

(local)


ssh appname_rsa

Wenn Sie sich anmelden können, ist die Einstellung abgeschlossen.

Wenn Sie dies bisher getan haben, lesen Sie Anmerkung 1 und beschreiben Sie den Inhalt des privaten Schlüssels im Private Key von CircleCI und registrieren Sie ihn.

2. Legen Sie Umgebungsvariablen in der CircleCI-Konsole fest

CircleCI wird basierend auf ** Github-Quellcode ** bereitgestellt. Daher können Dateien, die nicht wie in gitignore beschrieben auf Github übertragen werden, nicht erkannt werden.

CircleCI verfügt über eine Funktion zum Verwalten solcher Dateien, indem es als Umgebungsvariable auf der Konsole festgelegt wird. Verwenden Sie es daher.

Gehen Sie in den CircleCI-Projekteinstellungen zur Seite "Umgebungsvariablen" und wählen Sie "Variable hinzufügen".

Stellen Sie dann zwei Umgebungsvariablen ein.

Name:'RAILS_MASTER_KEY' Value:Lokal'master.key'Beschreiben Sie den Inhalt.

Name:'PRODUCTION_SSH_KEY' Value:'~/.ssh/appname_rsa_xxxxxxxxxxxxxxx~'

Schreiben Sie nach appname_rsa_ des Werts von PRODUCTION_SSH_KEY die Zeichenfolge ohne: von Fingerabdrücken, die neben dem zuvor registrierten Hostnamen des SSH-Schlüssels beschrieben sind.

Richten Sie als Nächstes die SSH-Verbindung von Capistrano in der Produktionsumgebung ein. Hier schreiben wir config / deploy / Production.rb mit PRODUCTION_SSH_KEY.

config/deploy/production.rb


server 'Beschreiben Sie die elastische IP von EC2', user: 'yuki', roles: %w[app db web]

#SSH-Verbindung unter Verwendung von Umgebungsvariablen, die in der CircleCI-GUI festgelegt wurden
set :ssh_options, {
  keys: [ENV.fetch('PRODUCTION_SSH_KEY').to_s],
  forward_agent: true,
  auth_methods: %w[publickey]
}

3. Vergewissern Sie sich, dass eine SSH-Kommunikation möglich ist

Fügen Sie die folgende Beschreibung zu .circleci / config.yml hinzu. In Fingerprints steht es neben dem Hostnamen des zuvor registrierten SSH-Schlüssels. Kopieren Sie ihn daher.

yml:.circleci/config.yml


     - add_ssh_keys:
          fingerprints:
            - "XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX"

Dann auf Github drücken.

Wenn es in der Konsole auf der CircleCI-Seite für den Prozess "Installieren zusätzlicher SSH-Schlüssel" ausgeführt werden kann

Installed key XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX

Sollte angezeigt werden.

4. Führen Sie Capistrano aus, wenn Sie zu Github drücken

Schreiben Sie Folgendes in .circleci / config.yml.

yml:.circleci/config.yml


      - add_ssh_keys:
          fingerprints:
            - "XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX"

      - deploy:
          name: Capistrano deploy
          command: bundle exec cap production deploy

Lass uns zu Github gehen. Sollte in der Lage sein, automatisch bereitzustellen! ... ist.

5. Stellen Sie die Capistrano-Bereitstellung so ein, dass sie nur ausgeführt wird, wenn der Github-Zweig Master ist

Fügen Sie "Filter" am Ende der Workflows von "circleci / config.yml" hinzu.

yml:.circleci/config.yml


# build,test,Beschreiben der Bereitstellung.
・
・
・

workflows:
  version: 2
  build_accept_deploy:
    jobs:
      - build
      - test:
          requires:
            - build
      - deploy:
          requires:
            - test
          filters:
            branches:
              only: master

Jetzt wird die Capistrano-Bereitstellung nur ausgeführt, wenn der Github-Zweig Master ist!

Zusammenfassung

Ich bin ziemlich viel über den SSH-Zertifizierungsteil gestolpert, lol.

Ich hoffe, es hilft denen, die ähnlich stolpern ☺️

Schließlich werde ich den Quellcode und die Referenzartikel von CircleCI und Capistrano als Referenz veröffentlichen.

Quellcode

yml:.circleci/config.yml


version: 2.1

orbs:
  ruby: circleci/[email protected]

jobs:
  build:
    docker:
      - image: circleci/ruby:2.5.1-node-browsers
        environment:
          BUNDLER_VERSION: 2.1.4
    steps:
      - checkout
      - ruby/install-deps

  test:
    parallelism: 3
    docker:
      - image: circleci/ruby:2.5.1-node-browsers
        environment:
          DB_HOST: 127.0.0.1
          RAILS_ENV: test
          BUNDLER_VERSION: 2.1.4
      - image: circleci/mysql:8.0
        command: --default-authentication-plugin=mysql_native_password
        environment:
          MYSQL_ALLOW_EMPTY_PASSWORD: 'true'
          MYSQL_ROOT_HOST: '%'
    steps:
      - checkout
      - ruby/install-deps
      - run: mv config/database.yml.ci config/database.yml 
      - run:
          name: Wait for DB
          command: dockerize -wait tcp://localhost:3306 -timeout 1m
      - run: bundle exec rake db:create
      - run: bundle exec rake db:schema:load
      # Run rspec in parallel
      - ruby/rspec-test
      - ruby/rubocop-check

  deploy:
    docker:
      - image: circleci/ruby:2.5.1-node-browsers
        environment:
          BUNDLER_VERSION: 2.1.4
    steps:
      - checkout
      - ruby/install-deps
      - add_ssh_keys:
          fingerprints: "XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX"
      - deploy:
          name: Capistrano deploy
          command: bundle exec cap production deploy
  

workflows:
  version: 2
  build_accept_deploy:
    jobs:
      - build
      - test:
          requires:
            - build
      - deploy:
          requires:
            - test
          filters:
            branches:
              only: master

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]:xxxxxx/xxxxxx.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/appname'

# 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

config/deploy/production.rb


server 'EC2 Elastic IP', user: 'yuki', roles: %w[app db web]

#SSH-Verbindung unter Verwendung von Umgebungsvariablen, die in der CircleCI-GUI festgelegt wurden
set :ssh_options, {
  keys: [ENV.fetch('PRODUCTION_SSH_KEY').to_s],
  forward_agent: true,
  auth_methods: %w[publickey]
}

Referenzartikel

[Circle CI] Rails5.2 / Capistrano / Automatische Bereitstellung in AWS durch CICD-Umgebung Bereitstellung mit CircleCI automatisieren

Recommended Posts

Ich habe versucht, die automatische Bereitstellung mit CircleCI + Capistrano + AWS (EC2) + Rails durchzuführen
Einfache Bereitstellung mit Capistrano + AWS (EC2) + Rails
Ich habe versucht, ein Portfolio mit AWS, Docker, CircleCI, Laravel [mit Referenzlink] zu erstellen.
[Rails] Nginx, Puma-Umgebungsbereitstellung und Serverstudie [AWS EC2]
Ich habe versucht, das Ruby on Rails-Plugin mit vim-plug zu installieren
Ich habe DI mit Ruby versucht
[Rails] Ich habe versucht, eine Mini-App mit FullCalendar zu erstellen
Ich habe Rails Anfänger ausprobiert [Kapitel 1]
[Rails] Ich habe versucht, die Stapelverarbeitung mit der Rake-Task zu implementieren
Ich habe Rails Anfänger ausprobiert [Kapitel 2]
Ich habe UPSERT mit PostgreSQL ausprobiert.
Ich habe BIND mit Docker ausprobiert
Was tun, wenn während der automatischen Bereitstellung auf EC2 mit Capistrano ein SSH-Schlüsselauthentifizierungsfehler auftritt?
Ich habe versucht, die Bildvorschau mit Rails / jQuery zu implementieren
Ich habe versucht, mit Rails eine Gruppenfunktion (Bulletin Board) zu erstellen
Ich habe versucht, JOOQ mit Gradle zu verwenden
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, UDP mit Java zu kommunizieren
[Rails] Ich habe versucht, die Anwendung zu löschen
Rails Die AWS-Bereitstellung wird nicht berücksichtigt
[AWS SDK] Automatisches EC2-Konstruktionsskript
Ich habe GraphQL mit Spring Boot ausprobiert
Ich habe Flyway mit Spring Boot ausprobiert
[EC2 / Vue / Rails] EC2-Bereitstellungsverfahren für Vue + Rails
[Rails] Aufbau einer AWS EC2-Instanzumgebung
Ich habe versucht, Slim mit Scaffold anzupassen
[Rails] Zusammenfassung der AWS-Bereitstellungsfehler
Ich habe versucht, ein automatisches Backup mit angenehmem + PostgreSQL + SSL + Docker zu erstellen
[Circle CI] Ich war süchtig nach dem automatischen Test von Circle CI (Rails + MySQL) [Memo]
Ich habe versucht, den Zugriff von Lambda → Athena mit AWS X-Ray zu visualisieren
[AWS] So stellen Sie eine mit Rails 6 erstellte Webanwendung mithilfe von CircleCI (1) -Vorbereitung automatisch für ECR / ECS bereit [Containerbereitstellung]
Ich habe versucht, Realm mit Swift UI zu verwenden
Ich habe versucht, mit Web Assembly zu beginnen
Ich habe versucht, Scalar DL mit Docker zu verwenden
Ich habe versucht, OnlineConverter mit SpringBoot + JODConverter zu verwenden
Ich habe mit Studyplus zeitsparendes Management-Lernen versucht.
Ich habe versucht, ein wenig mit BottomNavigationView zu spielen ①
[Rails] Bildbeitrag von CarrierWave [AWS EC2]
Ich habe versucht, OpenCV mit Java + Tomcat zu verwenden
Ich habe Lazy Initialization mit Spring Boot 2.2.0 ausprobiert
Ich habe Step-Funktionen mit AWS CDK erstellt.
[AWS] Veröffentlichen Sie die Rails-App mit Nginx + Puma