Airflowをdevcontainerで動かす手順をまとめたメモです。

Airflowのverionは、3.0.0を想定します。

想定する開発の流れ・作成する環境

poetryなどを使えば環境を用意できるので、
devcontainerで屋上屋を架す必要は無いのですが、
macosでは上手く動かなかったので、
ここではcontainerを利用することにしました。

コーディングや単体テストはdevcontainerを使わず、
AirflowからのDAGの動作確認をする時にdevcontainerを利用することを想定します。
そのため、コーディング・単体テストに必要名パッケージはpyproject.tomlで管理します。

また、vscode依存を避けるため、devcontainer-cliを利用します。

ディレクトリ構成・ファイルの内容

作成する環境のディレクトリ構成と各種ファイルの内容を示します。

ディレクトリ構成

repotitory-root/

  • .devcontainer/
    • devcontainer.json
    • Dockerfile
    • requirements.txt
    • dev-requirements.txt
    • simple_auth_manager_passwords.json
    • Makefile
  • src/
    • dags/
    • plugins/
  • logs/
  • pyproject.toml
  • poetry.lock

ファイルの内容

.devcontainer/devcontainer.json

{
  "build": {
    "dockerfile": "Dockerfile"
  },
  "appPort": [8080],
  "mounts": [
    {
      "source": "${localWorkspaceFolder}/src/dags",
      "target": "/opt/airflow/dags",
      "type": "bind", "consistency": "cached"
    },
    {
      "source": "${localWorkspaceFolder}/src/plugins",
      "target": "/opt/airflow/plugins",
      "type": "bind", "consistency": "cached"
    },
    {
      "source": "${localWorkspaceFolder}/logs",
      "target": "/opt/airflow/logs",
      "type": "bind", "consistency": "cached"
    },
    {
      "source": "${localWorkspaceFolder}/.devcontainer/simple_auth_manager_passwords.json",
      "target": "/opt/airflow/simple_auth_manager_passwords.json.generated",
      "type": "bind", "consistency": "cached"
    }
  ]
}

.devcontainer/Dockerfile

FROM apache/airflow:3.0.0
COPY requirements.txt requirements.txt
COPY dev-requirements.txt dev-requirements.txt
RUN pip install -r requirements.txt -r dev-requirements.txt

.devcontainer/simple_auth_manager_passwords.json

{"admin": "admin"}

pyproject.toml

[project]
name = "airflow-devcontainer-study"
dependencies = [
]
requires-python = "==3.12.10"

[tool.poetry]
package-mode = false

[tool.poetry.requires-plugins]
poetry-plugin-export = ">=1.8"

[tool.poetry.group.dev.dependencies]

環境構築の前提

ここでは、前提としてpyenv,docker,devcontainer-cliのセットアップされていることとします。

環境構築の手順

環境構築の手順を示します。

ディレクトリ・各種ファイルの準備

作業ディレクトリと配下のディレクトリを作成します。

$ mkdir airflow-devcontainer-study && cd $_
$ mkdir {src,logs,.devcontainer} src/{dags,plugins}
$ touch src/{dags,plugins}/.gitkeep logs/.gitkeep .devcontainer/{requirements.txt,dev-requirements.txt}

必要なファイルを作ります、内容は前述(ファイルの内容)の通り。

  • .devcontainer/devcontainer.json
  • .devcontainer/Dockerfile
  • .devcontainer/simple_auth_manager_passwords.json
  • pyproject.toml

devcontainerの環境をpyproject.tomlに反映

devcontainer内のPythonのversionを確認して、pyproject.tomlの「requires-python」を書き換えます。
※ここでは、3.12.10で揃っているので書き換えは不要。

$ devcontainer up --workspace-folder .
$ devcontainer exec --workspace-folder . python --version
Python 3.12.10

Pythonのインストール・仮想環境作成・パッケージのインストールを行います。

$ pyenv install 3.12.10
$ pyenv local 3.12.10
$ pip install poetry
$ python -m venv .venv
$ poetry install

devcontainer内のPythonのpackageを、pyproject.tomlに追加する。

$ poetry add $(devcontainer exec --workspace-folder . pip freeze)

手元の環境では、mysql-clientの追加でエラーがでましたが、利用しないので、次のように除外してすすめています。

$ poetry add $(devcontainer exec --workspace-folder . pip freeze | grep -v mysql)

パッケージ追加とdevcontainerへの反映

必要なパッケージがあれば、追加します。 次のコマンドは、devグループにruff,pytestを追加する場合の例。

$ poetry add ruff pytest -D

devcontainerにもパッケージを追加するために、requrements.txt,dev-requirements.txtにも反映します。

$ poetry export -o .devcontainer/requirements.txt --without-hashes --without=dev
$ poetry export -o .devcontainer/dev-requirements.txt --without-hashes --only=dev

devcontainerを作り直せば、devcontainer側にも反映されます。

$ docker ps -a | grep $(basename $(pwd)) | awk '{print $1}' | xargs docker rm -f
$ devcontainer up --workspace-folder .
$ devcontainer exec --workspace-folder . pip freeze | grep ruff
ruff==0.11.8

devcontainerの使い方

devcontainerの使い方は、以下の通りです。

devcontainerの起動

devcontainer up --workspace-folder .

devcontainerの終了

docker ps -a | grep $(basename $(pwd)) | awk '{print $1}' | xargs docker stop

devcontainerの削除

docker ps -a | grep $(basename $(pwd)) | awk '{print $1}' | xargs docker rm -f

Airflowの実行
(AirflowのUIはhttp://localhost:8080/からUser/Password=admin/adminでログイン)

devcontainer exec --workspace-folder . airflow standalone

devcontainer内のbashで作業をする場合

devcontainer exec --workspace-folder . bash

devcontainer-cliに終了・削除のサブコマンドが無く、ちょっと面倒なので、
例えば、次のようなMakefileを用意するなどした方が良いと思います。

.devcontainer/Makefile

.PHONY: up down rm bash airflow

up:
	devcontainer up --workspace-folder ..

down:
	docker ps -a | grep $$(basename $$(dirname $$(pwd))) | awk '{print $$1}' | xargs docker stop

rm:
	docker ps -a | grep $$(basename $$(dirname $$(pwd))) | awk '{print $$1}' | xargs docker rm -f

bash: up
	devcontainer exec --workspace-folder .. bash

airflow: up
	devcontainer exec --workspace-folder .. airflow standalone

以上。