概要
Rails
の環境をECS
で作成する際、多くの開発者がmaster.key
をコンテナーに環境変変数として設置すると思います。この方法でも問題ないですが、コンテナーの環境変数を使用したくないと言う要望もあるかと思い、表題の方法について手順を書きたいと思います。
前提条件
-
Docker
のバージョンが18.09
以上である -
Ruby on Rails
の環境がある -
GitHub Actions
が導入されている -
Docker
を使用して、Ruby on Rails
の環境立ち上がっている
GitHubの設定
-
Settings
を押下すると、サイドバーにSecrets and variables
がある。その中にActions
がある為、そこに環境変数を入れる
-
GitHub
の権限設定によっては、settings
の管理画面が見れない可能性があります。その場合は、管理者に問い合わせて下さい - 必要に応じて環境変数を作成して下さい
GitHub Actions
-
config
のディレクトリーに、master.key
のファイルを作成する -
master.key
のファイル内に、暗号化キーを書き込む
- name: Create rails master key for build
run: |
touch $GITHUB_WORKSPACE/config/master.key
echo ${{ secrets.RAILS_MASTER_KEY }} > $GITHUB_WORKSPACE/config/master.key
# $GITHUB_WORKSPACE: .githubが置いてある場所をルートディレクトリーと定義している
-
env
に 環境変数を設定する -
Docker
のバージョンが18.09
以降であれば、BuildKit
と言う機能を使う事ができる -
BuildKit
の機能を使用する事で、秘密情報(今回の場合、master.key
)をECR
のimage
に安全に渡す事ができる
(imgae
内に、master.key
の情報が含まれない為、image
からmaster.key
の情報が漏洩しない)
- name: Build, tag, and push image to Amazon ECR
id: build-image
env:
DOCKER_BUILDKIT: 1
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
REPOSITORY: "<ECRリポジトリ名>"
IMAGE_TAG: ${{ github.sha }}-${{ github.run_id }}
run: |
docker buildx create --use
docker buildx build \
--secret id=master_key,src=$GITHUB_WORKSPACE/config/master.key \
-t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG \
--push \
-f containers/production/Dockerfile .
echo "image=$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG" >> $GITHUB_OUTPUT
# -f containers/production/Dockerfile . :各々のリポジトリーの構成に合わせて修正して下さい
REPOSITORYは環境変数に設定する事を推奨する
BuildKitの概要
-
Docker
イメージのビルドや他のビルドプロセスを効率的に行う為のツール - 通常のビルドよりも並列処理やキャッシュの利用が優れており、ビルド時間を大幅に短縮できるのが特徴
-
BuildKit
は、buildkitd
(デーモン)とbuildctl
(クライアント)から構成されている
主な機能
-
キャッシュ効率の向上 : ビルドの各ステップを細かくキャッシュし、再ビルド時には変更された部分だけを再実行する。これにより、無駄なビルドを避け、時間を短縮出来る
-
並列処理 : 複数のビルドステップを並列に実行する事ができ、
CPU
リソースを効率的に活用出来る。これにより、ビルドの速度が向上する -
Dockerfile
を使った柔軟なビルド :Dockerfile
をビルドの定義として利用するが、独自の中間フォーマット(LLB
)に変換してビルドを実行する。これにより、複雑な依存関係の管理が簡単になる -
シークレットやSSHキーの安全な取り扱い : ビルド時にシークレットファイル(例:
API
キー)やSSH
キーを安全に取り扱う事が出来る。ビルドの際、外部に機密情報が漏れなくなる為、セキュリティが強化出来る
補足
-
buildkitd
(デーモン) : BuildKitのビルドエンジンとして機能している。リクエストを受け取って、ビルドを実行し、ビルドの各ステップを処理する -
buildctl
(クライアント) : ユーザーがビルドリクエストを送信する為のインターフェース。ユーザーがCLI
を使ってビルドを開始したり、オプションを設定したりする際に、このbuildctl
コマンドを使用する -
LLB
(Low-Level Build) : ビルドの処理手順や依存関係を効率的に管理する為の中間フォーマット。通常、Dockerfile
を使ってビルドを行う際、各コマンド(FROM
,RUN
,COPY
など)はそのまま実行されるが、BuildKit
はこれらの命令を一旦LLB
形式に変換してからビルドを実行する
Dockerfile
-
Dockerfile
でもBuildKit
を使用して、image
を作成する
# master.keyをコピー
RUN --mount=type=secret,id=master_key,target=master.key,required=true \
rails assets:precompile RAILS_ENV=Production
コマンドの叩き方
# Dockerfileのファイルパスを指定するコマンド
DOCKER_BUILDKIT=1 docker build --no-cache --secret id=master_key,src=path/to/master.key -t rilas_image -f build_files/porduction/Dockerfile .
# または
# Dockerfileのがカレントディレクトリにある場合のコマンド
DOCKER_BUILDKIT=1 docker build --no-cache --secret id=master_key,src=path/to/master.key -t rilas_image .
コマンドの構造
- BuildKitを有効にする為の環境変数。このオプションを設定すると、
BuildKit
の機能が使用可能となる
DOCKER_BUILDKIT=1
- Dockerイメージをビルドする標準的なコマンド
docker build
- キャッシュを使わずに、常に新しいビルドを行うオプション。
BuildKit
はキャッシュ機能が強力ですが、キャッシュを使いたくない場合に下記を指定する
--no-cache
- ビルド中に シークレット情報(ここでは
master_key
)を安全に使う為の仕組み。path/to/master.key
というファイルに保存された秘密情報(例: APIキーや暗号キー)をDocker
ビルド中で参照するが、この情報は外部に漏れない様に保護された状態で処理される。シークレット情報は、ビルドが終わると自動的に削除され、外部には見えない様になる - 要約 : ビルド中に一時的に鍵やパスワードを使いたい際、セキュリティを確保しながらそれらを渡す方法
--secret id=master_key,src=path/to/master.key
# 相対パスの書き方 : src=path/~/master.key
# 絶対パスの書き方 : src=/Users/test/path/~/master.key
# 先頭に/が入ると絶対パスでの指定になる
出力されるDocker
イメージにrails_imageという名前を付与する。名前は任意で決めてよい
-t rails_image
- 現在のディレクトリをビルドコンテキストとして指定する。現在のいるディレクトリからDockerfileを探す
.
- ビルドに使用するDockerfileの場所を指定する
-f build_files/porduction/Dockerfile .
参考資料
- Railsのcredentials.yml.encとmaster keyをDockerで安全に扱う
- docker buildkitを使いecsで本番モードでrailsを起動させる方法(master.keyの配送方法など)
- [公式] docker buildx build
- [公式] buildx を使ったビルド
- [公式] BuildKit
- Dockerに統合されたBuildKitのLLB (low-level builder)の仕様を探ってみよう
まとめ
GitHub Actions
の理解やBuildKit
と言うDockerの新たな機能について知見が増えました。BuildKit
に関して、セキュアなコンテナーを作成する以外にも様々使い道がありそうなので、いろいろい試して見たいと思います。