kusanagiWordPressThemeCircleCI
kusanagiでWordPressのCD/CI環境構築を行いました。本番環境、ステージング環境、開発環境の3環境です。リモートとしては本番サーバー(本番環境https://hogehoge.com)と開発サーバー(ステージング環境https://hogehoge.com、開発環境https://dev01.hogehoge.com)の2サーバーです。リモート2サーバー、3環境という構成です。リポジトリのノンベア・ベアについては管理がめんどくさいので採用していません。ftpやsftpで本番のリポジトリのmasterブランチを書き換えてgit addもgit commitもせず、やったぜオーラを出す様な人は居ない(笑)としておきます。
git pull の部分はgit fetch / git merge とブランチ設定を含めて、改良していく予定です。
開発サーバー側はgit管理しない、git管理は本番サーバーの本番環境のみという作戦もある様です。メインリポジトリのgithubと本番環境のgitの2つだけ管理すればいいのでgit/github本番環境へのファイナルマージ兼環境全体マネージャの負担は大きく減りますね。
開発者のローカルも含めて全環境のインフラをDockerでも、Virtualboxでも、AWSでも、Azureでも、さくらVPSでも、ConohaVPSでも、kusanagiで統一できるためです。環境差を最小限に抑えやすいです。また、本番サーバーの本番環境と開発サーバーのステージング環境で独自ドメインを同一にしたため、WordPressのDB同期が可能となり、developブランチの開発環境https://dev01.hogehoge.comをmasterブランチの本番環境https://hogehoge.comにマージしたら、本番環境で問題が起きる!!F○ck!!などのケースをreleaseブランチのステージング環境https://hogehoge.comで事前に検証できます。本番再現性の高いステージング環境をはさむことで本番環境でトラブルが起きる確率を最小限に減らすことが出来ます。
rsyncを使うと環境個別の設定値の管理をやりにくくなるということもあり、githubメインリポジトリからリモートリポジトリへのpushやpullをCircleCIでトリガーとして、本番/ステージ/開発環境のシェルスクリプトのgit pullをCircleCIでキックしてすべてgitでデプロイします。
kusanagiはLinuxユーザー設計がセキュアでパーミッションまでしっかり作りこまれています。環境構築中はpermission denied が頻発します。LinuxユーザーやLinuxグループ、パーミッション、各種ssh接続環境の構築、githubリポジトリとリモート/ローカルホストのgitの連携構築、ブランチの使い分け、などを把握していないと結構大変です。インフラエンジニアやセキュリティエンジニアの方のほうがとっつきやすいかもしれません。
まずは、Linuxのrootユーザーやkusanagiユーザーではない、CircleCI用のLinuxユーザーをステージング/開発サーバーで作ります。CircleCIで使うため、パスフレーズ無しの鍵認証となります。日頃からパスフレーズ有りを徹底している場合、セキュリティ的に違和感があると思いますが、どうしようもないです。
rootユーザーで行ってください
useradd ユーザー名
ユーザー名は開発サーバーのCircleCIユーザーとしてcircleusdevとしました。CircleCIのドキュメントなどでcircleやcircleciなどの命名ケースがあるので命名の重複を避けました。本番サーバーのCircleCIユーザーはcircleusprodとなります。
useradd circleusdev
rootユーザーで行ってください
passwd ユーザー名
ユーザー名はcircleusdev
passwd circleusdev
rootユーザーで行ってください
cat /etc/passwd
ファイル中身の見方としては、横に1行単位で以下の様に並んでいます。基本的に、パスワードは暗号化されて見られないです。
ユーザー名 : パスワード(x) : ユーザーID : グループID : 任意コメント(何も記載されてないことが多い) : ユーザーホームディレクトリ : ユーザーが使用するシェル
groups ユーザー名
ユーザー名はcircleusdev
groups circleusdev
rootユーザーで行ってください
usermod -aG グループ名 ユーザー名
グループはkusanagi、ユーザーはcircleusdevとします。kusanagiユーザーが所属するkusanagiグループとwwwグループの両グループをcircleusdevユーザーに追加します。wwwは不要かもしれませんが念の為に追加します。
usermod -aG kusanagi circleusdev
usermod -aG www circleusdev
circleusdevユーザーでは、cd /home/kusanagiでpermission deniedが発生します。rootユーザーになり、permission denied が発生する/home/kusanagiディレクトリにて「グループ」のパーミッションの数値を調整します。
rootユーザーからcircleusdevユーザに変更
su - circleusdev
パーミッションでrwxの7を使いたくないですが、/home/kusnagi ディレクトリは701なので、グループをrwxとして771に変えます。751では同kusanagiグループのcircleusdevユーザーは書き込み出来ない(読みと実行のみ)ので気をつけてください。
chmod 771 /home/kusanagi
/home/kusanagi/.ssh(700➞770)を行うと鍵認証できなくなるのでくれぐれも気をつけてください。
kusanagi 立ち上げ直後にやっておきたいLinuxユーザー設定の基本 でLinux一般ユーザーを作ってssh接続するまでの手順を確認出来ます。パスフレーズ無しでcircleusdevユーザーで同じ様に設定してください。
VPS(Linux)からgithubに接続でも手順を確認できますが、CircleCIで使う場合、以下の手順を推奨します。必ず、/home/circleusdev/.sshにてcircleusdevユーザーでパスフレーズ無しでssh-keygenコマンドで設定を行ってください。
ssh-keygen -t rsa -b 4096 -C "メールアドレス" -f id_rsa_github
id_rsa_github.pubはgithubのGUIでPersonal settings(Settings)➞SSH and GPG keys➞New SSH keyに登録してください。そして、/home/circleusdev/.ssh/configファイルを以下のように作り、接続先Hostをステージ/開発サーバに事前登録して、ssh github.comなどでgithubにssh接続出来るようにしてください。パスフレーズ無しでssh接続を出来る事によってシェルスクリプトによる自動化が可能となります。*今回は、Hostの接続名自体をgithub.comにしています。
Host github.com
HostName github.com
IdentityFile /home/circleusdev/.ssh/id_rsa_github
User git
rootユーザーで行ってください
chmod 600 /home/circleusdev/.ssh/config
ステージ/開発サーバーのcircleusdevユーザーで
vi /home/kusanagi/hogehoge_html/deploy_stage.sh
を作ります。
deploy_stage.shの中身は以下の通りです。git pullコマンドのブランチ運用については少しずつ追記更新します。
#! /bin/bash
cd /home/kusanagi/hogehoge_html/DocumentRoot/wp-content/themes/something
git pull
echo "git pull !"
念のため
chown circleusdev:circleusdev /home/kusanagi/hogehoge_html/deploy_stage.sh
も行い、ユーザー:グループを circleusdev:circleusdevにしておきます。
さらにrootユーザーで
chmod 775 /home/kusanagi/hogehoge_html/DocumentRoot/wp-content
chmod 775 /home/kusanagi/hogehoge_html/DocumentRoot/wp-content/themes
chown -R circleusdev /home/kusanagi/hogehoge_html/DocumentRoot/wp-content/themes/something/.git/
も行います。
最後に.circleci/config.ymlです。version: 2.1 のOrbsは使っていません。Environment variablesは適宜CircleCIで設定してください。
# Environment variables
# - HOST_NAME_STAGEDEV
# - USER_NAME_STAGEDEV
# - HOST_NAME_PROD
# - USER_NAME_PROD
version: 2
jobs:
build:
docker:
- image: circleci/php:latest
steps:
- checkout
#- run:
#name: "Check Composer Version"
#command: composer --version
- add_ssh_keys:
fingerprints:
- "フィンガープリント"
- run:
name: Start ssh-keyscan
command: |
ssh-keyscan ${HOST_NAME_DEV} >> ~/.ssh/known_hosts
echo ${CIRCLE_BRANCH}
#- run: whoami
- deploy:
name: Start develop deploy
command: |
if [ "${CIRCLE_BRANCH}" == "master" ]; then
ssh -o "StrictHostKeyChecking=no" ${USER_NAME_PROD}@${HOST_NAME_PROD} "/home/kusanagi/hogehoge_html/deploy_prod.sh"
elif [ "${CIRCLE_BRANCH}" == "release" ]; then
ssh -o "StrictHostKeyChecking=no" ${USER_NAME_STAGEDEV}@${HOST_NAME_STAGEDEV} "/home/kusanagi/hogehoge_html/deploy_stage.sh"
elif [ "${CIRCLE_BRANCH}" == "develop" ]; then
ssh -o "StrictHostKeyChecking=no" ${USER_NAME_STAGEDEV}@${HOST_NAME_STAGEDEV} "/home/kusanagi/dev01hogehoge_html/deploy_dev.sh"
else
echo "Not pull req"
fi
本番環境、ステージング環境、開発環境からgithubへgit pullを行うdeploy_prod.sh、deploy_stage.sh、deploy_dev.shをそれぞれの環境のプロファイルディレクトリに配置、ローカル開発環境からgithubの中央リポジトリにfeatureなどの特定のブランチを指定してpullリクエスト、もしくはgithub上のフォークリポジトリから中央リポジトリへfeatureなどの特定のブランチを指定してpullリクエストを行い、masterブランチ / developブランチ / releaseブランチへのpushやmerge pull requestをトリガーとしてCircleCIで各ホストにssh接続してデプロイ向けシェルスクリプトの各ファイルをキックします。
本番環境、ステージング環境、開発環境、それぞれの違いをわかりやすくするため環境別のホストIPや各種独自ドメインをDBに登録して、ブラウザで見ている環境が本番、ステージング、開発のどれであるか?簡単にわかるような環境判別プラグインを作りたい。
DevOpsチーム全体で、chmodやchownなどのパーミッション変更は、環境構築を行ったインフラエンジニア以外、勝手にやらないことをチーム内で徹底啓蒙する必要があります。本番デプロイで問題が起きる原因の1つとして、環境毎のパーミッション不揃い問題があります。インフラエンジニアの仕事は、トラブル原因Linuxユーザー(開発エンジニア)を特定しやすい管理、トラブルが起きないLinuxパーミッション管理、updatableでセキュア、デプロイがやりやすい、テストコードが上手で、速い軽い安定したサーバー、を維持しつつ、突然のヤフー砲に負けないサーバーを構築/維持することです。