create-react-appで作成したreactアプリをCircleCI2.0でS3にデプロイしようとしたときにハマったのでメモ。
S3側の設定などはcreate-react-appのREADMEのS3のデプロイ でも言及されているblog post が参考になります。
ハマった点
ハマった点は2点あります。
1. deployのjobとbuildのjobを分けてしまうとbulidのjobで作成した生成物が引き継がれない
上述のblog postには
- Install the AWS CLI.
- Create security credentails
- Configure the CLI with
aws configure
.
とあるので、CircleCIのビルドjobに上記のコマンドを入れましたが、うまくいきませんでした。
そのときのymlは以下のとおりです。
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/node:9.11
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
working_directory: ~/repo
steps:
- checkout
# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run: yarn install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
# run tests!
- run: yarn test
# build
- run: yarn run build
deploy-master:
machine:
enabled: true
working_directory: ~/repo
steps:
- run: ls -alt # ☆何もない
- run: aws s3 sync ./build s3://production.example.com --delete
deploy-staging:
machine:
enabled: true
working_directory: ~/repo
steps:
- run: ls -alt # ☆何もない
- run: aws s3 sync ./build s3://staging.example.com --delete
workflows:
version: 2
build-deploy:
jobs:
- build
- deploy-master:
requires:
- build
filters:
branches:
only: master
- deploy-staging:
requires:
- build
filters:
branches:
only: develop
build, deploy-master, deploy-stagingの3つのjobを定義して、ワークフローでブランチがmasterだったらdeploy-masterのjobを実行、ブランチがdevelopだったらdeploy-stagingのjobを実行するというにしています。しかしこれだとうまく動作しませんでした。
buildのjobはうまく動作しますが、deploy-masterまたはdeploy-stagingのlsコマンドの結果はファイルなしでした。buildしたパッケージはありませんでした。
jobをまたいでbuildパッケージを利用できない、つまりbuildのjobでbuildしたパッケージを他のjobで利用できないため、別のやり方に変更しなければいけません。
2. CircleCIのnodeのイメージを利用したときawscliのインストールに手間取った
↑のymlでawsコマンドがないとエラーになりました。awscliをインストールする必要があります。
awscliのインストールをしようとしたらpipがないとのエラーが出たのでpython3をインストールしたもののpipのパスが通っていないとのエラーになりました。
そのためPATH=$PATH:/home/circleci/.local/bin; export PATH
をjobのタスクに追加することで解決しました。
awscliがインストールされてあるカスタムしたDockerイメージを使えばいいのですが、今回はCircleCIのイメージで頑張ってみました。
なお、AWSのクレデンシャルをCircleCIで設定するのを忘れずに。
S3にアップロードできる権限が必要なので、IAMでユーザを作成してアクセスキーIDとシークレットアクセスキーをCircleCIに登録しておきます。
.circleci/config.yml
最終的なymlは以下になります。
# Javascript Node CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-javascript/ for more details
#
version: 2
jobs:
build:
docker:
# specify the version you desire here
- image: circleci/node:9.11
# Specify service dependencies here if necessary
# CircleCI maintains a library of pre-built images
# documented at https://circleci.com/docs/2.0/circleci-images/
# - image: circleci/mongo:3.4.4
working_directory: ~/repo
steps:
- checkout
# Download and cache dependencies
- restore_cache:
keys:
- v1-dependencies-{{ checksum "package.json" }}
# fallback to using the latest cache if no exact match is found
- v1-dependencies-
- run: yarn install
- save_cache:
paths:
- node_modules
key: v1-dependencies-{{ checksum "package.json" }}
# run tests!
- run: yarn test
# build
- run: yarn build
- deploy:
command: |
PATH=$PATH:/home/circleci/.local/bin; export PATH
sudo apt-get -y -qq update
sudo apt-get -y -qq install python3 python3-dev
sudo curl -O https://bootstrap.pypa.io/get-pip.py
python3 get-pip.py --user
pip install awscli --upgrade --user
if [ "${CIRCLE_BRANCH}" == "master" ]; then
aws s3 sync ./build s3://production.example.com --delete
elif [ "${CIRCLE_BRANCH}" == "develop" ]; then
aws s3 sync ./build s3://staging.example.com --delete
fi
workflowを定義せず、buildのjobにdeployのタスクを含めました。
そうすることによってyarn buildでbuildしたパッケージを参照することができます。
pushされたブランチに応じてデプロイ先のS3バケットを変更してデプロイしています。
以上、create-react-appで作ったアプリケーションのS3デプロイの参考になれば幸いです。