CircleCI で 複数フォルダのDockerビルドを行おうとして少し詰まったので備忘録としておいておきます。
実現したかったこと
- 複数のディレクトリに対して、別々にビルドやデプロイを行いたかった
- 対象ディレクトリは Dockerfile を持っている
- rootディレクトリ から docker-compose で操作する
主に使った機能(?)
executors
同一リポジトリ内に、 CI/CD 対象が複数存在している場合は、 executors
で切り分けることができる。
ref: https://circleci.com/docs/2.0/configuration-reference/#executors-requires-version-21
executors:
first: # executor に付けた任意の名前
machine:
image: circleci/classic:edge
docker_layer_caching: true
second: # executor に付けた任意の名前
machine:
image: circleci/classic:edge
docker_layer_caching: true
environment
executors ごとに設定したい変数がある場合、 environment
で設定できる。
ref: https://circleci.com/docs/2.0/configuration-reference/#executors-requires-version-21
executors:
first: # executor に付けた任意の名前
machine:
image: circleci/classic:edge
docker_layer_caching: true
environment:
CONTAINER_REPOSITORY_NAME: iemarco-crawler-ecr # 任意の変数名
TARGET_DIR: . # 任意の変数名
SERVICE_NAME: app # 任意の変数名
parameters
parameters
を使うことで変数の宣言を行うことができる。
<< parameters.変数名 >>
とすることで、該当スコープ内で変数を使用することができる。
入っている値がそのまま評価される みたいなので、 quote 等を使う場合は "<< parameters.変数名 >>"
こういった形で使ってあげる。
ref: https://circleci.com/docs/2.0/configuration-reference/#parameters-requires-version-21
jobs:
exec_test: # job に付けた任意の名前
parameters:
executor: # 変数名
type: string # 変数の型
default: first # 初期値の設定も可能
executor: << parameters.executor >> # 変数の呼び出し
サンプル
version: 2.1
executors:
first:
machine:
image: circleci/classic:edge
docker_layer_caching: true
environment:
CONTAINER_REPOSITORY_NAME: iemarco-crawler-ecr
TARGET_DIR: ./app
SERVICE_NAME: ./app
second:
machine:
image: circleci/classic:edge
docker_layer_caching: true
environment:
CONTAINER_REPOSITORY_NAME: iemarco-crawl-batch-manager-ecr
TARGET_DIR: ./db
SERVICE_NAME: db
commands:
push_docker_image:
steps:
- run: |
eval $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
docker build -t $DOCKER_REGISTORY_HOST/$CONTAINER_REPOSITORY_NAME:$STAGE $TARGET_DIR
docker push $DOCKER_REGISTORY_HOST/$CONTAINER_REPOSITORY_NAME:$STAGE
jobs:
exec_test:
parameters:
executor:
type: string
executor: << parameters.executor >>
steps:
- checkout
- run: touch $TARGET_DIR/.env
- run: mkdir $TARGET_DIR/lib && chmod 777 $TARGET_DIR/lib
- run: docker-compose run $SERVICE_NAME shards
- run: | # environment を使って条件分岐
if [[ `cat $SERVICE_NAME` == "app" ]]; then
docker-compose run $SERVICE_NAME /bin/bash -c "./bin/micrate up";
fi
- run: docker-compose run $SERVICE_NAME crystal spec
image_push:
parameters:
executor:
type: string
executor: << parameters.executor >>
environment:
STAGE: production
steps:
- checkout
- push_docker_image
workflows:
build_and_test:
jobs:
- exec_test:
executor: first
- image_push:
executor: first
filters:
branches:
only:
- master
requires:
- exec_test
build_and_test_for_second:
jobs:
- exec_test:
executor: second
- image_push:
executor: second
filters:
branches:
only:
- master
requires:
- exec_test
もっと良い感じの書き方があれば教えていただきたいですm(_ _)m
主に jobs でexecutor を毎回渡してるところとかをすっきりさせたい…