DockerでFastAPI+MySQLの環境を構築してみる(Windows)

開発環境

  • OS:Windows11
  • Docker Desktopインストール済み
  • VSCodeインストール済み

アプリケーションの定義ファイル(YAML)作成

type nul > docker-compose.yml

下記の内容で編集。

services:
  app:
    build: ./infra/fast-api
    ports:
      - "8000:8000"
    volumes:
      - ./app:/app

  db:
    build: ./infra/mysql
    volumes:
      - db-store:/var/lib/mysql
    ports:
      - "3306:3306"

volumes:
  db-store:

appコンテナ(FastAPI)作成

Dockerファイル作成

ディレクトリ作成。

mkdir -p infra/fast-api

Dockerファイル作成。

type nul > infra/fast-api/Dockerfile

下記の内容で編集。

# ベースイメージを指定
FROM python:3.9

# 作業ディレクトリを作成
WORKDIR /app

# 必要なパッケージをインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# アプリケーションのソースコードをコピー
COPY . .

# アプリケーションを起動
CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0", "--port", "8000"]

requirements.txt作成

type nul > infra/fast-api/requirements.txt

下記の内容で編集。

uvicorn
fastapi
mysqlclient
sqlalchemy

DBコンテナ(MySQL)作成

Dockerファイル作成

ディレクトリ作成。

mkdir infra/mysql

ファイル作成。

type nul > infra/mysql/Dockerfile

下記の内容で編集。

FROM mysql/mysql-server:8.0

ENV MYSQL_DATABASE=odaneko \
  MYSQL_USER=odaneko \
  MYSQL_PASSWORD=odaneko \
  MYSQL_ROOT_PASSWORD=odaneko \
  TZ=Asia/Tokyo

COPY ./my.cnf /etc/my.cnf
RUN chmod 644 /etc/my.cnf

confファイル作成

type nul > infra/mysql/my.cnf

下記の内容で編集。

[mysqld]
# default
skip-host-cache
skip-name-resolve
datadir = /var/lib/mysql
socket = /var/lib/mysql/mysql.sock
secure-file-priv = /var/lib/mysql-files
user = mysql

pid-file = /var/run/mysqld/mysqld.pid

# character set / collation
character_set_server = utf8mb4
collation_server = utf8mb4_ja_0900_as_cs_ks

# timezone
default-time-zone = SYSTEM
log_timestamps = SYSTEM

# Error Log
log-error = mysql-error.log

# Slow Query Log
slow_query_log = 1
slow_query_log_file = mysql-slow.log
long_query_time = 1.0
log_queries_not_using_indexes = 0

# General Log
general_log = 1
general_log_file = mysql-general.log

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4

サンプルAPI作成

appディレクトリ作成

mkdir app

db.py作成

MySQL接続用のコードを作成。

type nul > app/db.py

hostは別プロジェクトのMySQLコンテナ名です。
db_name、user、passwordは環境に合わせてください。

from sqlalchemy import create_engine
from sqlalchemy.orm import declarative_base, sessionmaker, scoped_session

host = "db:3306"
db_name = "odaneko"
user = "odaneko"
password = "odaneko"

DATABASE = 'mysql://%s:%s@%s/%s?charset=utf8' % (
    user,
    password,
    host,
    db_name,
)

ENGINE = create_engine(
    DATABASE,
    echo=True
)

session = scoped_session(
    sessionmaker(
        autocommit=False,
        autoflush=False,
        bind=ENGINE
    )
)

Base = declarative_base()
Base.query = session.query_property()

main.pyを作成

APIの処理が記載されたプログラムを作成。

type nul > app/main.py

下記の内容で編集。
DB接続確認を行うAPIです。

from fastapi import FastAPI
from db import session
from sqlalchemy import text

app = FastAPI()

@app.get("/mysql-test")
def mysql_test():
    query = text("SELECT 1;")
    records = session.execute(query).fetchall()
    return [dict(record._mapping) for record in records]

コンテナビルド・起動

docker compose up -d --build

Dockerデスクトップでも起動を確認。

環境が構築できたか確認

下記のURLを開いて、Swaggerが表示されるか確認。
http://localhost:8000/docs

ExecuteからAPIを実行し、1がリターンされていればOK。

以上になります。
お読み頂き、ありがとうございました。