メインコンテンツまでスキップ

第11章:APIサービスの“コンテナ化”を最小でやる📦🛠️

この章でやることはシンプル! **「TypeScriptのAPIを、Composeから“サービス”として起動できる」**状態を作ります🚀✨ (細かい最適化は後の章でOK。まずは“動けば勝ち”でいきます💪)


11.1 まず脳内整理:DockerfileとComposeの役割🧠🔧

  • Dockerfile:APIの“箱(イメージ)”の作り方レシピ🍳
  • compose.yaml:箱たち(API/DB/Redis…)を“チームとして動かす指示書”📋

Composeは、Compose Specificationが推奨の形式で、最近は compose.yaml が基本になってます。(Docker Documentation) あと、トップレベルの version: は **obsolete(警告が出るやつ)**なので、入れなくてOKです。(Docker Documentation)


11.2 “最小セット”はこれだけでOK✅✨

今回追加するのは主にこの3つ!

  • Dockerfile(API用)
  • .dockerignore(要らないものをビルドに混ぜない)
  • compose.yamlapi: サービス定義(追加)

フォルダ例📁(イメージ)

  • compose.yaml

  • apps/api/

    • Dockerfile
    • .dockerignore
    • package.json / package-lock.json
    • src/(TypeScriptのソース)

11.3 Nodeのベースイメージは“LTS”が安心🛟🟩

2026-02-10時点だと、Node v24 が Active LTS です(安定&長めにメンテされる枠)(nodejs.org) DockerのNode公式イメージも、こういう“サポート中のNode系”に合わせて提供されています。(GitHub)

なのでこの章では node:24でいきます👍✨(迷子になりにくい!)


11.4 Dockerfile(開発用)を“最小で”作る📦🔥

ポイントは3つだけ😊

  1. package*.json を先にコピー(依存のキャッシュが効きやすい)
  2. npm ci で依存を入れる(ロックファイル基準で安定)
  3. 最後にソースをコピーして起動!

apps/api/Dockerfile(例)👇

## 開発用:まずは「動けば勝ち」構成✨
FROM node:24-bookworm-slim

WORKDIR /app

## 依存関係(先にコピーしてキャッシュを効かせる)
COPY package*.json ./
RUN npm ci

## ソース
COPY . .

## APIが使うポート(例:3000)
EXPOSE 3000

## 開発起動(例:ホットリロードは次章以降で強化していく)
CMD ["npm", "run", "dev"]

node:24-bookworm-slim みたいなタグは、Node公式イメージ側で提供されてます。(Docker Hub) (この章では「まず動く」優先なので “slim” でOK🙆‍♂️)


11.5 .dockerignore は絶対に入れる🧹🧨(事故防止)

特に node_modules は混ぜると事故りやすいです(ホスト側とコンテナ側で環境が違うので💥)。 最小はこれ👇

apps/api/.dockerignore

node_modules
dist
.git
Dockerfile
npm-debug.log
.DS_Store

11.6 package.jsondev を“コンテナで起動できる形”にする▶️🧑‍💻

ここはプロジェクトごとに違ってOK! 大事なのは **npm run dev が「落ちずに起動する」**ことだけ😊✨

例(Expressなどを想定):

{
"scripts": {
"dev": "node ./dist/index.js"
}
}

まだTSをそのまま動かしてるなら(例:tsx/ts-node系)でもOKです👌 ただし「まず動く」がゴールなので、凝りすぎないのがコツ😄


11.7 compose.yamlapi サービスを追加する🧩🚀

Composeでイメージをビルドしたいときは build: を使います。(Docker Documentation) compose.yaml の該当部分(例)👇

services:
api:
build:
context: ./apps/api
ports:
- "3000:3000"
env_file:
- ./.env
depends_on:
- db
- redis
  • build.context:Dockerfileがあるフォルダを指す📍
  • ports:ホストの 3000 → コンテナの 3000 🌐
  • env_file:環境変数は .env から(第8章の方針をそのまま継承🔑)
  • depends_on:DB/Redisがいる前提で“関係だけ”書く(待ち合わせは第14章で強化⏳🩺)

11.8 起動して「動いた!」を確認する✅🎉

まずはビルド込みで起動!

docker compose up --build api

別ターミナルで状態チェック👀

docker compose ps

ログを見る🧾✨

docker compose logs -f api

11.9 “よくある落とし穴”ベスト5🕳️🐾(ここだけ押さえれば勝率UP)

  1. ポートが埋まってる3000 競合)🚪💥 → ports: "3100:3000" みたいにホスト側だけ変える

  2. npm ci が落ちる📦😵 → package-lock.json が壊れてないか、node バージョン差がないか確認

  3. 起動した瞬間に落ちる🧯 → CMD が間違ってる or dev スクリプトが存在しない、が多い

  4. 環境変数が読めてない🔑💨 → env_file のパスミス、.env の場所違い

  5. depends_on 書いたのにDBが間に合わない🐘💤 → これは正常です!depends_on は“順番の目安”で、完全な待ち合わせは第14章でやります⏳✨


11.10 ここまでできたら合格🎓✅(チェックリスト)

  • docker compose up --build apiapi が落ちずに起動する
  • docker compose psapi が Up になってる
  • docker compose logs -f api起動ログが見える
  • ブラウザやcurlで localhost:3000 にアクセスできる 🌐✨

11.11 ミニ演習🎮🧩(達成感ブースト!)

  1. GET /health を作って "ok" を返す💚
  2. compose.yamlports を変えて、localhost:3100 で開く🧪
  3. docker compose down → もう一回 up しても API が起動するのを確認🔁✨

11.12 Copilot / Codex に投げると速い“指示テンプレ”🤖⚡

コピペでOK👇(プロジェクトに合わせて微調整してね😊)

  • apps/api開発用Dockerfile を作って。Nodeは 24 LTSnpm ci を使って、npm run dev で起動する構成にして。」
  • compose.yamlapi サービスを追加して。build.context./apps/api、ポートは 3000:3000.env を読むようにして。」

次の第12章では、いよいよ ソース共有(bind mount)node_modules 地獄回避 をやって、開発体験を一気に上げます👟🧨→✨