【入門】nginx とは?設定方法を紹介

「Web/アプリケーション/プロキシ/API」サーバー構築シリーズの Web サーバー編です。

その他の記事については、以下の記事をご覧ください。

スポンサーリンク

nginx とは

nginx とは、以下の機能を持つ Web サーバーです。
HTTP サーバー(Web サーバー)
 - 静的 Web サーバー
 - 動的 Web サーバー
HTTP リバースプロキシサーバー
ロードバランサー
TCP/ UDP リバースプロキシサーバー
メールプロキシサーバー

Web サーバー・HTTP サーバー

Web サーバーとは、「HTTP サーバー (必須) 」と「ファイル (オプション) 」の集まりのことです。

HTTP サーバーとは、URL および HTTP プロトコルを理解するソフトウェアのことです。

https://developer.mozilla.org/ja/docs/Learn/Common_questions/What_is_a_web_server

なお、Web サーバーは以下の2種類が存在します。

静的 Web サーバー動的 Web サーバー
構成要素HTTP サーバー (ソフトウェア)
コンピューター (ハードウェア)
静的 Web サーバー
アプリケーションサーバー (AP)
データベース (DB)
レスポンスサーバーにあるファイルをそのまま返すAP や DB を利用してファイルを毎回生成して返す

プロキシ・リバースプロキシとは

プロキシサーバーとは、クライアントの代わりに外部のサーバーにアクセスするサーバーです。

リバースプロキシサーバーとは、クライアントからのアクセスをサーバーに転送するサーバーです。

リバースプロキシサーバーをバックエンドサーバーの前段に置く理由は、以下の5つです。

  • キャッシュサーバーとして利用 (レスポンスの高速化とバックエンドサーバーの負荷を軽減)
  • レスポンスを圧縮 (レスポンスの転送を高速化)
  • SSL ターミネーション (暗号化や復号化の処理をリバースプロキシにオフロード)
  • セキュリティの向上 (リバースプロキシでフィルタリング、バックエンドサーバーを隠蔽)
  • 拡張性 (クライアントはリバースプロキシと通信するので、バックエンドサーバーを変更可能)

なお、nginx はリバースプロキシに対応しています。

nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev.

http://nginx.org/en/

プロキシサーバーを構築する場合は、Squid を利用します。

ロードバランサーとは

ロードバランサーとは、クライアントからのアクセスを各サーバーに振り分けることで、負荷分散を行うサーバーです。

ロードバランサーは、1台のサーバーで処理できないような大量なリクエストに対応するために利用します。

リバースプロキシとロードバランサーの違い

  • ロードバランサーは負荷分散に利用
    • バックエンドサーバーは複数の同じサーバーを置きます
  • リバースプロキシは転送に利用
    • バックエンドサーバーが1台でも OK
    • バックエンドサーバーに異なるサーバーを置いても OK
    • 認証サーバーに転送し、認証に成功した場合は Web サーバーに転送といったことが可能

本記事で紹介する nginx の設定

本記事では、以下の設定方法を記載します。

スポンサーリンク

nginx の使い方

nginx のセットアップ

nginx のインストール

nginx を起動

sudo systemctl start nginx

ブラウザの URL 欄にサーバーの IP アドレスを入力すると Web ページが確認できます。

nginx の設定

設定ファイルは「/etc/nginx/nginx.conf」です。

設定ファイルに関する用語

用語説明
モジュール取り外し可能な小さなプログラム
使う機能(モジュール)のみを取り込むことで、プロセスサイズを小さくしてメモリ消費量を抑える
ディレクティブ命令
モジュールは複数のディレクティブから構成される
コンテキスト適用範囲
ディレクティブを{ } で囲む

ディレクティブの一覧は以下のとおりです。

ディレクティブのアルファベットの索引 日本語訳

ディレクティブの設定例

構文:server { ... }
デフォルト:-
コンテキスト:http
http://mogile.web.fc2.com/nginx/http/ngx_http_core_module.html#server

例えば、上記の「server」ディレクティブは以下のように利用します。

http{
    server{
    }
}

server」ディレクティブは、「http」ディレクティブのコンテキストなので、 "http { }" で囲んで利用します。

なお、「server」、「http」ディレクティブは ngx_http_core_module モジュールに含まれます。

main コンテキスト

設定ファイル /etc/nginx/nginx.conf は、暗黙的に main コンテキストで囲まれています。

構文:useruser [group];
デフォルト:user nobody nobody;
コンテキスト:main
http://mogile.web.fc2.com/nginx/ngx_core_module.html#user

つまり、上記の「main」コンテキストにある「user」ディレクティブは以下のように利用できます。

user nginx;

/etc/nginx/conf.d/

http コンテキストの設定は「/etc/nginx/conf.d/」配下に、追加で設定ファイルを置くことができます。

これは「etc/nginx/nginx.conf」ファイルの以下の include ディレクティブによるものです。

http {
    (中略)
    include /etc/nginx/conf.d/*.conf;
}
スポンサーリンク

静的 Web サーバーの設定

静的 Web サーバーとは、保持しているファイルをブラウザーへ「そのまま」送るサーバーです。

ここでは、nginx を静的 Web サーバーとして設定方法を紹介します。

Web ページを作成

テキストファイルと画像ファイルを配置するディレクトリを作成し、ファイルを配置します。

sudo mkdir /var/www
sudo sh -c 'echo "text files path" > /var/www/index.html'
sudo mkdir /var/images
sudo sh -c 'echo "images files path" > /var/images/index.html'

nginx の設定

静的 Web ページは以下のように設定します。

sudo vim /etc/nginx/conf.d/static.conf
server {
    listen localhost:80;
    location / {
        root    /var/www;
    }

    location /images/ {
        root /var;
    }
}
ディレクティブ説明
listen接続を待ち受けるアドレスとポート番号
今回は「localhost:80」でアクセスした場合の設定
locationURL のパスごとに動作を決定(最長一致)
今回は以下の2つでアクセスした場合の設定
・「localhost:80/
・「localhost:80/images/
rootドキュメントルート(Web ページのファイルを置く場所)を指定
アクセスするパスは「<root> + <location>」となります。
・/var/www + / = /var/www/
・/var + /images/ = /var/images/
sudo systemctl restart nginx

動作確認

以下のコマンドで動作確認をします。

curl localhost/index.html
text files path

「location」ディレクティブで指定した「/」にアクセスしたので、「/var/www/」に存在する index.html の内容が表示されています。

curl localhost/images/index.html
images files path

「location」ディレクティブで指定した「/images/」にアクセスしたので、「/var/images/」に存在する index.html の内容が表示されています。

静的 Web サーバーでは、「現在 ** 人やこのページを見てます」のようなアクセスする度にページの内容を変更することはできません。このような Web ページを作成する場合は、動的 Web サーバーを利用します。

動的 Web サーバーの設定

動的 Web サーバーとは、保持しているファイルをアプリケーションが変更してから、HTTP サーバを通してブラウザーに送信するサーバーです。

冒頭で述べたように、動的 Web サーバーは主に以下の3要素で構成されます。

今回は、静的 Web サーバー + アプリケーションで動的な Web ページを作成します。

ゲートウェイインターフェース

Web サーバーとアプリケーション (or AP サーバーとアプリケーション) を繋ぐには、以下のようなゲートウェイインターフェースを利用します。

対応言語ゲートウェイインターフェース
どの言語でもFastCGI (Common Gateway Interface)
PythonWSGI (Web Server Gateway Interface)
RubyRack (Ruby web server interface)
PerlPSGI (Perl web Server Gateway Interface)
JavaJava Servlet
PHPFPM (FastCGI Process Manager)

一般的には、各言語に特化したインターフェースの方が使いやすかったり、機能が充実しています。

WSGI を利用して動的 Web ページを作成する場合は以下の記事をご覧ください。

本記事では、言語に依らない FastCGI を紹介します。

FastCGI (fcgiwrap) をインストール

ここでは Amazon Linux 2 での fastcgi を利用したインストール方法を紹介します。

デフォルトのリポジトリに「fcgiwrap」パッケージが存在しないため、EPEL(Extra Packages for Enterprise Linux)リポジトリを追加します。

sudo amazon-linux-extras install epel -y

fcgiwrap (FastCGI) をインストールします。

sudo yum install fcgiwrap -y

FastCGI プロセスを生成するために、spawn-fcgi をインストールします。

sudo yum install spawn-fcgi -y

spawn-fcgi の設定

sudo vim /etc/sysconfig/spawn-fcgi

UNIX ドメインソケットに「/var/run/fcgiwrap.socket」を bind し、FastCGI プロセスとして「/usr/sbin/fcgiwrap」を利用するように設定します。

OPTIONS="-u nginx -g nginx -s /var/run/fcgiwrap.socket -S -M 0770 -F 1 -P /var/run/spawn-fcgi.pid -- /usr/sbin/fcgiwrap"
sudo systemctl start spawn-fcgi

FastCGI プログラムを Python で作成

sudo vim /usr/share/nginx/html/test.py
#!/usr/bin/python3
import random
print("HTTP/1.0 200 OK")
print("Content-type: text/html\n")
print("ランダムな数字を表示します。")
print(random.random())
sudo chmod 755 /usr/share/nginx/html/test.py

FastCGI プロキシの設定

sudo vim /etc/nginx/conf.d/fcgi.conf
server {
    listen       localhost:8080;

    location ~ \.py$ {
      root   /usr/share/nginx/html/; #$document_root
      fastcgi_pass unix:/var/run/fcgiwrap.socket;
      include           /etc/nginx/fastcgi_params;
      fastcgi_param     SCRIPT_FILENAME   $document_root$fastcgi_script_name;
    }
}

$document_root
現在のリクエストのroot または aliasディレクティブ値

$fastcgi_script_name
変数の値の中のスラッシュで終わるURIの後に追加されるファイル名を設定します。

http://mogile.web.fc2.com/nginx/http/ngx_http_core_module.html#variables
http://mogile.web.fc2.com/nginx/http/ngx_http_fastcgi_module.html#var_fastcgi_script_name
ディレクティブ説明
fastcgi_passFastCGI サーバーのアドレス or UNIX ドメインソケットパスを指定します。
今回は spawn-fcgi で指定した UNIX ドメインソケットパスを指定します。
fastcgi_paramFastCGI サーバーに渡すパラメータを指定します。
・SCRIPT_FILENAME は利用する FastCGI プログラムのパスを指定します。
・他にも「QUERY_STRING」・「REQUEST_METHOD」等があります。
sudo systemctl restart nginx

動作確認

curl localhost:8080/test.py
ランダムな数字を表示します。
0.035786423335100515

上記の Web ページは test.py はランダムな数字を生成する FastCGI プログラムを利用して、アクセスする度に HTML を生成しています。

実際にもう1度アクセスしてみると、Web ページの内容が変わっていることがわかります。

curl localhost:8080/test.py
ランダムな数字を表示します。
0.5110232597988356

リバースプロキシの設定

リバースプロキシサーバーとは、クライアントからのアクセスをサーバーに転送するサーバーです。

キャッシュがあれば Web サーバーに転送せずに、リバースプロキシがキャッシュをレスポンス

今回は同一ホストに「リバースプロキシサーバー」と「 Web サーバー」を立てます。

Web ページの作成

Web サーバーで利用する Web ページを作成します。

sudo mkdir /var/proxy
sudo sh -c 'echo "proxied page" > /var/proxy/index.html'
sudo chmod 755 /var/proxy/index.html

nginx のリダイレクトの設定

sudo vim /etc/nginx/conf.d/proxy.conf

「8001 ポートがリバースプロキシサーバー」、「8002 ポートが Web サーバー」となるように設定します。

server {
    listen localhost:8001;
    location / {
        proxy_pass  http://localhost:8002/proxy/;
    }
}

server {
    listen localhost:8002;

    location /proxy/ {
        root /var;
    }
}

「proxy_pass」ディレクティブでリバースプロキシサーバーがリクエストを転送する先を指定します。

今回は同じホスト(localhost)に転送してますが、異なるホストの IP アドレスを指定することも可能です。

sudo systemctl restart nginx

動作確認

curl localhost:8001/
proxied page

8001 ポートのリバースプロキシサーバーにアクセスし、8002 ポートのウェブサーバーに転送されていることが確認できます。

ロードバランサーの設定

ロードバランサーとは、クライアントからのアクセスを複数の Web サーバーに振り分けることで負荷分散を行うサーバーです。

nginx ではリバースプロキシの機能を利用してロードバランサーを実現します。

1台のロードバランサーで3台のWebサーバーで処理を分散する

4台もホストを用意できないよ!!という方は後述する docker コンテナを4つ利用する方法を実施ください。

3台の Web サーバーを設定

3 台のホストで以下のコマンドを実行します。

sudo amazon-linux-extras install nginx1 -y

3台の Web サーバーを区別するために、異なる Web ページを作成します。

sudo sh -c 'echo "server1" > /usr/share/nginx/html/loadbalance.html'
sudo sh -c 'echo "server2" > /usr/share/nginx/html/loadbalance.html'
sudo sh -c 'echo "server3" > /usr/share/nginx/html/loadbalance.html'

3台のホストで Web サーバーを起動します。

sudo systemctl start nginx

nginx の設定

ロードバランサーのホスト1台で以下の設定を行います。

sudo vim /etc/nginx/conf.d/loadbalancer.conf
server {
    listen 8003;

    location / {
        proxy_pass http://myapp1;
    }
}

upstream myapp1 {
    server 192.0.2.1;
    server 192.0.2.2;
    server 192.0.2.3;
}

赤線で引いたホストの IP アドレスは適宜置き換えてください。

ディレクティブ説明
proxy_passロードバランサーのプロキシ先を指定します。
upstream のグループ名を指定します。
upstreamロードバランサー配下に置く各 Web サーバーを設定します。
sudo systemctl restart nginx

動作確認

アクセスする度に異なるサーバーにロードバランスされていることがわかります。

curl localhost:8003/loadbalance.html
server1
curl localhost:8003/loadbalance.html
server2
curl localhost:8003/loadbalance.html
server3

docker で nginx を起動

docker を利用して nginx を起動する方法を紹介します。

なお、そもそも docker って何?という方や、まだ docker をインストールしていない方は以下の記事をご覧ください。

また、既に 80 番ポートで nginx が listen している場合は停止しておいてください。

sudo systemctl stop nginx

nginx コンテナを起動

今回利用する nginx のイメージファイルは以下です。

Docker Hub
docker run --rm -d --name nginx -p 80:80 nginx:latest

使い終わったらコンテナは止めておきましょう。

(後述するロードバランサーで 80 番ポートを使います)

docker stop nginx

docker でロードバランサーを実現

以下の構成を目指して、4つの nginx コンテナを作成します。

Web ページを作成

各 Web サーバーが区別できるように、Web ページの内容を「server1」・「server2」・「server3」とする。

sudo sh -c 'echo "server1" > /var/local/server1.html'
sudo sh -c 'echo "server2" > /var/local/server2.html'
sudo sh -c 'echo "server3" > /var/local/server3.html'

nginx の設定

sudo vim /var/local/load_balancer.conf
server {
    listen 80;

    location / {
        proxy_pass http://myapp1;
    }
}

upstream myapp1 {
    server web_server1;
    server web_server2;
    server web_server3;
}

upstream の server ディレクトリでは、後述する docker-compose.yml の「container_name」を指定しています。

docker-compose.yml を作成

1つのロードバランサーと、3つの Web サーバーを用意します。

version: '3'

services:
    load_balancer:
        image: nginx:latest
        ports:
            - "80:80"
        volumes:
            - /var/local/load_balancer.conf:/etc/nginx/conf.d/default.conf

    web_server1:
        container_name: web_server1
        image: nginx:latest
        volumes:
            - /var/local/server1.html:/usr/share/nginx/html/server.html

    web_serber2:
        container_name: web_server2
        image: nginx:latest
        volumes:
            - /var/local/server2.html:/usr/share/nginx/html/server.html

    web_serber3:
        container_name: web_server3
        image: nginx:latest
        volumes:
            - /var/local/server3.html:/usr/share/nginx/html/server.html

nginx コンテナを起動・動作確認

docker-compose でコンテナを一気に起動します。

docker-compose をインストールしていない方は以下の記事をご覧ください。

ロードバランサー(localhost:80)にアクセスする度に、各 Web サーバーからレスポンスが戻ってきていることを確認できる。

curl localhost/server.html
server1
curl localhost/server.html
server2
curl localhost/server.html
server3

関連記事

サーバー構築シリーズの続きは以下のとおりです。


参考資料

Beginner’s Guide