Dockerfileのテンプレ8選 ― Node・Python・Go・nginxなど用途別ベース

主要言語・ミドルウェアのDockerfileテンプレを8パターン収録。マルチステージビルド・非rootユーザー・ヘルスチェックまでコピペで動きます。

Dockerfileを書くとき、毎回他のプロジェクトからコピペしてくる人が多いんじゃないでしょうか(自分もそう)。

ただ、コピペ元が古いと **「セキュリティ甘い」「イメージサイズ巨大」**みたいな罠をそのまま引き継いじゃうんですよね(- -;

そこで、2026年時点でモダンに動く用途別Dockerfileテンプレをここに集約しました。

最近のDockerfileで気をつけたいのは下記の3点。

下記テンプレは全部この観点でモダンに書き直してあるので、新規プロジェクトのスタートに最適です!

1. Node.js(マルチステージビルド)

用途: Next.js / Expressなど、Node製のWebアプリ向け

# ===== Build stage =====
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# ===== Runtime stage =====
FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production

# 非root ユーザーで実行
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nodejs -u 1001

COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
COPY --from=builder --chown=nodejs:nodejs /app/package.json ./

USER nodejs
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s \
    CMD wget -qO- http://localhost:3000/health || exit 1

CMD ["node", "dist/server.js"]

マルチステージビルドを使うと、ビルドツール類が最終イメージに残らないので、サイズを大幅削減できます。

npm ci を使うのも地味に大事で、npm install よりも再現性が高くて推奨されてます(^^b

2. Python(FastAPI / Flask)

用途: PythonのWeb APIサーバー向け

FROM python:3.12-slim AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

FROM python:3.12-slim
WORKDIR /app
ENV PYTHONUNBUFFERED=1

# 非root ユーザー
RUN useradd -m -u 1001 app
COPY --from=builder --chown=app:app /root/.local /home/app/.local
COPY --chown=app:app . .

USER app
ENV PATH=/home/app/.local/bin:$PATH
EXPOSE 8000

HEALTHCHECK --interval=30s --timeout=3s \
    CMD curl -f http://localhost:8000/health || exit 1

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

PYTHONUNBUFFERED=1 を入れておくと ログがリアルタイムに出ます

これがないとログが遅延してデバッグが地獄になるので、ほぼ必須の環境変数ですね(^^!

3. Go(静的バイナリ・最小イメージ)

用途: Go製のサーバーやCLI、極小イメージにしたいとき

FROM golang:1.22-alpine AS builder
WORKDIR /build
COPY go.mod go.sum ./
RUN go mod download
COPY . .
# 静的バイナリビルド
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags="-s -w" -o app .

# Distroless でセキュア&極小
FROM gcr.io/distroless/static-debian12:nonroot
WORKDIR /
COPY --from=builder /build/app /app
USER nonroot:nonroot

EXPOSE 8080
ENTRYPOINT ["/app"]

Goは 静的バイナリ+distroless10MB台まで圧縮できます。

distroless はシェルすら入っていないので、シェル経由の侵入経路がそもそも塞がれます。セキュリティ重視の本番運用でよく採用されるパターンですね(^^b

ただしデバッグ時に docker exec -it ... sh できないので、ログとヘルスチェックを厚めに用意しておくのが運用上のコツです。

4. nginx(静的サイト配信)

用途: ReactやVueでビルドした静的ファイルを配信するとき

FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:1.27-alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

EXPOSE 80
HEALTHCHECK --interval=30s --timeout=3s \
    CMD wget -qO- http://localhost/ || exit 1

CMD ["nginx", "-g", "daemon off;"]

SPA配信 はこのパターンが定番です。

Reactルーターのフォールバックは nginx.conf 側で try_files $uri /index.html; を入れる必要があります(^^!

5. Ruby on Rails

用途: Railsアプリのコンテナ化

FROM ruby:3.3-alpine AS builder
WORKDIR /app
RUN apk add --no-cache build-base postgresql-dev nodejs yarn
COPY Gemfile* ./
RUN bundle config set --local without 'development test' && \
    bundle install
COPY . .
RUN bundle exec rake assets:precompile

FROM ruby:3.3-alpine
WORKDIR /app
RUN apk add --no-cache postgresql-client tzdata
RUN adduser -D -u 1001 rails
COPY --from=builder --chown=rails:rails /usr/local/bundle /usr/local/bundle
COPY --from=builder --chown=rails:rails /app /app

USER rails

EXPOSE 3000
CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0"]

Rails は アセットプリコンパイルをビルド段階でやるのがコツ。

ランタイムでやると起動が遅くなるので、ビルド時に終わらせちゃいましょう(^^b

6. Java(Spring Boot)

用途: Spring Boot製アプリのコンテナ化

FROM eclipse-temurin:21-jdk-alpine AS builder
WORKDIR /build
COPY mvnw pom.xml ./
COPY .mvn .mvn
RUN ./mvnw dependency:go-offline
COPY src src
RUN ./mvnw package -DskipTests

FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
RUN addgroup -S spring && adduser -S spring -G spring
USER spring
COPY --from=builder /build/target/*.jar app.jar

EXPOSE 8080
HEALTHCHECK --interval=30s --timeout=3s \
    CMD wget -qO- http://localhost:8080/actuator/health || exit 1

ENTRYPOINT ["java", "-jar", "/app/app.jar"]

Java は JDKでビルド、JREで実行するのがマルチステージの定番。

JREの方が軽いので、最終イメージサイズが大きく削れます(^^!

7. PostgreSQL(初期化スクリプト付き)

用途: 開発環境用にPostgreSQLとスキーマを一緒に立ち上げたいとき

FROM postgres:16-alpine

# 環境変数(compose 側で上書き推奨)
ENV POSTGRES_DB=mydb \
    POSTGRES_USER=user \
    POSTGRES_PASSWORD=password

# 初回起動時に実行されるSQL
COPY ./init.sql /docker-entrypoint-initdb.d/

EXPOSE 5432

HEALTHCHECK --interval=10s --timeout=5s \
    CMD pg_isready -U $POSTGRES_USER -d $POSTGRES_DB || exit 1

このサンプルはローカル開発専用です。 Dockerfile に POSTGRES_PASSWORD=password のように認証情報を直書きするとイメージレジストリ経由で漏洩します。本番環境では必ず Secrets Manager や環境変数で注入してください。

/docker-entrypoint-initdb.d/ に置いたSQLファイルは 初回起動時のみ実行されます。

テーブル作成やシードデータ投入はここに置くと、docker-compose up 一発でDB初期化が完了します(^^b

8. 開発用ツールイメージ

用途: チームで開発環境をそろえたいとき

FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
    curl \
    git \
    vim \
    jq \
    tree \
    ripgrep \
    fzf \
    zsh \
    ca-certificates \
    && rm -rf /var/lib/apt/lists/*

# 開発用ユーザー作成
RUN useradd -m -s /bin/zsh dev
USER dev
WORKDIR /home/dev

CMD ["zsh"]

開発ツール一式入りイメージを用意しておくと、新人さんの環境構築が一瞬で終わります。

VSCode Dev Container と組み合わせると効果が高いです。ただしチームメンバーのシェル好み(bash派/zsh派/fish派)は意外と揉めるので、エディタや CLI の強制はほどほどに(^^!