「DockerでNginxを動かしたいけど何から始めればいいかわからない」という方向けに、基本的なコンテナの起動からDocker Composeを使った本格的な構成まで順番に解説します。コマンドを実際に動かしながら読み進めてください。
DockerとNginxの基本を理解する
Dockerはアプリケーションとその実行環境をコンテナにパッケージ化する技術です。「自分のMacでは動いたのに本番サーバーでは動かない」という問題を解消してくれます。
NginxはWebサーバーです。静的ファイルの配信・リバースプロキシ・ロードバランサーとして使われます。DockerでNginxを動かすと、環境構築が数コマンドで完了するのが魅力です。
Dockerの基本コマンド
まずDockerが正しくインストールされているか確認します。
# バージョン確認
docker --version
# イメージの一覧確認
docker images
# 起動中のコンテナ確認
docker ps
# 全コンテナ確認(停止中も含む)
docker ps -a
# コンテナの停止
docker stop コンテナ名またはID
# コンテナの削除
docker rm コンテナ名またはID
# イメージの削除
docker rmi イメージ名
NginxコンテナをDockerで起動する
まずNginxのイメージをDocker Hubから取得して起動します。
# Nginxイメージを取得
docker pull nginx
# Nginxコンテナを起動
docker run -d -p 8080:80 --name my-nginx nginx
# オプションの説明
# -d : バックグラウンドで実行
# -p 8080:80: ホストの8080番ポートをコンテナの80番ポートにマッピング
# --name : コンテナに名前をつける
# nginx : 使用するイメージ名
起動後にブラウザでhttp://localhost:8080にアクセスすると「Welcome to nginx!」が表示されます。
ポートマッピングでよくあるミスとして、ホストOSの80番ポートが他のアプリケーションに使われていてコンテナが起動しないケースがあります。その場合は-p 8080:80のようにホスト側のポートを変えてください。
# コンテナが起動しているか確認
docker ps
# 出力例
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a1b2c3d4e5f6 nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:8080->80/tcp my-nginx
カスタム設定ファイルをマウントする
デフォルトのNginx設定を変更したい場合はボリュームマウントを使います。コンテナを再作成しなくても設定変更が反映されるので便利です。
# ホストの設定ファイルをコンテナにマウント
docker run -d \
-p 8080:80 \
--name my-nginx \
-v /path/to/nginx.conf:/etc/nginx/nginx.conf:ro \
-v /path/to/html:/usr/share/nginx/html:ro \
nginx
# :ro は読み取り専用でマウント(推奨)
# コンテナ側から誤って設定ファイルを変更するリスクを防げる
カスタムnginx.confの基本的な構成はこちらです。
# nginx.conf の例
events {
worker_processes auto;
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Gzip圧縮を有効化
gzip on;
gzip_types text/plain text/css application/json application/javascript;
# keepalive設定
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
}
Docker ComposeでNginxを管理する
毎回長いdocker runコマンドを打つのは面倒です。Docker Composeを使うと設定をYAMLファイルで管理できて、コマンド一つで起動・停止できます。
# docker-compose.yml
version: '3.8'
services:
nginx:
image: nginx:latest
container_name: my-nginx
ports:
- "8080:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./html:/usr/share/nginx/html:ro
restart: unless-stopped
# Docker Composeの基本コマンド
# 起動
docker compose up -d
# 停止
docker compose down
# ログ確認
docker compose logs nginx
# 設定を変更した後に再起動
docker compose restart nginx
NginxをリバースプロキシとしてNode.jsと連携する
Nginxをリバースプロキシとして使うと、外部からのリクエストをバックエンドのアプリケーションに転送できます。Node.jsアプリとNginxを連携させる例はこちらです。
# docker-compose.yml(Nginx + Node.js)
version: '3.8'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- app
app:
image: node:18-alpine
working_dir: /app
volumes:
- ./app:/app
command: node server.js
expose:
- "3000"
# nginx.conf(リバースプロキシ設定)
http {
upstream node_app {
server app:3000; # サービス名で指定できる
}
server {
listen 80;
location / {
proxy_pass http://node_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
}
Docker Composeではサービス名でコンテナ間通信ができます。上の例ではserver app:3000とサービス名appでNode.jsコンテナに接続しています。IPアドレスを指定する必要がない点がDockerの便利なところです。
SSL/TLS証明書の設定(Let's Encrypt)
Let's Encryptの無料証明書をDockerで使う場合はcertbotコンテナと組み合わせます。
# docker-compose.yml(Nginx + certbot)
version: '3.8'
services:
nginx:
image: nginx:latest
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
- ./certbot/conf:/etc/letsencrypt:ro
- ./certbot/www:/var/www/certbot:ro
certbot:
image: certbot/certbot
volumes:
- ./certbot/conf:/etc/letsencrypt
- ./certbot/www:/var/www/certbot
command: certonly --webroot -w /var/www/certbot
-d yourdomain.com --email your@email.com
--agree-tos --no-eff-email
# nginx.conf(HTTPS設定)
server {
listen 80;
server_name yourdomain.com;
# Let's Encryptの認証用
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
# HTTPをHTTPSにリダイレクト
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name yourdomain.com;
ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
証明書パスの指定ミスはよくあるエラーです。Dockerコンテナ内のNginxから見たパスと、ホストOSから見たパスを混同しないように注意してください。
ログ管理と監視
NginxのログをDockerで確認する方法はこちらです。
# Dockerのログを確認
docker logs my-nginx
# リアルタイムでログを確認
docker logs -f my-nginx
# コンテナ内に入って直接確認
docker exec -it my-nginx bash
cat /var/log/nginx/access.log
cat /var/log/nginx/error.log
Nginxのログを標準出力に転送するとDockerのログドライバで収集しやすくなります。
# nginx.confでログを標準出力に転送
http {
access_log /dev/stdout;
error_log /dev/stderr warn;
}
パフォーマンスチューニングのポイント
Nginxをチューニングする際に押さえておくべき設定はこちらです。
# nginx.conf パフォーマンスチューニング例
worker_processes auto; # CPUコア数に合わせて自動設定
events {
worker_connections 1024; # 1プロセスあたりの最大接続数
use epoll; # Linuxでの効率的なI/O
}
http {
# Gzip圧縮
gzip on;
gzip_comp_level 6;
gzip_types text/plain text/css application/json
application/javascript text/xml;
# ブラウザキャッシュ
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
# keepalive設定
keepalive_timeout 65;
keepalive_requests 100;
}
よくあるエラーと対処法
# エラー①:ポートが使用中
Error: Bind for 0.0.0.0:80 failed: port is already allocated
対処:-p 8080:80 のようにホスト側のポートを変える
# エラー②:設定ファイルの構文エラー
nginx: [emerg] unknown directive "xxx"
対処:コンテナ内で設定を検証する
docker exec my-nginx nginx -t
# エラー③:Permission denied
対処:ボリュームマウントのパーミッションを確認
ls -la /path/to/nginx.conf
# エラー④:コンテナ間で通信できない
対処:同じdocker-compose.ymlで定義されているか確認
サービス名で通信できているか確認
docker network ls で共有ネットワークを確認
まとめ
DockerでNginxを構築する基本の流れをまとめます。
docker run -d -p 8080:80 --name my-nginx nginxでまず動かしてみる- 設定をカスタマイズするなら
-vでnginx.confをマウントする - 複数サービスを組み合わせるならDocker Composeで管理する
- 本番環境ではSSL・ログ管理・パフォーマンスチューニングを設定する
まずdocker runでNginxを動かしてWelcomeページを確認するところから始めてみてください。