git push 하면 자동으로 pull 해 주는 환경을 만든다

3964 단어 SSHGitBitbucket

이 기사에 대하여



Bitbucket에 git push 그러면 자동으로 git pull 해준다.

그런 겸손한 행복을 원했지만 의외로 귀찮은 준비가 필요했습니다. 이 기사에서는 그 절차를 소개합니다.

구성





Bitbucket



무료로 사용할 수 있는 리포지토리의 호스팅 서비스. webhooks 기능이 있다면 다른 서비스도 괜찮을 것입니다.

보안을 위해 배포 전용 계정을 만드는 것이 좋습니다. 해당 리포지토리에 대한 읽기 권한을 부여하십시오.

deployer: 배포용 애플리케이션



Bitbucket에서 HTTP POST를 받고 git pull를 실행하는 응용 프로그램.

어떤 언어·환경으로 만들어도 괜찮습니다만, 배포하는 유저 권한으로 움직일 필요가 있습니다. 이번에는 Ruby/Sinatra로 만들고 Apache + Passenger로 움직이기로 했습니다.

1. SSH 키 생성



Bitbucket은 SSH 키로 계정을 식별하므로 전용 SSH 키를 만들어 등록합니다. 소유자는 배포할 사용자(이 예에서는 webapp)를 사용해야 합니다.
sudo -u webapp ssh-keygen
# 適当なパスに出力する(以下の例では /path/to/webapp.ssh/id_rsa とする)
# パスフレーズは設定しない

2. git 용 ssh 래퍼 만들기



SSH 키를 지정하여 git 명령을 실행하기 위해 래퍼가 될 쉘 스크립트를 만듭니다.

git-ssh.sh
#!/bin/sh

exec ssh -oIdentityFile=$GIT_SSH_KEY "$@"

3. git clone에 의한 동작 확인



동작 확인을 하지 않고, git clone 해 봅니다.
sudo -u webapp \
 GIT_SSH=/path/to/bin/git-ssh.sh GIT_SSH_KEY=/path/to/webapp.ssh/id_rsa \
 git clone [email protected]:bar/hogehoge.git target

올바르게 소유자 webapp로 clone 할 수 있으면 성공입니다.

4. 배포용 애플리케이션 설치



배포 대상에 cd 하고 git pull 하기 위한 응용 프로그램을 만듭니다. 특히 복잡한 점은 없습니다.

일단, 실수로 변경해 git pull 가 실패하는 것을 막기 위해, git stash 를 넣고 있습니다. 원하는대로 조정하십시오.
require 'sinatra/base'
require 'open3'

class DeporaApp < Sinatra::Base
  # 環境変数のチェック
  configure do
    {
      "DEPLOY_ROOT" => "writable",
      "GIT_SSH_KEY" => "readable",
      "GIT_SSH" => "executable",
    }.each do |env_key, check|
      raise "#{env_key} is not present" unless ENV[env_key]
      raise "#{env_key} is not #{check}" unless File.send("#{check}?", ENV[env_key])
    end

    set :deploy_root, ENV['DEPLOY_ROOT']
  end

  # URLは適当
  post '/hogehoge' do
    cmd = [
      "cd #{settings.deploy_root}",
      "git add .",
      "git stash save",
      "git pull",
    ].join("&&")

    o, e, s = Open3.capture3(cmd)
    text = "Stdout: #{o}\n\nStderr: #{e}"

    # 通知メールを送ったりする
    text
  end
end
config.ru의 소유자는 배포 사용자로 변경합니다. bundle install 또한 배포 사용자로 실행해야 합니다.
sudo chown webapp:webapp config.ru
sudo -u webapp bundle install --deployment

배포 대상과 SSH 관련 설정은 환경 변수로 제공하므로 VirtualHost 설정에 기록합니다.
<VirtualHost *:443>
  ServerName deployer.example.com

  SetEnv DEPLOY_ROOT /path/to/target
  SetEnv GIT_SSH /path/to/bin/git-ssh.sh
  SetEnv GIT_SSH_KEY /path/to/webapp.ssh/id_rsa

  PassengerAppEnv production

  DocumentRoot /path/to/deployer/public
  # 以下略
</VirtualHost>

5. URL에 액세스하여 동작 확인



이번에는 POST 데이터의 내용은 일절 보고 있지 않으므로, 직접 URL을 두드려 테스트할 수 있습니다.
curl -X POST https://deployer.example.com/hogehoge

POST 데이터나 접속원 IP를 체크하고 있는 경우는, 좀 더 정교한 테스트가 필요하네요.

6. Bitbucket webhooks에 URL 등록





이상입니다.

좋은 웹페이지 즐겨찾기