はじめに
GitHub Actions、便利ですよね
ソースコードの変更後、いちいち手元でdocker buildしてpushなんてやってられないですし、
外部CIツールを新たに導入するよりは全部GitHub内で完結してたほうがシンプルです。
しかしながら別のprivate repositoryにある社内用ライブラリを持ってくるのが地味に面倒だったのでやり方を書きます
1行で
リポジトリsecretsにトークンを入れてBuild-time secretsでコンテナ内に注入
説明
認証方法
GitHub→GitHub内とは言え認証は必要です
httpsかsshで認証することになります
権限を細かく絞れるためトークンを介するhttps接続の方が良いと思います
https
下記記事のようにトークンを作成し、トークンを用いて認証します
この際、個人ユーザのトークンを利用するとアカウント削除時にトークンが使えなくなりそうなので、マシンユーザを作成してそちらでトークンを作成します。マシンユーザがcloneしたいリポジトリのread権限を持っている必要があります
Dockerfileのbuildで簡単にGithubのプライベートリポジトリをクローンする方法 - Qiita
https://qiita.com/Jah524/items/fa68f99c8b787f94b884
ssh
GitHubに登録してある公開鍵に対応する秘密鍵をコンテナ内に入れてしまえば接続はできます
ただユーザに許可されている全権限がついてしまうので、トークンを利用したほうがより安全ですね
Build-time secrets
リポジトリにトークンを直書きするのはもちろん、docker build
の--build-arg
に渡す方法も安全であるとは言えません
Build-time secretsという機能があるのでこちらを使いましょう
Docker Engine 18.09 から使える Build-time secrets を試してみた | はったりエンジニアの備忘録
https://blog.manabusakai.com/2018/12/docker-build-secret/
コンテナにsecretsを渡す
下記ドキュメントにrepo-token
で渡すとあるので、そうすればいいのかと思ってしまいがちなのですが(1敗)、
この形で渡したトークンはActionsの中のcloneで使えるだけなので、コンテナに渡す場合は普通にenv
を使います
GITHUB_TOKENでの認証 - GitHub ヘルプ
https://help.github.com/ja/actions/configuring-and-managing-workflows/authenticating-with-the-github_token
steps:
- uses: actions/labeler@v2
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
コード
事前にリポジトリのsecretsにMACHINE_USER_TOKEN
の名前でトークンを入れておきます
下記のようにファイルの形でコンテナにトークンを渡します
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
TOKEN: ${{ secrets.MACHINE_USER_TOKEN }}
run: |
echo $TOKEN >> .token
DOCKER_BUILDKIT=1 docker build --secret id=token,src=.token \
-t $ECR_REGISTRY/$ECR_REPOSITORY:latest \
.
rm .token
docker push $ECR_REGISTRY/$ECR_REPOSITORY:latest
Dockerfileの1行目にマジックコメントを入れます
# syntax = docker/dockerfile:1.0-experimental
Dockerfileでは下記のように受け取ります
pyproject.tomlにはssh形式でパスを入れておく想定で(どちらでもいいのですが手元で作業する分にはsshのほうが便利)
それを置換してトークンを入れています
COPY pyproject.toml .
RUN --mount=type=secret,id=token TOKEN=$(cat /run/secrets/token) \
&& sed -i "s/ssh:\/\/git@github.com/https:\/\/$TOKEN@github.com/g" pyproject.toml \
&& pip install . && rm pyproject.toml
[tool.poetry.dependencies]
<tool_name> = {git = "ssh://git@github.com/<org>/<repo>.git", tag = "1.0"}
GithubActionsのログにも秘匿化された状態で出力されています
#18 9.075 Collecting <tool_name>@ git+https://***@github.com/<略>
まとめ
Build-time secretsでクレデンシャルを安全に扱いましょう
https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information