元経理マンが27歳でエンジニアに転向してからのメモ集

元経理マンがエンジニアに転向して現在

ローカルで構築したRuby On RailsのアプリをGCPへの自動デプロイ環境を構築する。②

こちらの続き。

ryomoyr.hatenablog.com

Cicle CIのビルド

Circle CIはアカウントを作成して、GitHubと連携していれば、
リモートリポジトリを作成したらすでにプロジェクトに追加できる状態になっている。

add projectsから該当のリポジトリSetUp Project押す。 以下のようなプロジェクトの設定画面になるので、画像のように設定する。

f:id:ryomoyr:20181014152040p:plain:w400

下に出てきたコードをコピーして、
.circleci/config.ymlファイルをRails rootに作成して貼り付ける。

その後にCircle CIの画面に戻って、Start Buildを押す。
最初は失敗するので、先程コピペした内容をコミットしてプッシュする。

Circle CIを確認するとまた、エラーになるが、 pushして、Circle CIのビルドが始まればとりあえずOK

変数の設定とfinger printの生成

Circle CIと連携するのに、IPアドレスやポート番号を変数に登録しておく。
また、反映させたい本番環境にはCircle CIからsshでログインすることになるので、
秘密鍵をCircle CI側に登録しておくことで、
finger printが生成できるので、それを.circleci/config.ymlに記載する。

プロジェクトの設定画面の以下の2つから設定を行う。

f:id:ryomoyr:20181014152929p:plain:w300

Environment Variableには、IPとポート番号など見られたくない内容を登録しておく。

f:id:ryomoyr:20181014153356p:plain:w300

また、Add an SSH Keyでは、HOSTとローカルにある秘密鍵を登録しておく。

f:id:ryomoyr:20181014153229p:plain:w300

登録すると、finger printが得られるので、config.ymlに記載する。

f:id:ryomoyr:20181014153524p:plain:w300

config.ymlの記載

Environment Variable と SSH Key で登録した内容をこちらに反映。
また、config.ymlの内容を以下に変更する。

finger printは各自で違う。

# Ruby CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2
jobs:
  build:
    docker:
      # specify the version you desire here
       - image: circleci/ruby:2.4.2-node-browsers
    working_directory: /home/circleci/rails.com
    steps:
      - checkout

      - setup_remote_docker:
          reusable: true

      - restore_cache:
          keys:
            - v1-dependencies-{{ checksum "Gemfile.lock" }}
            - v1-dependencies-

      - run:
          name: install dependencies
          command: |
            bundle install --jobs=4 --retry=3 --clean
          #command: bundle check || bundle install --jobs=4 --retry=3

      - save_cache:
          paths:
            - ./vendor/bundle
          key: v1-dependencies-{{ checksum "Gemfile.lock" }}

      #production
      - add_ssh_keys:
          fingerprints:
            - "fa:c0:b9:73:b5:9f:fb:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:"
      - run:
          name: Start ssh-agent
          command: |
            ssh-agent -s > ~/.ssh_agent_conf
            source ~/.ssh_agent_conf
            for _k in $(ls ${HOME}/.ssh/id_*); do
              ssh-add ${_k} || true
            done


      - deploy:
          name: Start deploy
          command: |
            if [ "${CIRCLE_BRANCH}" == "master" ]; then
                ssh-keyscan -p ${PORT} ${HOST} >> ~/.ssh/known_hosts
                ls
                # bundle exec cap production deploy
            fi

一旦これをpushして、lsコマンドが実行できていればsshでの接続もできている。

f:id:ryomoyr:20181014174423p:plain:w300

Capistrano3 による自動デプロイ

Gemfileの記載

こちらの3つを追加。 capistrano
capistrano-rails
capistrano-bundler

最終的にGemfileは以下。

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.4.2'
gem 'rails', '~> 5.2.1'
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
gem 'puma', '~> 3.11'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'capistrano', '~> 3.5'
gem 'capistrano-rails'
gem 'capistrano-bundler'
gem 'bootsnap', '>= 1.1.0', require: false
gem 'dotenv-rails'

group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
end

group :development do
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  gem 'spring'
  gem 'spring-watcher-listen', '~> 2.0.0'
end

group :test do
  gem 'capybara', '>= 2.15'
  gem 'selenium-webdriver'
  gem 'chromedriver-helper'
end

gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

bundleコマンドを実行してGemファイルをインストールする。

インストール

こちらのコマンドで一発で各種の設定ファイルができる。

# bundle exec cap install

mkdir -p config/deploy
create config/deploy.rb
create config/deploy/staging.rb
create config/deploy/production.rb
mkdir -p lib/capistrano/tasks
create Capfile
Capified

各種設定ファイルの記載

Capfile

require "capistrano/setup"
require "capistrano/deploy"
require "capistrano/scm/git"
install_plugin Capistrano::SCM::Git
require "capistrano/bundler"
require "capistrano/rails/assets"
require "capistrano/rails/migrations"
Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r }

config/deploy.rb

set :application, "rails.com"
set :repo_url, "git@github.com:xxxxxx/xxxxxxx"
set :deploy_to, '/home/kusanagi/rails.com'
set :linked_files, fetch(:linked_files, []).push(".env", "config/master.key")

repo_urlはpushしているリモートリポジトリを入れる。

config/deploy/production.rb

server "xx.xx.xx.xx",
  user: "kusanagi",
  roles: %w{web app},
  ssh_options: {
    port: xxxxx,
    forward_agent: true,
    auth_methods: %w(publickey)
    # password: "please use keys"
  }

serverはIPアドレス、portは各自で設定したポート番号をいれる。
本当はここでも.envが使えると思っていたのだが、できないので、
公開鍵認証を行わずにpublicリポジトリで公開するのはNG。
できるのであればやり方は今後調べてみる。

デプロイ

この状態でpushするとCircleCIが反応して、デプロイサーバーにsshで入って、
自動でデプロイをしてくれる。 が、以下のエラーが最初に出る。

00:08 deploy:check:linked_files
      ERROR linked file /home/kusanagi/rails.com/shared/.env does not exist on xx.xx.xx.xx
Exited with code 1

先にpushしてsharedフォルダが作成されないとできないが、
あとは.envファイルとmaster.keyをGCPのsharedに入れて、もう一度回せば、
Circle CIでSuccessがでる。

デプロイする前に GCPのサーバーのNginxのrootをhome/kusanagi/rails.com/current/publicに置き換える。

変更が終わったらデプロイしてみる。 まずは、vagrant環境でindex.htmlを作成する。

f:id:ryomoyr:20181014190023p:plain:w300

pushすると、自動でGCPにデプロイしてくれる。

f:id:ryomoyr:20181014190308p:plain:w300

以上。

GitHub見られたらサーバー情報モロバレだし、 capistranoとか使い方全然正しくなさそうなので、

通りすがりでも正しいやり方分かる方はぜひとも教えてやっていただけますでしょうか。。。