yikegaya’s blog

仕事関連(Webエンジニア)について書いてます

DockerでGCP Artifact Registryへのbuild環境を作った

仕事でDataflowで動かすApache BeamのPythonスクリプトを書いてたんですがコードを共通化する時にArtifact Registryを使う必要がありそうだったのでローカルでPython共通パッケージをビルドしてArtifact RegistryにpushできるDocker環境を作りました。

方針として基本ローカルにhomebrewなどでPython環境を構築していかず基本何をするにもDockerでチームメンバー間の開発環境の差分を吸収したかったのでDockerで作ってます。

用意するファイル

サービスアカウントの認証キーとenvファイル

Artifact Registryへの権限を許可したサービスアカウントの認証キーをjsonでダウンロードしてルート直下に配置する必要があります。名前は任意ですが今回はcredentials.jsonという名前で置いてます。

envファイル

.envファイルにGOOGLE_APPLICATION_CREDENTIALSいうキー名で先ほどの認証キーのパスを指定します。今回はDockerのWORKDIRを/workspaceというフォルダ名にしているので/workspace/credentials.jsonを指定します。

GOOGLE_APPLICATION_CREDENTIALS=/workspace/credentials.json

Dockerfile

pythonイメージのDockerfileです。 COPYコマンドで先ほどの認証キーを配置します。requirements.txtの内容は後述します。

FROM python:3.10

WORKDIR /workspace

COPY . .

RUN pip install -r requirements.txt

compose.yml

コンテナが1つかないのでcomposeはなくてもさほど苦労せず運用できそうですが個人的にcompose用意した方がDockerコマンドにオプション並べるよりも扱いやすいので用意してます。upコマンドでコンテナにattachしてデバッグしやすいようにcommandに tail -f /dev/nullを記載しています。

version: '3.8'

services:
  artifact_repository_python:
    build: .
    env_file: .env
    command: tail -f /dev/null
    container_name: artifact_repository_python
    volumes:
      - .:/workspace

requirements.txt

setuptools、wheel、twineはPythonの共通パッケージをビルドしてArtifact Registryにpushするのに使います。

keyringとkeyrings.google-artifactregistry-authはArtifact Registryの接続認証に必要となります。

setuptools
wheel
twine
keyring
keyrings.google-artifactregistry-auth

.gitignore

GCPの認証キーはgitに含めるとまずいのでgitignoreしてください。

また後述するPythonコードの共通パッケージをbuildする際にできるファイルもgitignoreしたいですがこの辺りの記載をそのまま使うと楽です。

github.com

共通パッケージの例

dataflow_custom_optionというApache Beamのオプションを返却する共通パッケージを作る例です。

Pythonの共通パッケージについてはここでは詳しく触れませんのでざっくり書きます。

Pythonの共通パッケージについて参考

https://packaging.python.org/ja/latest/discussions/setup-py-deprecated/ packaging.python.org

dataflow_custom_optionというフォルダを用意して以下のファイルを配置します。

setup.py

rom setuptools import setup, find_packages

setup(
    name='dataflow_custom_option',
    version="1.0.0",
    packages=find_packages(where='src'),
    package_dir={'': 'src'},
    install_requires=open('requirements.txt').read().splitlines()
)

dataflow_custom_optionフォルダに以下配置

init.py

from .custom_option import configure_pipeline_options
__all__ = ["configure_pipeline_options"]

custom_option.py

コードの中身は適当です。共通化したいコードを記述してください。

from apache_beam.options.pipeline_options import PipelineOptions

def configure_pipeline_options(job_name, gcp_project_id, runner='DataflowRunner'):
    options = PipelineOptions(
        job_name = job_name,
        runner = 'runner',
        project = gcp_project_id,
        region = 'asia-northeast1',
    )

    return options

ここまで用意したら以下コマンドでArtifact Registryにpushできます。

# ビルド
docker-compose run --rm artifact_repository_python bash -c "cd dataflow_custom_option && python setup.py sdist bdist_wheel"

# GCPのArtifact Repositoryへのpush
docker-compose run --rm artifact_repository_python twine upload --skip-existing --repository-url https://asia-northeast1-python.pkg.dev/development-severus/dataflow-python dataflow_custom_option/dist/* --verbose

pushした共通パッケージのインストール

Dockerで実行するPythonコードでArtifact Registryにpushしたコードを使う場合

使う側でもArtifact Registryへのpush環境と同じように認証付きの環境を用意する必要があります。Dockerで作る場合このようになります。

FROM python:3.10

WORKDIR /workspace

COPY . .

ENV GOOGLE_APPLICATION_CREDENTIALS /workspace/credentials.json

RUN pip install keyring keyrings.google-artifactregistry-auth
RUN pip install -r requirements.txt

requirements.txtには以下のように--extra-index-urlとしてArtifact Registryのレポジトリパスを記載します。

--extra-index-url https://asia-northeast1-python.pkg.dev/hoge-project/hoge-repository/simple
dataflow-custom-option

末尾にsimpleと付けるのはpipの仕様のようです。

packaging.python.org

コード上でのimport

from severus_dataflow_custom_option import configure_pipeline_options

options = configure_pipeline_options(job_name, gcp_project_id, runner='DirectRunner')

# Dataflowのパイプライン記載
with beam.Pipeline(options=options) as p:
            (p

以上。