dbtを手軽に試す!Dockerを利用してPostgreSQLと一緒に簡単セットアップ

2023.12.01

データアナリティクス事業本部のueharaです。

dbt、最近勢いがありますね。

  • 「ちょっとdbtを触ってみたい」
  • 「けど開発環境はあんまり汚したくない...」

このように思っている方も多いのではないでしょうか。

今回は、Dockerを利用してdbtをPostgreSQLと一緒に簡単セットアップする方法をご紹介したいと思います。

※Dockerが既に実行できる環境を想定しておりますので、準備がまだの方はインストール案内ページなどを参考に、ご準備お願いします。

はじめに

今回はDocker Composeを利用して、以下の環境を立ち上げます。

ファイルの準備

今回作成するファイルの構成は以下の通りです。

「dbt」は空のフォルダを作成して下さい。

.
├ dbt (空のフォルダ)
├ compose.yml
├ Dockerfile
├ profiles.yml.tmpl
└ requirements.txt

compose.yml

compose.ymlは以下のように記載します。

compose.yml

services:  
  dbt:
    build: 
      context: .
      dockerfile: Dockerfile
    container_name: my_dbt
    volumes:
      - ./dbt:/dbt
    environment: 
      DB_HOST: postgres
      DB_PORT: 5432
      DB_USER: test_user
      DB_PASSWORD: test_pass
      DB_NAME: dbt_dev
    depends_on: 
      - postgres
    tty: true

  postgres:
    image: postgres:latest
    container_name: my_postgres
    environment: 
      POSTGRES_USER: test_user
      POSTGRES_PASSWORD: test_pass
      POSTGRES_DB: dbt_dev
    ports:
      - "5432:5432"

dbtコンテナのDockerイメージは、後に記載するDockerfileからビルドします。

また、先に作成したローカルの./dbtフォルダを、コンテナ内の/dbtにマウントするよう設定しています。

その他、dbtのコンテナは環境変数でDBのユーザ名やパスワードの値を設定しています。こちらはお好きに変更して下さい。

PostgreSQLコンテナでは、dbtコンテナで指定したものと同じユーザ名やパスワードを環境変数で指定します。

また、ローカルのDBeaverなどのSQLクライアントからアクセスしたいので、ホストの5432番のポートをPostgresQLコンテナの5432ポートにフォワードするよう設定しています。

Dockerfile

dbt用のイメージはPythonのイメージから作成します。

Dockerfile

FROM python:3.11

# ワーキングディレクトリを設定
WORKDIR /dbt

# pythonのライブラリをインストール
COPY requirements.txt /tmp/requirements.txt
RUN pip install --no-cache-dir -r /tmp/requirements.txt

# envsubst利用のためインストール
RUN apt-get update && apt-get install -y gettext-base

# profilesのテンプレート用意
COPY profiles.yml.tmpl /tmp/profiles.yml.tmpl
RUN mkdir ~/.dbt

ENTRYPOINT [ "/bin/sh", "-c" ]

# プロジェクトの作成
CMD ["envsubst < /tmp/profiles.yml.tmpl > ~/.dbt/profiles.yml && \
      dbt init dbt_dev --profile dbt_dev --target /dbt && \
      tail -f /dev/null"]

それぞれやっていることの大枠はコメントに記載の通りです。

profiles.yml.tmpl

profiles.yml.tmplは、dbt Core (CLI)で必要となる設定ファイルであるprofiles.ymlのテンプレートファイルになります。

profiles.yml.tmpl

dbt_dev:
  target: dev
  outputs:
    dev:
      type: postgres
      host: ${DB_HOST}
      user: ${DB_USER}
      password: ${DB_PASSWORD}
      port: ${DB_PORT}
      dbname: ${DB_NAME}
      schema: public
      threads: 1
      keepalives_idle: 0
      connect_timeout: 10

profiles.ymlはdbtからPostgreSQLに接続する際の認証情報等が記載される設定ファイルですが、profiles.yml.tmplはその設定値を環境変数の値を代入するようなテンプレートになっています。

Dockerfileのenvsubst < /tmp/profiles.yml.tmpl > ~/.dbt/profiles.ymlという処理にて、テンプレートファイルから実際のprofiles.ymlを作成しています。

requirements.txt

requirements.txtはdbtイメージ作成時に含めたいPythonモジュールを記載するファイルになります。

今回は単にdbt-postgresを記載します。

requirements.txt

dbt-postgres

以上でファイルの準備は完了です。

環境の立ち上げ

環境の立ち上げは、compose.ymlを作成したフォルダにて以下のコマンドを実行するだけです。

$ docker-compose up --build -d

以下コマンドで、my_dbtmy_postgresという名前のコンテナが作成できているか確認して下さい。

$ docker container ls

dbtを動かしてみる

環境が立ち上がると、./dbtにdbtのプロジェクトファイルが作成されていると思います。

.
├ dbt
│ ├ dbt_dev   # これ 
│ └ logs
├ ...

今回作成したdbt_devフォルダの中にmodelsseedsなどのフォルダが含まれていると思います。

試しに、seedsにcsvファイルを置いて、dbt seedコマンドの実行を確認してみたいと思います。

まず、dbt公式チュートリアルで公開されているraw_customers.csvを「./dbt/dbt_dev/seeds」に格納します。

次に、my_dbtコンテナに入ります。

以下コマンドでコンテナ内に入ることができます。

$ docker exec -it my_dbt bash

コンテナに入ると、開始時のディレクトリは/dbtになっていると思います。

プロジェクトフォルダに移動して、dbt seedコマンドを実行します。

# プロジェクトフォルダに移動
$ cd dbt_dev

# コマンド実行
$ dbt seed

実行結果が以下のように表示されていれば、ロードが成功しています。

12:15:13  Running with dbt=1.7.3
12:15:14  Registered adapter: postgres=1.7.3
12:15:14  Unable to do partial parsing because saved manifest not found. Starting full parse.
12:15:14  Found 2 models, 1 seed, 4 tests, 0 sources, 0 exposures, 0 metrics, 401 macros, 0 groups, 0 semantic models
12:15:14  
12:15:14  Concurrency: 1 threads (target='dev')
12:15:14  
12:15:14  1 of 1 START seed file public.raw_customers .................................... [RUN]
12:15:14  1 of 1 OK loaded seed file public.raw_customers ................................ [INSERT 100 in 0.09s]
12:15:14  
12:15:14  Finished running 1 seed in 0 hours 0 minutes and 0.25 seconds (0.25s).
12:15:14  
12:15:14  Completed successfully
12:15:14  
12:15:14  Done. PASS=1 WARN=0 ERROR=0 SKIP=0 TOTAL=1

データを確認してみる

今回はDBeaverを利用して、PostgreSQLのデータを確認したいと思います。

接続設定にて、compose.ymlファイルで指定したDB名・ユーザ名・パスワードなどの情報を設定します。

接続ができたらSQLを実行してデータの中身を見てみます。

期待通りの結果が出力できています!

もちろんdbt rundbt testも実行できるので、壊れても良い検証用環境ですので色々いじってみると良いと思います。

最後に

今回は、Dockerを利用してdbtをPostgreSQLと一緒に簡単セットアップする方法をご紹介してみました。

参考になりましたら幸いです。

参考文献