とほほのNginx入門

目次

Nginxとは

インストール

RHEL 10 / AlmaLinux 10 / Rockey Linux 10 へのインストール

# dnf -y install nginx
# /usr/sbin/nginx -v
nginx version: nginx/1.26.3

Ubuntu 24.04 へのインストール

$ sudo apt -y install nginx
$ /usr/sbin/nginx -v
nginx version: nginx/1.24.0 (Ubuntu)

コマンドラインオプション

-?, -h
ヘルプを表示する。
-v
バージョン情報を表示する。
-V
バージョン情報とコンパイル時のオプション情報を表示する。
-t
コンフィグレーションファイルの文法をテストする。
-T
コンフィグレーションファイルの文法をテストし、コンフィグレーション情報を表示する。
-q
コンフィグレーションファイルの文法テスト時、エラーではないメッセージを抑制する。
-s signal
Nginx のプロセスにシグナルを送信する。signal には stop, quit, reopen, reload のいずれかを指定する。
-p prefix
パス名の先頭部分を指定する(デフォルト:/usr/share/nginx/)
-e filename
エラーログの出力先(デフォルト:stderr)
-c filename
コンフィグレーションファイル名(デフォルト:/etc/nginx/nginx.conf)
-g directvies
/etc/nginx/nginx.conf に記述するようなコンフィグレーション項目をコマンドラインで一時的に指定する。
# /usr/sbin/nginx -g "daemon off; master_process off;"

基本的な使用方法

Nginx の簡単な使用方法は下記です。

# /usr/sbin/nginx                # Nginxを起動する
# /usr/sbin/nginx -s quit        # Nginxを安全に終了する
# /usr/sbin/nginx -s stop        # Nginxを強制的に終了する
# /usr/sbin/nginx -s reload      # コンフィグファイルを読み直す
# /usr/sbin/nginx -s reopen      # ログファイルを再オープンする

systemctl であれば下記の様に。

$ sudo systemctl enable nginx     # OS起動時にNginxも起動する
$ sudo systemctl start nginx      # Nginxを起動する
$ sudo systemctl stop nginx       # Nginxを停止する
$ sudo systemctl restart nginx    # Nginxを再起動する

コンフィグファイル

下記の http, server, listen, root などをディレクティブと呼びます。

http {
    server {
        listen  80;
        root    /usr/share/nginx/html;
    }
}

ディレクティブのマニュアルは下記にあります。

基本設定

実行ユーザ(user)

nginx プロセスの実行ユーザを指定します。

user nginx;

サーバ設定

仮想サーバ(server)

server はひとつの仮想サーバを定義します。ポート番号(listen)やサーバー名(server_name) を変更することで複数の仮想サーバを稼働させることができます。

http {
    server {
        listen      80 default_server;
        server_name _;
        deny        all;
    }
    server {
        listen      80;
        server_name www.example.com;
        root        /usr/share/nginx/html;
    }
    server {
        listen      80;
        server_name *.example.com;
        root        /usr/share/nginx/html;
    }
}

server_name にはワイルドカード(*)や正規表現も使用できます。完全一致するものが優先で、その他は最長マッチングします。マッチするものが無い場合、default_server を指定した server、指定していない場合は先頭の server が選択されます。

ロケーション(location)

location は URL のパス名によって処理を振り分けます。パス名の前には =~ などのプレフィックスを記述することができます。

http {
    server {
        location = /favicon.ico {       # 完全一致
            ...
        }
        location /path/ {               # 前方一致(プレフィックス無し)
            ...
        }
        location ^~ /images/ {          # 前方一致(正規表現はチェックしない)
            ...
        }
        location ~ \.php$ {             # 正規表現(大文字・小文字を区別する)
            ...
        }
        location ~* \.(gif|jpg|png)$ {  # 正規表現(大文字・小文字を区別しない)
            ...
        }
    }
}

優先順位は下記となります。

リッスンポート(listen)

待ち受けポートを指定します。

listen 80;                  # 80番ポート
listen *:80;                # 80番ポート
listen 192.168.10.100:80;   # インタフェースを特定した80番ポート
listen [::]:80;             # IPv6の80番ポート
listen 443 ssl;             # SSL用の443番ポート
listen 80 default_server;   # server_nameにマッチするものが見つからない時のデフォルトサーバ

サーバ名(server_name)

サーバー名を指定します。ワイルドカード(*)や ~ で始まる正規表現を使用できます。

server_name _;                         # マッチしないサーバ(デフォルトサーバ)
server_name www.example.com;           # 文字列指定
server_name *.example.com;             # ワイルドカード指定
server_name ~^([a-z]+)\.example\.com$; # 正規表現指定

ページ設定

ルートディレクトリ(root)

ルートディレクトリを指定します。

root /usr/share/nginx/html;

インデックスファイル(index)

URL でファイル名を省略した場合に表示するインデックスファイルのファイル名を指定します。複数記述した場合は先頭から探します。デフォルトは index.html です。

index index.html index.htm;

自動インデックス(autoindex )

URL がディレクトリを示していて、index で指定されたファイルも存在しない場合、ファイルの一覧を表示することを許可します。

autoindex on;

エラーページ(error_page)

404 Not Found などのエラーが発生した際に指定した URL にリダイレクトします。

server {
    error_page 404 /404.html;
    error_page 500 502 503 504 /50x.html;
}

パス名置換(rewrite)

rewrite を用いてアクセスしてきたパス名を置換することができます。

server {
    rewrite ^/old/(.*)$ /new/$1 last;
}

第3引数には下記のいずれかを指定することができます。

レスポンス設定

レスポンスヘッダ追加(add_header)

レスポンスにHTTPヘッダを追加します。

add_header X-Debug-Message 'IP: $remote_addr';

レスポンスヘッダ上書き(more_set_headers)

レスポンスヘッダを追加ではなく上書きする場合は headers-more-nginx-modulemore_set_headers を用います。ただし、headers-more-nginx-module が Nginx に組み込まれていない場合は再コンパイルが必要です。

more_set_headers 'Content-Type: application/json';

ステータスとテキストを返却(return)

指定したHTTPステータスで、テキストや URL の内容を返却します。

location = /hello {
    add_header Content-Type text/plain;
    return 200 "Hello!!\n";
}
location = /foo {
    return http://192.168.100.1/foo;
}

ファイルを返却(alias)

alias を用いると、指定したファイルを返却することができます。

location = /favicon.ico {
    alias /usr/share/nginx/html/favicon.ico;
}

ファイルを検索(try_files)

try_files はファイルを検索します。下記の例ではアクセスに対して /file1 の URL で示されるファイルを探し、無ければ /file2、無ければ /file3 を探します。最後の引数のみは検索ではなく、/file1~3 がいずれも見つからなかった時に返却するコンテンツの URL を指定します。try_files というディレクティブ名ですが、引数に指定するのはファイル名ではなく URL であることに注意してください。

try_files /file1 /file2 /file3 /error.html

最後の引数には =404 のようにステータスコードを指定することができます。通常、http://.../dirA に対してアクセスすると /dirA/ への 301 リダイレクトを返し、再度ブラウザが /dirA/ にアクセスしますが、下記の様に設定しておくと、指定した URL が見つかればそれを、見つからなければディレクトリと見なして $uri/index.html を、見つからなければ 404 Not Found エラーを返します。

try_files $uri $uri/index.html =404;

ログ設定

エラーログ(error_log)

エラーログを記録するファイル名と記録レベルを指定します。debug, info, notice, warn, error, crit, alert, emerg のレベルがあります。

error_log /var/log/nginx/error.log notice;

アクセスログ(access_log, log_format)

アクセスログを記録するファイル名とフォーマットを指定します。フォーマットの詳細は log_format を参照してください。

http {
    log_format formatA '$time_iso8601 $remote_addr $status $request';
    access_log  /var/log/nginx/access.log formatA;
}

off を指定するとログを記録しません。favicon.ico へのアクセスログを抑制した場合は下記など。

location = /favicon.ico {
    access_log off;
}

性能設定

ワーカープロセス数(worker_processes)

ワーカープロセス数を指定します。auto を指定すると自動的に増減されます。

worker_processes 10;
worker_processes auto;

ワーカーコネクション数(worker_connections)

ワーカーコネクション数を指定します。ひとつのワーカープロセス毎の値ではなく、すべてのワーカープロセスのコネクション数の最大総数を指定します。システムのファイル数の上限(ulimit -n)を超えることはできません。

events {
     worker_connections 1024;
}

クライアント最大ボディサイズ(client_max_body_size)

クライアントからのリクエストの最大ボディサイズを指定します。下記の例では 100MB に設定しています。

client_max_body_size 100m;

セキュリティ設定

アクセス元IPアドレス制限(allow, deny)

下記を指定すると、192.168.100.100 や 192.168.200.* からのアクセスのみに制限することができます。

server {
    allow 192.168.100.100;
    allow 192.168.200.0/24;
    deny  all;
}

直IPアクセス制限(default_server)

下記を指定すると、直IPアドレス指定など、他の server ディレクティブのサーバ名にマッチしないアクセスを拒絶することができます。

http {
    server {
        port        80 default_server;
        server_name _;
        deny        all;
    }
    server { ... }
    server { ... }
}

BASIC認証する(auth_basic)

まず、下記の手順で .htpasswd ファイルを作成します。

# dnf -y install httpd-tools                # RHEL系の場合
$ sudo apt-get install apache2-utils        # Ubuntu系の場合
$ htpasswd -c /etc/nginx/.htpasswd yamada   # 1人目のユーザーの場合
New password: ************
Re-type new password: ************
$ htpasswd /etc/nginx/.htpasswd suzuki      # 2人目以降のユーザーの場合
New password: ************
Re-type new password: ************

コンフィグファイルに下記を追記します。

server {
    auth_basic           "BASIC AUTH";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

HTTPSでアクセスする(ssl_*)

自己署名証明書(オレオレ証明書)」または正式な手順でサーバーの秘密鍵(*.key)と証明書(*.crt)を作成し、コンフィグファイルを下記を記述します。

server {
    listen              443 ssl;
    ssl_certificate     /etc/nginx/cert/server.crt;
    ssl_certificate_key /etc/nginx/cert/server.key;
}

アプリケーション連携

CGI連携(Perlなど)

Nginx → fcgiwrap → スクリプトの流れで処理します。まず、fcgiwrap をインストールします。

# RHEL/AlmaLinux/Rocky Linuxの場合
# dnf -y install epel-release
# dnf -y install fcgiwrap

# Ubuntuの場合
$ sudo apt-get install fcgiwrap

Nginx のコンフィグファイルに下記を追加します。

location ~ /cgi-bin/.*\.cgi$ {
    fastcgi_pass 127.0.0.1:4000;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

fcgiwrap を起動します。

# /usr/sbin/fcgiwrap -s tcp:127.0.0.1:4000 &

cgi-bin/index.cgi などに簡単なCGIを作成して試してみます。

#!/bin/bash
echo Content-Type: text/plain
echo
echo Hello
$ chmod 755 ./cgi-bin/index.cgi
$ curl http://localhost/cgi-bin/index.cgi
Hello

PHP連携

Nginx → php-fpm → PHPスクリプトの流れで処理します。まず、php-fpm をインストールします。

# dnf -y install php-fpm             # RHEL/AlmaLinux/Rocky Linuxの場合
$ sudo apt-get -y install php-fpm    # Ubuntuの場合

Nginx のコンフィグファイルに下記を追加します。

location ~ \.php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php-fpm/www.sock;     # RHEL/AlmaLinux/Rocky Linuxの場合
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;  # Ubuntu 24.04の場合
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}

/run/php-fpm ディレクトリを作成して php-fpm を起動します。

# mkdir /run/php-fpm   # Ubuntuの場合は不要
# /usr/sbin/php-fpm

簡単な PHP スクリプト(index.php)を作成して試してみます。

<?php
echo "Hello world!!\n";
$ curl http://localhost/index.php
Hello world!!

Python連携

Ubuntu 24.04 の場合もコンテナ内で root で操作することを前提としています。

# RHEL系
# dnf -y install nginx python3 python3-pip python3-devel gcc procps

# Ubuntu系
# apt-get update
# apt-get -y install nginx python3 python3-pip python3-venv vim curl

Nginx のコンフィグファイルに下記を追加してください。RHEL系の場合は /etc/nginx/nginx.conf の中の server ディレクティブに追加。Ubuntu の場合は /etc/nginx/sites-available/defaultserverlocation ディレクティブを書き換え。

location / {
    include uwsgi_params;
    uwsgi_pass 127.0.0.1:5000;
}

Nginx を起動してください。

# /usr/sbin/nginx

uwsgi をインストールして設定していきます。

# useradd -m -d /opt/myapp -s /bin/bash myapp
# mkdir -p /opt/myapp /var/log/myapp /var/run/myapp
# chown -R myapp:myapp /opt/myapp /var/log/myapp /var/run/myapp
# su - myapp    # RHEL系の場合は不要。Ubuntuの場合はプロンプトが変わります
# python3 -m venv ~/myenv
# source ~/myenv/bin/activate
# pip3 install uwsgi

/opt/myapp/uwsgi.ini ファイルを作成してください。

[uwsgi]
master = true
socket = 127.0.0.1:5000
processes = 4
uid = myapp
gid = myapp
chdir = /opt/myapp
wsgi-file = /opt/myapp/app.py
module = app:app
logto = /var/log/myapp/uwsgi.log
pidfile = /var/run/myapp/uwsgi.pid

/opt/myapp/app.py ファイルを作成してください。WSGI の詳細は Python/WSGI を参照してください。

def app(environ, start_response):
    start_response('200 OK', [('Content-Type','text/plain')])
    return ["OK\n".encode("UTF-8")]

uwsgi を起動した後、curl で動作確認します。

# uwsgi --ini /opt/myapp/uwsgi.ini &
# curl http://localhost
OK

Flask を利用する場合はまず Flask をインストールします。

# pip3 install flask

/opt/myapp/app.py を次のように書き換えて、uwsgi を再起動して(SIGTERMを送るのでも可) http://~ を呼び出してみてください。

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello!\n"

その他

リバースプロキシ(proxy_pass)

Nginx への要求を http://192.168.100.1 にリバースプロキシします。転送の際、HostX-Real-IPX-Forwarded-For ヘッダを設定しています。

server {
    listen 80;
    location / {
        proxy_set_header Host $http_host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_pass http://192.168.100.1;
    }
}

リバースプロキシを多段にしている場合、フロントのプロキシは上記の設定にしておき、2段目以降の X-Forwarded-For には下記を指定することでプロキシのIPアドレスを追加することができます。フロントのリバースプロキシに設定してしまうと、偽装された X-Forwarded-For 情報を転送してしまうので注意してください。

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;