はじめに
以前、業務でBedrockにある複数のモデルを切り替えできるよう作成した自作パッケージをDockerfileにpip installできたらなと思って実施したのが今回の記事になります。
1.ビルド時の認証トークンの渡し方
次の方法で、DockerfileでCodeArtifactからパッケージをインストールすることは可能ですが、前者はイメージ内に認証トークンが残ってしまうため、セキュリティ上よろしくないです。
そこで、後者の方法で機密情報をイメージ内に残すことなく渡すことができるため、比較的安全にCodeArtifactから自作パッケージをインストールすることができます(※)。
なお、
今回は以下のサイトを参考に後者の方法で自作パッケージをインストールしてみます。
- ARGやENVを用いて認証トークンを渡す
- Docker Build Secrets経由で認証トークンを渡す
【※注意事項】
通常の pip install では漏洩しませんが、デバッグ実行やログ出力、古いバージョンの pip の使用によって認証情報が漏洩する可能性もあるため、開発環境・CI環境を問わず、認証トークンの扱いには十分注意が必要です。
2.Docker Build Secretsを利用した自作パッケージのインストール
2.1.Docker Engineのバージョン確認
今回の方法では、Docker Engineはv27.3.0以降を利用しています。これは2.3に記載のビルドスクリプトにあるBuild Secretsのenvオプションがv27.3.0以降でないとサポートされていないためです。
最初、検証する際に以下のエラーに遭遇しましたが、これはDockerが「env」を知らないものだと認識したため、ビルドができずにいました。
unexpected key 'env' in 'env=PIP_EXTRA_INDEX_URL'
以下のサイトを参考にDocker Engineのバージョンを変えることでビルドが通るようになりました。
2.2.Dockerfile
以下のようなDockerfileを作成しています。
- Build Secrets等のBuildKitの機能を利用するため、syntax ディレクティブを先頭に追加する
- mountオプションを利用し、一時的にCodeArtifactの認証情報をマウントする
# syntax=docker/dockerfile:1.10.0
FROM python:3.12-slim
RUN apt-get update && apt-get install -y \
build-essential \
libssl-dev \
libffi-dev \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /app
# Python 依存パッケージ(自作パッケージも含む)
COPY requirements.txt .
# mountオプションを利用することで、一時的に認証情報をマウントし、
# イメージに残さないようにする
RUN --mount=type=secret,id=ca_url,env=PIP_EXTRA_INDEX_URL \
pip install --no-cache-dir -r requirements.txt
COPY worker.py .
CMD ["python", "worker.py"]
2.3.Dockerビルド及び自作パッケージのインストール
CodeArtifact認証トークンを取得し、そのトークンをBuild Secrets経由でDockerfileに渡します。
ビルド中はこの認証トークンを利用しながらCodeArtifactから自作パッケージをインストールします。
CodeArtifact認証トークンを取得するスクリプト
#!/bin/bash
set -e
CODEART_TOKEN=$(aws codeartifact get-authorization-token \
--domain ${CODEART_DOMAIN} \
--query authorizationToken \
--output text)
# $PIP_EXTRA_INDEX_URLでCodeArtifact内にあるパッケージのURLを設定する。
# そして、exec "$@"により、この URL を Docker ビルド時の secret として利用できる。
PIP_EXTRA_INDEX_URL="https://aws:$CODEART_TOKEN@$CODEART_DOMAIN-$ACCOUNT_ID.d.codeartifact.$CODEART_REGION.amazonaws.com/pypi/$CODEART_REPO/simple/" \
exec "$@"
Docker Buildスクリプト
#!/bin/bash
set -e
# setup_codeartifact.sh を実行し、$PIP_EXTRA_INDEX_URL の値を設定し、
# Dockerfileの$PIP_EXTRA_INDEX_URLに渡す。
./setup_codeartifact.sh docker build . -t worker:latest --secret id=ca_url,env=PIP_EXTRA_INDEX_URL
docker tag worker:latest
さいごに
改めて整理しますと、以下のように対応することで、CodeArtifact内のパッケージをDockerfileでもインストールできるようになります。
- Docker Engineのバージョンはv27.3.0以降にする
- Dockerfileにsyntaxディレクティブを明記する
- mountオプションを用いて認証情報を連携する
これで自作のパッケージをDockerでも利用できるようになり、Dockerの旨味も活かせるようになりました。また、Docker Build Secrets経由で認証情報をイメージに焼きこむことなく渡し、比較的安全にインストールもできるようになりました。