この記事は
プライベートリポジトリをクローンするためのSSHの秘密鍵をSecretsに登録し、それを docker/build-pusht-actions で利用してコンテナをビルド・プッシュする方法です。
参考記事
GitHub Actionsのワークフローでプライベートリポジトリをクローンするよう方法やsecretsへの登録は以下の記事を参考にしてください。
- GithubActionsでプライベートリポジトリをsubmoduleとして取り込む#ssh方式
- docker buildする際にhost側のssh keyを使ってbuildする
- GitHub Actionsでビルドするコンテナ内でGitHubのprivate repositoryをセキュアに参照する
3つ目の記事とやりたいことはほぼ同じですが、docker buildを独自ステップとして実装されています。
今回はこれを docker/build-push-action
で実現します。
docker/build-push-action でホストのSSH鍵を利用してプライベートリポジトリにアクセスする
https://github.com/docker/build-push-action#customizing の ssh: default
を利用します。
- uses: docker/build-push-action@v3
with:
push: true
tags: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:latest
ssh: default
ただし、このままでは SSH_AUTH_SOCK
がない旨のエラーになり秘密鍵を共有できません。
事前にSSHエージェントを起動、 ssh-add
しておき、docker/build-push-action
から参照できるようにしておく必要があります。
eval $(ssh-agent -s)
することでSSHエージェントが起動し SSH_AUTH_SOCK
が設定されます。
これを環境変数に設定(GITHUB_ENVに追加)することで build-push-action
のステップでも利用できるようにします。
- name: Set ENV for docker build
env:
TOKEN: ${{ secrets.TOKEN }}
run: |
mkdir -p ~/.ssh
echo "$TOKEN" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_rsa
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> $GITHUB_ENV
共有された秘密鍵を利用してgit cloneする場合、Dockerfileでは以下のようにします。
RUN --mount=type=ssh git clone xxx
AWS ECRにCDするGitHub Actionsワークフローサンプル
メインブランチが更新され、CIが成功した場合にECRに向けたCDを走らせる例です。
ビルドキャッシュも利用しています。
ECRにプッシュするため事前にECRログインが必要なので、そのためのAWS CredentialsもSecretsに登録しています。
---
name: cd
on:
workflow_dispatch:
workflow_run:
workflows:
- "ci"
branches:
- main
types:
- "completed"
env:
ECR_REPOSITORY: ogawatti/test
jobs:
build-and-deploy:
runs-on: ubuntu-latest
if: ${{ github.event.workflow_run.conclusion == 'success' }}
steps:
- uses: actions/checkout@v3
- uses: docker/setup-buildx-action@v1
- uses: actions/cache@v2
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
- name: Set ENV for docker build
env:
TOKEN: ${{ secrets.TOKEN }}
run: |
mkdir -p ~/.ssh
echo "$TOKEN" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
eval $(ssh-agent -s)
ssh-add ~/.ssh/id_rsa
echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> $GITHUB_ENV
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ap-northeast-1
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- uses: docker/build-push-action@v3
with:
push: true
tags: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPOSITORY }}:latest
ssh: default
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max
- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
ハマりどころ
ステップ内では ***
のように秘匿してくれますが、これを ENV
や build-args
等でビルドに渡すことはできません。
正確には、改行付きのSecretsを渡した場合に中身がどうなっているかが分かりませんでした。
ビルド中にコンテナ内で書き出した秘密鍵を ssh-add
しようとしても invalid format
になってしまい、 head
等で確認しようにも、書き出された値が空だったり秘匿されていたりでデバッグがかなり苦しい。
ローカルでのビルドでは build-args
を利用していたためそちらの方向で考えていましたが断念し、正攻法(?)で行くことになりました。