[RUBY] J'ai essayé le déploiement automatique avec CircleCI + Capistrano + AWS (EC2) + Rails

introduction

L'autre jour, j'ai déployé mon propre portefeuille sur AWS à l'aide de Capistrano, j'ai donc essayé de le déployer automatiquement en combinaison avec CircleCI.

Cela fait environ 4 mois que j'ai commencé à apprendre la programmation, mais j'ai pu l'implémenter en environ une semaine.

** Je souhaite intégrer CircleCI / CD dans mon portfolio! J'espère que cela sera utile pour ceux qui disent **.

Si vous avez des suggestions, je vous serais reconnaissant de bien vouloir commenter.

supposition

CircleCI et Capistrano sont résumés dans un article séparé.

Exécutez SystemSpec (RSpec) et Rubocop sur CircleCI) Déploiement facile avec Capistrano + AWS (EC2) + Rails

procédure

Vous devez définir plusieurs paramètres, alors faisons-le étape par étape.

  1. Enregistrez la clé privée ssh dans CircleCI afin de pouvoir accéder à l'instance EC2 d'AWS.
  2. Définissez les variables d'environnement sur la console CircleCI
  3. Modifiez .circleci / config.yml pour vous assurer que vous disposez d'une connexion SSH
  4. Exécutez le déploiement Capistrano lorsqu'il est poussé vers Github
  5. Configurez le déploiement Capistrano pour qu'il s'exécute uniquement lorsque la branche Github est maître

1. Enregistrer la clé privée SSH dans CircleCI

Après avoir sélectionné le projet à utiliser sur l'interface graphique CIrcleCI, sélectionnez «Paramètres du projet >> CLÉS SSH >> Ajouter une clé SSH» et entrez le «Nom d'hôte» et «Clé privée».

«Nom d'hôte» décrit le domaine ou l'adresse IP. J'ai écrit ʻappname.com` parce que j'avais mon propre domaine.

Private Key décrit le contenu de la clé privée, Cependant, il y a deux points à noter ici, je vais donc les expliquer. (Je suis resté coincé ici pendant quelques jours ...)

Précautions lors de l'enregistrement d'une clé privée

1. ** Décrivez le contenu de la clé privée utilisée lors de la connexion locale à EC2 **

Si vous créez votre propre application et la déployez sur AWS, vous devez disposer de plusieurs clés privées, telles que la clé d'accès AWS et la clé privée pour la liaison avec Github. Par conséquent, vous vous demandez peut-être quelle clé privée utiliser. (J'étais perdu ...)

La clé requise est ** la clé privée utilisée pour se connecter localement à EC2 **.

Si la clé privée est stockée dans ~ / .ssh, vérifiez la liste des clés privées avec la commande suivante.

(local)


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

Dans mon cas, j'utilise la commande suivante lors de la connexion locale à EC2.

(local)


[~]$ ssh appname_rsa

Dans ce cas, vous pouvez copier le contenu de la clé privée en tapant la commande suivante sur le terminal.

(local)


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

Collez le contenu copié dans Private Key.

Et si le début de la description est ----- BEGIN RSA PRIVATE KEY -----, c'est OK est.

S'il s'agit de ----- BEGIN OPENSSH PRIVATE KEY -----, passez à la note suivante.

2. ** Le format de fichier de clé privée doit être le format PEM **

Les formats de fichier de clé SSH sont ʻOPEN SSH et PEM, et le format de fichier de clé SSH défini dans CircleCI est spécifié comme PEM`.

Vous pouvez dire comment distinguer le format de fichier au début du contenu de la clé privée. ʻPour OPENSSH: ----- BEGIN OPENSSH PRIVATE KEY ----- PourPEM: ----- BEGIN RSA PRIVATE KEY ----- `

Si la clé privée utilisée pour se connecter localement à EC2 est au format «OPENSSH», vous devez créer une clé privée au format «PEM» et la définir de manière à pouvoir vous connecter à EC2.

Je l'ai créé au format «OPENSSH», j'ai donc recréé la clé privée en suivant les étapes ci-dessous.

Comment créer une clé privée au format PEM et définir la connexion

Tout d'abord, générez la clé localement.

(local)


[~]$ cd .ssh
[.ssh]$ ssh-keygen -m pem
(#Créer une clé publique)
-----------------------------
Enter file in which to save the key ():appname_rsa 
(#Entrez le nom du fichier ici)
Enter passphrase (empty for no passphrase): 
(#Entrez tel quel sans rien faire)
Enter same passphrase again: 
(#Entrez tel quel sans rien faire)
-----------------------------

[.ssh]$ ls
#「appname_rsa "et" appname_rsa.Confirmez que "pub" a été généré
[.ssh]$ cat appname_rsa.pub
(#Sortir le contenu de la clé sur le terminal → ssh-rsa~~~~Copier vers local)

Ensuite, définissez la clé publique créée précédemment côté serveur (EC2).

(server)


[yuki|~]$ mkdir .ssh
[yuki|~]$ chmod 700 .ssh
[yuki|~]$ cd .ssh
[yuki|.ssh]$ vim authorized_keys
(#vim ouvre)
-----------------------------
ssh-rsa sdfjerijgviodsjcIKJKJSDFJWIRJGIUVSDJFKCNZKXVNJSKDNVMJKNSFUIEJSDFNCJSKDNVJKDSNVJNVJKDSNVJKNXCMXCNMXNVMDSXCKLMKDLSMVKSDLMVKDSLMVKLCA [email protected]
(#Collez le contenu de la clé que vous avez copiée précédemment)
-----------------------------
[yuki|.ssh]$ chmod 600 authorized_keys
[yuki|.ssh]$ exit
[ec2-user|~]$ exit

Lorsque vous avez terminé, retournez dans vos sections locales et définissez les communications à utiliser pour l'authentification.

(local)


[~]$ cd .ssh
[.ssh]$ vim config
(#Démarrez Vim et éditez le fichier de configuration)

#Ajoutez ce qui suit
Host appname_rsa
Nom d'hôte IP Elastic EC2(#Selon vos paramètres)
  Port 22
  User yuki (#Nom d'utilisateur EC2)
  IdentityFile ~/.ssh/appname_rsa (#Réglage de la clé privée)
-----------------------------

Cela permet la communication SSH en utilisant la clé privée au format PEM. Entrez la commande suivante localement et essayez de vous connecter.

(local)


ssh appname_rsa

Si vous pouvez vous connecter, le réglage est terminé.

Si vous l'avez fait jusqu'à présent, reportez-vous à la note 1 et décrivez le contenu de la clé privée dans la «Clé privée» de CircleCI et enregistrez-la.

2. Définissez les variables d'environnement sur la console CircleCI

CircleCI se déploie en fonction du ** code source Github **. Par conséquent, les fichiers qui ne sont pas poussés sur Github comme décrit dans gitignore ne peuvent pas être reconnus.

Et CircleCI a une fonction pour gérer ces fichiers en le définissant comme une variable d'environnement sur la console, alors utilisez-la.

Depuis les paramètres du projet CircleCI, allez à la page «Variables d'environnement» et sélectionnez «Ajouter une variable».

Ensuite, définissez deux variables d'environnement.

Name:'RAILS_MASTER_KEY' Value:Local'master.key'Décrivez le contenu.

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

Après ʻappname_rsa_ de Value of PRODUCTION_SSH_KEY, écrivez la chaîne sans: of Fingerprints écrite à côté du nom d'hôte de SSH Key` enregistré précédemment.

Ensuite, configurez la connexion SSH de Capistrano dans l'environnement de production. Ici, écrivons config / deploy / production.rb en utilisant PRODUCTION_SSH_KEY.

config/deploy/production.rb


server 'Décrivez l'IP élastique d'EC2', user: 'yuki', roles: %w[app db web]

#Connexion SSH à l'aide de variables d'environnement définies dans l'interface graphique CircleCI
set :ssh_options, {
  keys: [ENV.fetch('PRODUCTION_SSH_KEY').to_s],
  forward_agent: true,
  auth_methods: %w[publickey]
}

3. Confirmez que la communication SSH est possible

Ajoutez la description suivante à .circleci / config.yml. Dans Fingerprints, il est écrit à côté du nom d'hôte de la clé SSH que vous avez enregistrée précédemment, alors copiez-la.

yml:.circleci/config.yml


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

Puis poussez vers github.

S'il peut être exécuté, dans la console côté CircleCI, pour le processus appelé ʻInstalling additional ssh keys`

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

Doit être affiché.

4. Exécutez Capistrano en poussant vers Github

Écrivez ce qui suit dans .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

Poussons vers Github. Devrait pouvoir se déployer automatiquement! ...est.

5. Configurez le déploiement Capistrano pour qu'il s'exécute uniquement lorsque la branche Github est maître

Ajoutez des filters à la fin des workflows de circleci / config.yml.

yml:.circleci/config.yml


# build,test,Décrivez le déploiement.
・
・
・

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

Désormais, le déploiement de Capistrano ne fonctionnera que lorsque la branche Github est maître!

Résumé

Je suis tombé sur la partie certification SSH un peu lol.

J'espère que cela aide ceux qui trébuchent de la même manière ☺️

Enfin, je publierai le code source et les articles de référence de CircleCI et Capistrano pour votre référence.

Code source

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


#Version fixe de capistrano
lock '3.14.1'

#Nom de l'application à déployer
set :application, 'golfour'

#dépôt git à cloner
set :repo_url, '[email protected]:xxxxxx/xxxxxx.git'

#La branche à déployer. Il n'est pas nécessaire que la valeur par défaut soit master.
set :branch, 'master'

#Le répertoire dans lequel effectuer le déploiement.
set :deploy_to, '/var/www/rails/appname'

# secret_base_Ajouté pour lire la clé
set :linked_files, %w[config/master.key]

#Un fichier avec un lien symbolique.
set :linked_files, fetch(:linked_files, []).push('config/database.yml', 'config/settings.yml', '.env')

#Un dossier avec des liens symboliques.
set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system')

#Le nombre de versions à conserver. Enregistrez jusqu'à 5 historiques.
set :keep_releases, 5

#version rubis
set :rbenv_ruby, '2.5.1'

#Le niveau du journal à sortir.
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 'IP élastique EC2', user: 'yuki', roles: %w[app db web]

#Connexion SSH à l'aide de variables d'environnement définies dans l'interface graphique CircleCI
set :ssh_options, {
  keys: [ENV.fetch('PRODUCTION_SSH_KEY').to_s],
  forward_agent: true,
  auth_methods: %w[publickey]
}

Article de référence

[Circle CI] rails5.2 / Capistrano / Déploiement automatique sur AWS par environnement CICD Automatiser le déploiement avec CircleCI

Recommended Posts

J'ai essayé le déploiement automatique avec CircleCI + Capistrano + AWS (EC2) + Rails
Déploiement facile avec Capistrano + AWS (EC2) + Rails
J'ai essayé de créer un portefeuille avec AWS, Docker, CircleCI, Laravel [avec lien de référence]
[Rails] Nginx, déploiement de l'environnement Puma et étude du serveur [AWS EC2]
J'ai essayé d'installer le plugin lié à Ruby on Rails avec vim-plug
J'ai essayé DI avec Ruby
[Rails] J'ai essayé de créer une mini application avec FullCalendar
J'ai essayé Rails débutant [Chapitre 1]
[Rails] J'ai essayé d'implémenter le traitement par lots avec la tâche Rake
J'ai essayé Rails débutant [Chapitre 2]
J'ai essayé UPSERT avec PostgreSQL.
J'ai essayé BIND avec Docker
Que faire si une erreur d'authentification de clé SSH se produit lors du déploiement automatique sur EC2 avec Capistrano
J'ai essayé d'implémenter la fonction de prévisualisation d'image avec Rails / jQuery
J'ai essayé de créer une fonction de groupe (babillard) avec Rails
J'ai essayé d'utiliser JOOQ avec Gradle
J'ai essayé d'interagir avec Java
J'ai essayé la communication UDP avec Java
[Rails] J'ai essayé de supprimer l'application
rails Le déploiement AWS n'est pas reflété
[AWS SDK] Script de construction automatique EC2
J'ai essayé GraphQL avec Spring Boot
J'ai essayé Flyway avec Spring Boot
[EC2 / Vue / Rails] Procédure de déploiement EC2 pour Vue + Rails
[Rails] Construction de l'environnement d'instance AWS EC2
J'ai essayé de personnaliser Slim avec Scaffold
[Rails] Récapitulatif des incidents liés aux erreurs de déploiement AWS
J'ai essayé de faire une sauvegarde automatique avec plus agréable + PostgreSQL + SSL + docker
[Circle CI] J'étais accro au test automatique de Circle CI (rails + mysql) [Memo]
J'ai essayé de visualiser l'accès de Lambda → Athena avec AWS X-Ray
[AWS] Comment déployer automatiquement une application Web créée avec Rails 6 sur ECR / ECS à l'aide de CircleCI (1) Préparation [Déploiement de conteneur]
J'ai essayé d'utiliser Realm avec Swift UI
J'ai essayé de démarrer avec Web Assembly
J'ai essayé d'utiliser Scalar DL avec Docker
J'ai essayé d'utiliser OnlineConverter avec SpringBoot + JODConverter
J'ai essayé l'apprentissage de la gestion qui fait gagner du temps avec Studyplus.
J'ai essayé de jouer un peu avec BottomNavigationView ①
[Rails] Publication d'images par CarrierWave [AWS EC2]
J'ai essayé d'utiliser OpenCV avec Java + Tomcat
J'ai essayé l'initialisation paresseuse avec Spring Boot 2.2.0
J'ai créé des fonctions d'étape avec AWS CDK.
[AWS] Publier l'application Rails avec nginx + puma