d0tfi1e’s blog

趣味と日記

CircleCIで自動デプロイ

circle.ymlを用意します。

machine:
  ruby:
    version: 2.4.2

test:
  override:
    - /bin/true

deployment:
  production:
    branch: master
    commands:
      - ruby deploy.rb

デプロイに使うだけなので、テストを/bin/trueに置き換えます。ruby deploy.rbに相当する部分はシェルスクリプトでいいんですが、現代っ子なのでRubyで書きます。

仕組みを説明すると、CircleCIのコンテナから上記コマンドが実行されるので、コンテナからリモートサーバへSSHでログインして、プログラムを最新に置き換えてあげるといったことをすればいいです。なので、リモートサーバのpemをCircleCIに登録してあげる必要があります。

CircleCIのプロジェクトのSettingsからSSH Settingsみたいなのがあった気がするので、そこにいって鍵を登録します。ホスト名はIPアドレスにしました。

deploy.rbを以下のように書きます。EC2にログインすることを想定して、ユーザー名はec2-userにしておきます(各自のものにしてください)。

IP = 'xxx.xxx.xxx.xxx'
KEY = "id_#{IP}"

puts "ssh -i ~/.ssh/#{KEY} ec2-user@#{IP} 'bash -s' < commands.sh"
res = `ssh -i ~/.ssh/#{KEY} ec2-user@#{IP} 'bash -s' < commands.sh`
if res['exit=0'].nil?
  exit(1)
end

commands.shはリモートで実行するコマンドです。

source ~/.bash_profile && \
cd プロジェクトのディレクトリ && \
git fetch && git reset --hard origin/master && \
必要があればサーバの停止など && \
必要があればdependencyのインストールなど && \
必要があればビルドなど && \
必要があればサーバの再起動など ; \
echo exit=$?

&&;の違いに注意してください。;はexit statusが0にならなくても次に進む場合の連結です。最後にすべての操作成功時にexit=0を出力するようにし、Ruby側からこれを確認し、デプロイの成功判定をCircleCI側に伝えます。