以前纏めていたCircleCIのconfig.ymlの場所を失念してしまい、見つけるのに少し時間がかかってしまった為、これを機にブログ化しておくことにしました。
CircleCIについて概要を説明すると、ビルド・テスト・デプロイが行えるSaas型のCI/CDサービスです。
Dockerで動作するDrone.ioやConcourseも検討しましたが、結局メンテナンスや使い勝手が楽なCircleCIを使っています。
CircleCIについては、有名且つ各所に色々な情報があるため割愛します。
ということで、今回のブログ化は主にCircleCIの.circleci/config.ymlの内容に絞ります。
また.circleci/config.ymlは、AWS EC2などを想定したSSH経由でのデプロイとします。
.circleci/config.yml(全体)
早速ですが、.circleci/config.yml(全体)です。
冒頭の通り、CircleCIのログインやプロジェクト設定など詳細は割愛します。
お手数ですが、たくさん情報があるため別途調べてみてください。
デプロイ先の環境によっては概ねコピー&ペーストで使用できますが、主にjobs: の内容(build, test, deploy)などは環境によって変更ください。
pwdコマンドやls -laコマンドを挟み、CircleCI上で実行ログを見た際にある程度分かりやすいようにしています。
行別の詳細は後述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | # 参考:https://circleci.com/docs/ja/2.0/configuration-reference/ version: 2.1 # ジョブのステップを実行する環境を定義 executors: deploy-environment: # 使用可能なmachineイメージ:https://circleci.com/docs/ja/2.0/configuration-reference/#%E4%BD%BF%E7%94%A8%E5%8F%AF%E8%83%BD%E3%81%AA-machine-%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8 machine: image: ubuntu-1604:201903-01 # ステップを実行するディレクトリ(デフォルト:~/project) working_directory: ~/project/ # ジョブ内で実行する一連のステップをマップとして定義 commands: checkout-command: description: "git checkout" steps: - run: pwd - checkout - run: ls -la attach-workspace-command: description: "attach workspace" steps: # ワークフローのワークスペースを現在のコンテナにアタッチする - attach_workspace: at: . # 現在のディレクトリ - run: pwd - run: ls -la ssh-deploy-command: description: "ssh deploy" # commandに与えるパラメータを定義 parameters: ssh_key_fingerprint: description: "ssh key fingerprint" type: string default: "" ssh_host: description: "ssh host" type: string default: "" ssh_port: description: "ssh port" type: integer default: 22 ssh_user: description: "ssh user" type: string default: "" app_env: description: "環境変数" type: string default: "local" deploy_dir: description: "deploy directory" type: string default: "" steps: - add_ssh_keys: fingerprints: - <<parameters.ssh_key_fingerprint>> - run: name: ssh deploy command: | ssh -l <<parameters.ssh_user>> -p <<parameters.ssh_port>> <<parameters.ssh_host>> ' # 現在日時 echo -e "\n========== 現在日時 ==========" && date && # APP_ENVを環境変数に設定 export APP_ENV=<<parameters.app_env>> && # APP_ENVが環境変数を確認 echo -e "\n========== APP_ENV ==========" && echo $APP_ENV && # デプロイするディレクトリへ移動 cd <<parameters.deploy_dir>> && # カレントディレクトリを確認 echo -e "\n========== pwd ==========" && pwd && # ファイル一覧を表示 echo -e "\n========== ls -la ==========" && ls -la && # リモートリポジトリの変更内容を取り込む echo -e "\n========== git pull ==========" && git pull && # ファイル一覧を表示 echo -e "\n========== ls -la ==========" && ls -la && # composerのパッケージをinstall echo -e "\n========== composer install ==========" && composer install -n --prefer-dist && # ファイル一覧を表示 echo -e "\n========== ls -la ==========" && ls -la ' jobs: build: docker: - image: circleci/php:7.4-node-browsers # ステップを実行するディレクトリ(デフォルト:~/project) working_directory: ~/project/ steps: - run: sudo apt update - run: sudo composer self-update - checkout-command - run: sudo docker-php-ext-install zip - run: composer install -n --prefer-dist # 一時ファイルを永続化してワークフロー内の別のジョブで使用できるようにする - persist_to_workspace: root: . # 現在のディレクトリ paths: - . # 現在のディレクトリ test: docker: - image: circleci/node:10.16.3 # ステップを実行するディレクトリ(デフォルト:~/project) working_directory: ~/project/ steps: - attach-workspace-command - run: name: テスト command: echo "Hello Test!" # ステージング環境へデプロイ deploy-staging: executor: deploy-environment steps: - ssh-deploy-command: ssh_key_fingerprint: "M4:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:k5" ssh_host: 123.xxx.xxx.456 ssh_user: myuser ssh_port: 22 app_env: staging deploy_dir: /hoge/ # 本番環境へデプロイ deploy-production: executor: deploy-environment steps: - ssh-deploy-command: ssh_key_fingerprint: "D7:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:h6" ssh_host: 123.xxx.xxx.789 ssh_user: myuser ssh_port: 22 app_env: production deploy_dir: /hoge/ workflows: version: 2 # ワークフロー名 build-and-test-approval-deploy: jobs: - build: # 指定branchにpushされた場合のみ実施 filters: branches: only: - staging - master - test: # testの前にbuildを実施 requires: - build # ステージング環境へデプロイ - deploy-staging: # デプロイ前に実施する処理 requires: - test # 指定branchにpushされた場合のみ実施 filters: branches: only: staging # 本番環境へデプロイ - deploy-production: # デプロイ前に実施する処理 requires: - test # 指定branchにpushされた場合のみ実施 filters: branches: only: master |
.circleci/config.yml(行別の説明)
1〜2行目(version:)
1 2 | # 参考:https://circleci.com/docs/ja/2.0/configuration-reference/ version: 2.1 |
本ブログ執筆時の最新バージョンは2.1です。
今回の.circleci/config.ymlで使用しているcommands:、parameters:、executors:はバージョン2.1でしか使用できません。
《参考》CircleCI 構成リファレンス
https://circleci.com/docs/ja/2.0/configuration-reference/
4〜11行目(executors:)
4 5 6 7 8 9 10 11 | # ジョブのステップを実行する環境を定義 executors: deploy-environment: # 使用可能なmachineイメージ:https://circleci.com/docs/ja/2.0/configuration-reference/#%E4%BD%BF%E7%94%A8%E5%8F%AF%E8%83%BD%E3%81%AA-machine-%E3%82%A4%E3%83%A1%E3%83%BC%E3%82%B8 machine: image: ubuntu-1604:201903-01 # ステップを実行するディレクトリ(デフォルト:~/project) working_directory: ~/project/ |
deploy-environment: で、デプロイ時に使用する環境を定義しています。
ステージング環境と本番環境にデプロイする際に行う処理は同じため、共通化しています。
13〜102行目(commands:)
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | # ジョブ内で実行する一連のステップをマップとして定義 commands: checkout-command: description: "git checkout" steps: - run: pwd - checkout - run: ls -la attach-workspace-command: description: "attach workspace" steps: # ワークフローのワークスペースを現在のコンテナにアタッチする - attach_workspace: at: . # 現在のディレクトリ - run: pwd - run: ls -la ssh-deploy-command: description: "ssh deploy" # commandに与えるパラメータを定義 parameters: ssh_key_fingerprint: description: "ssh key fingerprint" type: string default: "" ssh_host: description: "ssh host" type: string default: "" ssh_port: description: "ssh port" type: integer default: 22 ssh_user: description: "ssh user" type: string default: "" app_env: description: "環境変数" type: string default: "local" deploy_dir: description: "deploy directory" type: string default: "" steps: - add_ssh_keys: fingerprints: - <<parameters.ssh_key_fingerprint>> - run: name: ssh deploy command: | ssh -l <<parameters.ssh_user>> -p <<parameters.ssh_port>> <<parameters.ssh_host>> ' # 現在日時 echo -e "\n========== 現在日時 ==========" && date && # APP_ENVを環境変数に設定 export APP_ENV=<<parameters.app_env>> && # APP_ENVが環境変数を確認 echo -e "\n========== APP_ENV ==========" && echo $APP_ENV && # デプロイするディレクトリへ移動 cd <<parameters.deploy_dir>> && # カレントディレクトリを確認 echo -e "\n========== pwd ==========" && pwd && # ファイル一覧を表示 echo -e "\n========== ls -la ==========" && ls -la && # リモートリポジトリの変更内容を取り込む echo -e "\n========== git pull ==========" && git pull && # ファイル一覧を表示 echo -e "\n========== ls -la ==========" && ls -la && # composerのパッケージをinstall echo -e "\n========== composer install ==========" && composer install -n --prefer-dist && # ファイル一覧を表示 echo -e "\n========== ls -la ==========" && ls -la ' |
ファンクションのようなもので、何度も使用する一連の処理をコマンドとして定義しています。
parameters: では、受け取る値を型制御も含めて定義しています。
104〜120行目(job: > build:)
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 | jobs: build: docker: - image: circleci/php:7.4-node-browsers # ステップを実行するディレクトリ(デフォルト:~/project) working_directory: ~/project/ steps: - run: sudo apt update - run: sudo composer self-update - checkout-command - run: sudo docker-php-ext-install zip - run: composer install -n --prefer-dist # 一時ファイルを永続化してワークフロー内の別のジョブで使用できるようにする - persist_to_workspace: root: . # 現在のディレクトリ paths: - . # 現在のディレクトリ |
stepsに沿って上から順にビルド処理を行います。
stepsの内容は環境によって異なるため適宜変更が必要です。
合わせてdockerで使用するimageも環境によって異なってきます。
121〜130行目(job: > test:)
121 122 123 124 125 126 127 128 129 130 | test: docker: - image: circleci/node:10.16.3 # ステップを実行するディレクトリ(デフォルト:~/project) working_directory: ~/project/ steps: - attach-workspace-command - run: name: テスト command: echo "Hello Test!" |
stepsに沿って上から順にテストを行います。
stepsの内容は環境によって異なるため適宜変更が必要です。
テスト項目がない場合は、test: 自体config.ymlに記述する必要はありません。
(記述しない場合はworkflows: の内容も修正が必要です)
131〜152行目(job: > deploy-xxxxx:)
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | # ステージング環境へデプロイ deploy-staging: executor: deploy-environment steps: - ssh-deploy-command: ssh_key_fingerprint: "M4:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:k5" ssh_host: 123.xxx.xxx.456 ssh_user: myuser ssh_port: 22 app_env: staging deploy_dir: /hoge/ # 本番環境へデプロイ deploy-production: executor: deploy-environment steps: - ssh-deploy-command: ssh_key_fingerprint: "D7:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:h6" ssh_host: 123.xxx.xxx.789 ssh_user: myuser ssh_port: 22 app_env: production deploy_dir: /hoge/ |
ステージング環境と本番環境の2つがある場合を想定しています。
workflows: の内容に沿ってステージング環境のみデプロイ、本番環境のみデプロイが行えます。
commad: で定義していたssh-deploy-command: を呼び出して処理を行っています。
ssh_key_fingerprintには、CircleCIの該当プロジェクトの「Project Settings」画面→「SSH Keys」画面で登録したSSH Keyのフィンガープリントの値を記述します。
ssh_host、ssh_user、ssh_port、app_env、deploy_dirは環境によって変更が必要です。
config.ymlに直接記述でも良いですが、CircleCIを使う上でGit管理が前提のため(フィンガープリントを使用してのSSH接続と言えども)セキュリティ上はCircleCIの該当プロジェクトの「Project Settings」画面→「Environment Variables」画面にて変数及び値を登録した上で、変数名をconfig.ymlに記述しての使用が望ましいです。
変数名を使用した場合は、下記のような記述になります。
ssh_key_fingerprintも変数化できると思います。
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | # ステージング環境へデプロイ deploy-staging: executor: deploy-environment steps: - ssh-deploy-command: ssh_key_fingerprint: "M4:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:k5" ssh_host: ${STAGING_SSH_HOST} ssh_user: ${STAGING_SSH_USER} ssh_port: ${STAGING_SSH_PORT} app_env: ${STAGING_SSH_APP_ENV} deploy_dir: ${STAGING_SSH_DEPLOY_DIR} # 本番環境へデプロイ deploy-production: executor: deploy-environment steps: - ssh-deploy-command: ssh_key_fingerprint: "D7:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:h6" ssh_host: ${PRODUCTION_SSH_HOST} ssh_user: ${PRODUCTION_SSH_USER} ssh_port: ${PRODUCTION_SSH_PORT} app_env: ${PRODUCTION_SSH_APP_ENV} deploy_dir: ${PRODUCTION_SSH_DEPLOY_DIR} |
154〜187行目(workflows:)
154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 | workflows: version: 2 # ワークフロー名 build-and-test-approval-deploy: jobs: - build: # 指定branchにpushされた場合のみ実施 filters: branches: only: - staging - master - test: # testの前にbuildを実施 requires: - build # ステージング環境へデプロイ - deploy-staging: # デプロイ前に実施する処理 requires: - test # 指定branchにpushされた場合のみ実施 filters: branches: only: staging # 本番環境へデプロイ - deploy-production: # デプロイ前に実施する処理 requires: - test # 指定branchにpushされた場合のみ実施 filters: branches: only: master |
全てのジョブのオーケストレーションです。
workflows: の内容に沿って各ジョブが実行されます。
今回のconfig.ymlの内容では、下記の順番でビルド、テスト、デプロイが自動実行されます。
- stagingまたはmasterのGitリモートブランチにプッシュされる。
- build: が実行される。
- test: が実行される。
- stagingのGitリモートブランチにプッシュされた場合はdeploy-staging: が実行される。
masterのGitリモートブランチにプッシュされた場合はdeploy-production: が実行される。
まとめ
SSH経由ではなくFirebaseにデプロイしたいなど様々あると思いますが、今回はAWS EC2などを想定したSSH経由でのデプロイを前提とした、.circleci/config.ymlのご紹介でした。
(ブログ執筆時では).circleci/config.ymlの最新バージョンである2.1でしか使用できないキー(commands, parameters, executors)をいくつか盛り込んでみました。
CI/CDは一度設定を書いてしまえば以降はビルド、テスト、デプロイを自動で行ってくれるため、ミス軽減や工数削減、何より本番環境へのデプロイ時の精神的な負担を和らげてくれる素晴らしいものです。
中でもCircleCIはSaaS型のため、誰でも簡単に使用できるので一度是非使ってみてください。
メルカリでも使われているようです。
コメントを残す