nginxで静的コンテンツを表示する
目的
nginxのDockerコンテナを使って静的コンテンツを表示するための基本的な設定を抑える。
使用するnginxのバージョンは1.13.12。
デフォルトの設定
nginx:1.13-alpine
のDockerイメージでは、/etc/nginx/nginx.conf
と /etc/nginx/conf.d/default.conf
がデフォルトの設定として使われている。
nginx.conf
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; include /etc/nginx/conf.d/*.conf; }
default.conf
server { listen 80; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } error_page 500 502 503 504 /50x.html; location = /50x.html { root /usr/share/nginx/html; } }
公開ディレクトリが /usr/share/nginx/html
に設定されていて、 /test.html
でリクエストすると /usr/share/nginx/html/test.html
ファイルが表示されるようになっている。
ディレクティブの解説
ディレクティブとは
設定ファイルのそれぞれの項目はディレクティブと呼ばれ、ディレクティブ名とパラメータはスペースまたはタブ文字で区切り、最後にセミコロンを付ける。
各行の #
以降は行末まで全てコメントとして扱われる。
ディレクティブには ;
で終わるシンプルなディレクティブと、{...}
でブロックをとるディレクティブがある。
シンプルなディレクティブ
パラメータが1つだけ
worker_processes 1;
パラメータが複数
error_page 500 502 503 504 /50x.html;
各パラメータの間は空白文字で区切る。複数パラメータを改行で区切って指定可能
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"';
ブロック付きディレクティブ
ディレクティブには有効範囲(コンテキスト)があり、http
やserver
ディレクティブのブロックで指定されたコンテキストや、どのコンテキストにも所属しないmainコンテキストがある。mainコンテキストで指定された値はブロック内でも有効だが、ブロック内で指定されると値は上書きされる。
root /usr/share/nginx/html; # ① server { # A server_name a.example; root /usr/share/nginx/html/a; # ② } server { # B server_name b.example; }
ここでは2つのrootディレクティブ(①, ②)が定義されている。①はA, Bどちらのブロックにも含まれていないため、どのコンテキストでも有効。
しかし、Aのブロックには別のrootディレクティブ②が定義されているため、Aのコンテキストでは②が優先される。
Bのブロックにはrootディレクティブが記述されていないため、①のrootディレクティブが有効。
user
ワーカプロセスの実行ユーザを指定する。デフォルトではnobody
ユーザで起動する。
user
ディレクティブを使用することで、特定のユーザでワーカを動作させることができる。
http
HTTPサーバに関連する設定を記述するにはhttpディレクティブを用いてhttpコンテキストを定義する。
nginx本体に関する設定を除き、ほとんどのHTTPサーバの動作に関連する設定は、このhttpディレクティブのブロック内に記述する。
include
共通設定を使用する場合や複数のサーバを設定する場合、設定ファイルを複数に分割することで管理しやすくなります。includeディレクティブを用いることで、複数に分割した設定ファイルを読み込んで使用できる。
パラメータにはファイル名またはファイルマスクを指定できる。(include /etc/nginx/conf.d/*.conf
など)
ファイルは絶対パスあるいはnginx.confが配置されているパスからの相対パスで指定できる。
server
nginxでは使用するIPアドレス、ポート、ホスト名ごとに別々の設定を持つ複数のHTTPサーバを動作させることができ、これらはバーチャルサーバと呼ばれる。
バーチャルサーバは、それぞれ別々のHTTPサーバであるかのように動作し、それぞれ独立した設定を持っている。
バーチャルサーバはserverディレクティブで定義し、ブロック内に記述した設定がバーチャルサーバの設定として扱われる。
複数のバーチャルサーバを定義している場合、nginxは次の順番でどのバーチャルサーバが使用されるか決定します。
1. listenディレクティブのアドレスとポートに一致するバーチャルサーバを検索する
2. リクエストのHostヘッダがserver_nameディレクティブで指定したホストに一致したバーチャルサーバにリクエストを振り分ける
3. どのサーバにも一致しない場合デフォルトサーバにリクエストを振り分ける
ホスト名の一致は、完全一致、ワイルドカード、正規表現の順番に評価されます。
どのバーチャルサーバにも一致しない場合はデフォルトサーバにリクエストが振り分けられます。
デフォルトサーバは設定ファイルの一番上に記述したバーチャルサーバが使用されますが、listenディレクティブにdefault_serverパラメータを使用することで明示的に指定できる。
server { # ① listen 80 default_server; } server { # ② listen 80; server_name www.example.com; }
上の場合、www.example.com 以外へのリクエストは①のサーバコンテキストにマッチする。
listen
バーチャルサーバが使用するアドレス、ポートはlistenディレクティブで指定する。
listenディレクティブではアドレス、ポートまたはUNIXドメインソケットファイルを指定できる。
listen *:8080; #すべてのアドレスの8080番ポート listen 8080; #*:8080と同じ listen 127.0.0.1:8080; #ローカルアドレスの8080番ポート listen localhost:8080; #ホスト名で指定することもできる listen unix:/var/run/nginx.sock; #UNIXドメインソケットを指定
server_name
バーチャルサーバで使用するホスト名を指定するにはserver_nameディレクティブを使用する。
ホスト名を指定することで、80番ポートなど同じポート、アドレスで動作する複数のサーバを定義できる。
server_name example.com *.example.com;
server_nameディレクティブには複数のホスト名を指定できます。また、ホスト名の指定にはワイルドカードも使用できます。
server_name ~img\d+\.example\.com$;
ホスト名の指定には正規表現を使用することもできる。正規表現を使用する場合はチルダ(~)を先頭に付けて指定する。
root
公開するディレクトリを指定する。 nginxではrootディレクティブで指定したディレクトリのパスがそのURIのルートにマッピングされる。
root/var/www/html;
上の設定で http://www.example.com/images/example.png
にリクエストされた場合、URIにおける絶対パスは /images/example.png
。
ルートディレクトリは /var/www/html
なので、ファイルシステム上で参照されるファイルは /var/www/html/images/example.png
になる。
このようにファイルシステム上の絶対パスは、URIにおける絶対パスの前方にrootディレクティブに指定されたパスを結合したものになる。
nginxのDockerコンテナを使って静的コンテンツを表示する
Dockerfile
FROM nginx:1.13-alpine COPY nginx.conf /etc/nginx/nginx.conf RUN mkdir -p /var/www/html \ && touch /var/www/html/index.html \ && echo 'Hello' > /var/www/html/index.html
nginx.conf
user nginx; worker_processes 1; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; server { listen 80; server_name www.nginx-example; root /var/www/html; } }
Dockerfileをビルドし、nginxコンテナを8080番ポートで立ち上げる。
docker build -t $(REPOSITORY):$(VERSION) -f $(PWD)/Dockerfile $(PWD) docker run -p 8080:80 $(REPOSITORY):$(VERSION)
/test.html
でアクセスすると、Hello
が表示される!