nginx: Webサーバ(Dockerコンテナ)


前提


ドキュメント


Dockerイメージでの利用

docker pull nginx:stable-alpine

CMD: イメージのデフォルトコマンド

docker image inspect --format '{{.Config.Cmd}}' nginx:stable-alpine

コンテナ起動

# --detach: コンテナをバックグラウンドで起動
docker run --rm -it --name temp --publish 80:80 --detach nginx:stable-alpine

# アクセス
curl localhost

# ログ
docker logs temp
172.17.0.1 - - [12/Apr/2019:14:16:11 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
# => アクセス元がdocker0ブリッジになってしまう

# 停止
docker stop temp

フロントエンドのネットワーク: hostモード

docker run --rm -it --name temp --network host --detach nginx:stable-alpine

nginxコマンド: コンテナのシェルで試す

# AlpineにBashはない
docker run --rm -it --name temp nginx:stable-alpine /bin/sh

# ヘルプ
nginx -h

# サーバ起動(バックグラウンド)
nginx

# アクセス
wget -O - localhost

# サーバ停止
nginx -s stop

nginxコマンドをフォアグラウンド実行するとき

nginx -g "daemon off;"

2種類のプロセスが動く

マスタープロセスのプロセスID


設定ファイル: /etc/nginx/nginx.conf

ディレクティブ

ディレクティブと呼ぶ各種設定を一行ずつ記述する。末尾セミコロン。

ディレクティブ パラメータ;

コンテキスト

セミコロンの代わりに{}で他のディレクティブをグループ化するものを、コンテキストやブロックと呼ぶ。

コンテキスト パラメータ {
  他のディレクティブ;
  他のディレクティブ;
}

ディレクティブによっては、特定のコンテキストでしか使えない。

includeディレクティブ

設定ファイルは分割でき、必要とする場所でincludeディレクティブで読み込む。

include conf.d/other.conf

設定ファイルを出力: nginx -T

# デフォルト設定を出力して終了
docker run --rm -it nginx:stable-alpine nginx -T

コンテキストの階層

トップレベルのmainコンテキスト

最低限のnginx.conf

# トップレベル => mainコンテキスト
events { }

http {
  # ここはトップレベルではない
  server {
    location / { # リクエスト・パス
      root /var/www/; # コンテンツ・ディレクトリ
    }
  }
}

mainコンテキストのその他ディレクティブ


httpコンテキスト

URL(ホスト・ポート・パス)

URL例: http://example.com:80/path/to/file


serverコンテキスト: URLをグループ化


例: listen: ポートで分岐

http {
  server {
    listen 8080;
    location / {
      # http://example.com:8080/path/to/file => /var/www8080/path/to/file
      root /var/www8080/;
    }
  }
  server {
    # ポート80
    location / {
      # http://example.com/path/to/file => /var/www/path/to/file
      root /var/www/;
    }
  }
}

例: server_name: ホストで分岐

複数マッチの優先順位

  1. 完全一致
  2. 先頭のワイルドカード: *.example.com
  3. 末尾のワイルドカード: example.*
  4. 正規表現(記述の順番で)
http {
  server {
    server_name *.example.com; # ワイルドカードの部分は何でもマッチ
    location / {
      root /var/www/;
    }
  }
  server {
    server_name host1.example.com; # 完全一致が優先
    location / {
      root /var/www-host1/;
    }
  }
}

locationコンテキスト

location 修飾語 パス表現 {
  # パスに応じた処理
  root /var/www/;
}

修飾語

前方一致どうしは、最長マッチが優先、正規表現どうしは、最初にマッチしたもの優先。

マッチ後の処理


ホストファイルをマウントして起動

ホストで作成しておいたnginx.confやコンテンツを、コンテナにマウントして起動する。

# コンテンツ・ディレクトリ作成
mkdir -p www/
echo '<h1>Hello, nginx!</h1>' > www/index.html

docker run --rm -it --name temp --network host --detach \
  --mount type=bind,source="$PWD"/nginx.conf,destination=/etc/nginx/nginx.conf,readonly \
  --mount type=bind,source="$PWD"/www,destination=/var/www,readonly \
  nginx:stable-alpine

ログ出力先: /var/log/nginx/


ログ書式: log_formatディレクティブ

# main
log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                  '$status $body_bytes_sent "$http_referer" '
                  '"$http_user_agent" "$http_x_forwarded_for"';

# combined
log_format combined '$remote_addr - $remote_user [$time_local] '
                    '"$request" $status $body_bytes_sent '
                    '"$http_referer" "$http_user_agent"';

ログ例

# combinedフォーマット
127.0.0.1 - - [15/Apr/2019:13:36:09 +0000] "GET / HTTP/1.0" 200 22 "-" "curl/7.29.0"