Next.jsとFastAPI(Pythonの非同期Webフレームワーク)を組み合わせたマイクロサービス構成は、Claude CodeやCursorのようなAIコーディングツールに「動画ダウンローダーを作って」と頼むと、かなり近い形で一気に生成されるようになりました。
実際に公開されているFastMedia Downloaderというオープンソースプロジェクトは、FastAPI+Python 3.11のバックエンドと、Next.js+TypeScript+Tailwind CSSのフロントエンドを、Docker Compose(複数コンテナをまとめて起動する仕組み)で連携させる構成を採用しています。動画・音声の抽出にはyt-dlpとFFmpegという定番ツールをラップして使っています。このAI生成されがちな構成には、実運用に持っていく際に見落とされやすい落とし穴がいくつかあります。AIツールでスキャフォールディング(雛形生成)した直後のプロジェクトを本番に近づけようとしているエンジニアに向けて、確認すべきポイントを整理しました。
何が起きるか:ローカルでは動くのに本番で崩れる
AIコーディングツールに「FastAPI + Next.js + Dockerで動画変換サービスを作って」と指示すると、docker-compose up一発でローカルは動く状態のコードがすぐ出てきます。
ところが、そのまま本番環境やステージング環境にデプロイすると、コンテナ内でFFmpegバイナリが見つからない、非同期処理でメモリが膨らむ、CORSエラーでフロントエンドから叩けない、といった問題が立て続けに出ることがあります。
これは特定のプロジェクト固有の不具合ではなく、AI生成コードが「ローカルの単一環境で動くこと」を最優先に組み立てられがちな構造的な傾向によるものです。
なぜ起きるか:原因を3段階に分解する
1. システム依存バイナリのコンテナ隔離が中途半端
FFmpegのような低レベルの外部バイナリをコンテナ内に閉じ込める設計は、ホスト環境を汚さない利点がある一方、Dockerfileのベースイメージ選定を誤ると失敗します。
たとえばpython:3.11-slimのような軽量イメージには、FFmpegはおろかその依存ライブラリすら入っていません。AIツールはapt-get install ffmpegを書き忘れたり、逆にビルド時間を無視して重いイメージを提案したりする傾向があります。
2. FastAPIの非同期処理が「なんとなくasync」になっている
FastAPIの強みは非同期処理でメディアのメタデータ取得やダウンロードのレスポンス待ち時間を短縮できる点です。しかしAIが生成したコードでは、async defと書いてあるだけで、内部でyt-dlpの同期的な呼び出しをそのままawaitせずに使っているケースが少なくありません。
これはイベントループ(非同期処理を順番にさばく仕組み)をブロックしてしまい、同時アクセスが増えた瞬間にレスポンスが全体的に遅延します。見た目は非同期でも中身は同期、という状態です。
3. CI/CDとセキュリティ設定がテンプレートのまま
GitHub Actionsによる自動化パイプラインやDependabot(依存関係の脆弱性を自動検知する仕組み)は、AIが「ベストプラクティス」としてそのまま追加してくれることが多いです。
ただし、これらは多くの場合デフォルト設定のテンプレートのままで、実際のプロジェクトのブランチ保護ルールやシークレット管理と噛み合っていないことがあります。動いているように見えて、実は何もチェックしていないワークフローになっている、という状態が起こり得ます。
自分のプロジェクトが該当するか確認する方法
手を動かす前に、まず現状を把握するための確認手順です。
# Dockerfile内でFFmpegが実際にインストールされているか確認
docker build -t check-ffmpeg . && docker run --rm check-ffmpeg ffmpeg -version
# コンテナ内のイベントループがブロックされていないか、負荷テストで確認
# (Apache Benchなどで同時リクエストを送り、レスポンス時間の分布を見る)
ab -n 100 -c 20 http://localhost:8000/api/inspect
# GitHub Actionsのワークフローが実際にどのステップを実行しているか確認
cat .github/workflows/*.yml加えて、requirements.txtやpyproject.tomlのFastAPIとPythonのバージョンも確認しておきます。FastAPIは0.100系以降でPydantic v2への移行が進んでおり、AIが古い書き方(Pydantic v1のバリデータ構文など)を混ぜて生成することがあるためです。
python -c "import fastapi; print(fastapi.__version__)"
pip show pydanticバージョンの組み合わせに矛盾がないか、この2つのコマンドで最低限のチェックができます。
対策の手順
FFmpegなど外部バイナリの依存を明示する
DockerfileにRUN apt-get update && apt-get install -y ffmpegを明示的に書き、ビルドログでインストールの成否を確認します。マルチステージビルドを使う場合は、最終ステージにバイナリがコピーされているかも忘れず見ます。
非同期処理の中身を1つずつ検証する
FastAPIのエンドポイント内でyt-dlpやサブプロセスを呼んでいる箇所を洗い出し、asyncio.create_subprocess_execやrun_in_executorでイベントループをブロックしないよう書き換えます。AIツールに修正を依頼する際は「このsyncな呼び出しをブロッキングなしで実行するように書き換えて」と具体的に指示すると精度が上がります。
CI/CDとセキュリティ設定を1つずつ読む
.github/workflows配下のYAMLファイルを開き、テストが実際にどのコマンドを実行しているか、Dependabotの設定ファイル(.github/dependabot.yml)がどの依存範囲をスキャンしているかを目視で確認します。AIが生成したテンプレートは、プロジェクトの実態に合わせて対象パスやスケジュールを調整し直す必要があります。
まとめ:本番投入前にチェックすべき3点
AIコーディングツールでFastAPIとNext.js、Dockerを組み合わせた構成を作ること自体は、もはや数分で終わる作業になっています。
持ち帰ってほしいのは次の3点です。
- Dockerfile内で外部バイナリ(FFmpeg等)のインストールが明示されているかをビルドログで確認する
- async defの中身が本当に非ブロッキングかを負荷テストで検証する
- CI/CDとセキュリティ設定のYAMLを実際に開いて、テンプレートのままになっていないか読む
まずは手元のDockerfileとdocker-compose.ymlを開いて、FFmpegのインストール行とFastAPI・Pydanticのバージョンを確認するところから始めてみるのがおすすめです。