DockerでFastAPI+Next.js+MySQLの環境を構築してみる(Windows)
フロントアプリ作成
アプリケーションの定義ファイル(YAML)作成
type nul > docker-compose.yml下記の内容で編集。
services:
frontend:
image: node:22-alpine
working_dir: /app
ports:
- "3000:3000"
volumes:
- ./frontend:/appフロントアプリ作成
docker compose run --rm frontend sh -c "npx create-next-app@latest . --typescript"アプリケーションの定義ファイル(YAML)編集
services:
db:
build: ./db
volumes:
- mysql-data:/var/lib/mysql
ports:
- "3306:3306"
backend:
build:
context: ./backend
environment:
DATABASE_URL: mysql+pymysql://odaneko:odaneko@db:3306/odaneko
ports:
- "8000:8000"
frontend:
build:
context: ./frontend
ports:
- "3000:3000"
environment:
BACKEND_API_URL: http://backend:8000
volumes:
- ./frontend:/app
- /app/node_modules
- /app/.next
volumes:
mysql-data:backendコンテナ(FastAPI)作成
Dockerファイル作成
ディレクトリ作成。
mkdir backendDockerファイル作成。
type nul > backend/Dockerfile下記の内容で編集。
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]requirements.txt作成
type nul > backend/requirements.txtfastapi
uvicorn[standard]
sqlalchemy
pymysql.dockerignore
type nul > backend/.dockerignore__pycache__
*.pyc
.venv
.git
.gitignorefrontendコンテナ(Next.js)作成
Dockerファイル作成
ファイル作成。
type nul > frontend/Dockerfile下記の内容で編集。
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["npm", "run", "start"].dockerignore
type nul > frontend/.dockerignorenode_modules
.next
.git
.gitignore
Dockerfile
npm-debug.log*DBコンテナ(MySQL)作成
Dockerファイル作成
ディレクトリ作成。
mkdir dbファイル作成。
type nul > db/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.cnftype nul > db/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 = utf8mb4API作成
APIの処理が記載されたプログラムを作成。
type nul > backend/main.py下記の内容で編集。
DB接続確認を行うAPIです。
from fastapi import FastAPI
from sqlalchemy import create_engine, text
import os
app = FastAPI()
DATABASE_URL = os.environ["DATABASE_URL"]
engine = create_engine(DATABASE_URL)
@app.get("/db-test")
def db_test():
with engine.connect() as connection:
result = connection.execute(text("SELECT 1 AS result"))
row = result.fetchone()
return {
"result": row.result
}フロントページ作成
アプリ作成
ページ作成
mkdir frontend/app/db-testtype nul > frontend/app/db-test/page.tsx"use client";
import { useState } from "react";
export default function Home() {
const [result, setResult] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const executeTest = async () => {
setLoading(true);
setError("");
setResult(null);
try {
const response = await fetch("/api/db-test");
if (!response.ok) {
throw new Error("API request failed");
}
const data = await response.json();
setResult(data.result);
} catch (error) {
console.error(error);
setError("APIの呼び出しに失敗しました");
} finally {
setLoading(false);
}
};
return (
<main>
<h1>Python API 接続テスト</h1>
<button onClick={executeTest} disabled={loading}>
{loading ? "実行中..." : "DB検索を実行"}
</button>
{result !== null && (
<p>
DB検索結果:{result}
</p>
)}
{error && (
<p>
エラー:{error}
</p>
)}
</main>
);
}API作成
mkdir frontend/app/api/db-testtype nul > frontend/app/api/db-test/route.tsimport { NextResponse } from "next/server";
export async function GET() {
const response = await fetch(
`${process.env.BACKEND_API_URL}/db-test`
);
const data = await response.json();
return NextResponse.json(data);
}コンテナビルド・起動
docker compose up -d --buildDockerデスクトップでも起動を確認。

環境が構築できたか確認
下記のURLを開いて、テストページが表示されるか確認。
http://localhost:3000/db-test

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

