TL;DR
インフラやアプリの理解を深めるために、勉強も兼ねてDocker-Flask-PostgreSQLで下記の図のようにインフラを構築してみました。
緑色に部分が実現したい場所であり、青色の部分が今回記事にしたものです。
一通り動くところまでの手順と、エラーが出たところやそこをどう改善したのかをまとめました。
以下のリポジトリにサンプルコードを公開しました。フォルダ構成や記事の中で出てこないファイルなどはこちらをご覧ください。
サンプルコード→ https://github.com/hiseumn/flask-postgresql-sample
インフラの設定と実行
個々のDockerコンテナの説明
Nginx
以下はDocker-compose.ymlのnginxの抜粋です。
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./for_develop/nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- flask
-
nginx
はサービス名なので、わかりやすいものであれば何でもいいです。 -
image
はDocker Hubから最新のイメージを落としてきて使用します。
詳細はここからみれます。https://hub.docker.com/ -
ports
はホストのポート80をコンテナのポート80にマッピングします。ホストのポート80へのリクエストがNginxコンテナに転送されます。ブラウザでhttp://localhost にアクセスすると、そのリクエストはNginxコンテナのポート80で処理されます。 -
volumes
はホストシステムとコンテナ間でデータを共有するために使用されます。ローカルの./for_develop/nginx/nginx.confファイルをコンテナ内の/etc/nginx/nginx.confにマウントします。マウントとは、コンピュータシステムにおいてファイルシステムやディレクトリ、デバイスなどを特定の場所に接続して、アクセス可能にする操作を指します。これにより、自分のユースケースに合わせたユーザーやアプリケーションがデータやリソースを利用できるようになります。これにより、カスタムNginx設定を使用できます。 -
depends_on
は、サービスの依存状態を設定することができます。この場合、NginxコンテナはFlaskコンテナに依存しており、NginxコンテナはFlaskコンテナが起動してから起動します。
events{
worker_connections 1024;
}
http{
server {
location / {
# httpリクエストをリダイレクト
proxy_pass http://flask:5000/;
}
}
}
nginx.confの説明は割愛しますが、ここではhttpリクエストを全て後続のFlaskにリダイレクトしています。
Flask
以下はDocker-compose.ymlのFlaskの抜粋です。
flask:
build: .
ports:
- "5000:5000"
volumes:
- ./src/flask_postgresql_sample:/app
depends_on:
- postgresql
-
flask
はサービス名です -
build
はDockerfileのディレクトリを指定します。ここでは、現在のディレクトリをビルドコンテキストとして指定します -
ports
はホストのポート5,000をコンテナのポート5,000にマッピングします。ホストマシン上のアプリケーションはポート5,000を通じてコンテナ内のFlaskアプリケーションにアクセスできます -
volumes
はホストマシンのディレクトリをコンテナ内のディレクトリにマウントします。ホストの./src/flask_postgresql_sample
ディレクトリをコンテナ内の/app
ディレクトリにマウントします。これにより、ホスト側のソースコードをコンテナ内で使用できます。開発中にホストのコードを変更すると、コンテナ内でも即座に反映されます -
depends_on
はサービスの依存状態を設定することができます。この場合、Flaskコンテナはpostgresqlコンテナに依存しており、Flaskコンテナはpostgresqlコンテナが起動してから起動します
Dockerfileの作成
Flaskのサーバーは、パッケージのインストール等コマンドを実行する必要があるため、今回はDocker Hubからイメージを取得することができません。DockerイメージをビルドするためのDockerfileは下記の通りです。
# ベースイメージを指定
FROM python:3.12-slim
# 作業ディレクトリを設定
WORKDIR /app
# 必要なパッケージをインストール
RUN pip install --upgrade pip
# 依存関係をインストール
COPY ./src/flask_postgresql_sample/app.py /app/app.py
COPY requirements.lock requirements.lock
COPY pyproject.toml pyproject.toml
COPY README.md README.md
RUN pip install -r requirements.lock
# コマンドを実行
CMD ["python", "app.py"]
PostgreSQL
以下はDocker-compose.ymlのPostgreSQLの抜粋です。
postgresql:
image: postgres:latest
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- "5432:5432"
-
postgresql
はサービス名です。 -
image
はDocker Hubから最新のイメージを落としてきて使用します。 -
environment
はコンテナの環境変数を設定します。これにより、コンテナ内のPostgreSQLインスタンスの初期設定を行います。-
POSTGRES_USER
はデータベースの管理ユーザー名を指定します。ここでは、ユーザー名がpostgresに設定されています。 -
POSTGRES_PASSWORD
はデータベースの管理ユーザーのパスワードを指定します。ここでは、パスワードがpostgresに設定されています。 -
POSTGRES_DB
は初期データベースの名前を指定します。ここでは、データベース名がpostgresに設定されています。
このデータベースはコンテナが初めて起動したときに自動的に作成されます。
-
-
ports
はホストのポート5432をコンテナのポート5432にマッピングします。これにより、ホストマシン上のアプリケーションはポート5432を通じてコンテナ内のPostgreSQLデータベースにアクセスできます。
dockerコンテナのオーケストレーション
今までの説明をまとめると以下のようになります。
services:
flask:
build: .
ports:
- "5000:5000"
volumes:
- ./src/flask_postgresql_sample:/app
depends_on:
- postgresql
postgresql:
image: postgres:latest
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: postgres
ports:
- "5432:5432"
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./for_develop/nginx/nginx.conf:/etc/nginx/nginx.conf
depends_on:
- flask
Dockerコンテナの起動
docker-compose.ymlがあるディレクトリに移動し、docker-compose up
コマンドを実行します。
docker-compose up
詰まったところ
Flaskのサービスにアクセスできない
ポート番号5,000がすでに使われているため使用できないと言われた
調べてみたところ、MacのAirPlayレシーバー
がオンになっているとうまくいかないようでした。設定を開き、Airと調べるとAirDropとHandoff
のところにAirPlayレシーバー
があります。これをオフにしたらうまくいきました。
## 参考資料
以上