- 会社でNginxを使うことになったけど、何が何だかさっぱりだ…
- Nginxはインストールできたけど、設定ファイルの意味が全然わからない。
- エラーが出てもどう対処したらいいか不安…
- 前にNginxを挑戦したけど挫折。今度こそ成功させたい。
このような疑問にお答えします。
これまでアプリケーションを作るためにプログラムを書き続けた方は、今回紹介するような少し低レイヤーのソフトウェアを苦手に感じる場合が多いと思います。
僕自身もPythonでデスクトップで動くだけの自動化ソフトばかり作っていた時期には、「Nginxってなんだか難しそうだな…」と漠然としたイメージがありました。
ところがサーバーに触れる機会が増えていくに従って、「あ、なんとなくこんな感じのものなんだな!」という実感が徐々についてくるようになりました。
本記事ではNginxに対して漠然とした恐怖を感じている方に、基礎から実際の運用までを詳しく解説していきます。
書籍で学びたい方は『nginx実践ガイド』はおすすめ。
KindleUnlimitedに加入すれば無料で読めますし、かなり詳しく書かれているのでざっと一読しておくと良いと思います。
Nginx入門: ウェブサーバとは何か?
ウェブサーバーはWebページやWebアプリケーションを配信するシステムです。ブラウザからのリクエストに従って、HTTPSなどのプロトコルで通信します。
また、このようなコンテンツを配信する役割の他にも、セキュリティやパフォーマンス最適化も担当する結構重要な存在です。
Nginxはウェブサーバーの一種
Nginxはウェブサーバーの役割を果たすソフトウェアです。
とはいえ、他にも「ロードバランサの機能がある」だったり「リバースプロキシの機能もある」などと言われますが、これらはウェブサーバーの機能の一部を切り取って表現したものと考えて良いかと思います。
以下に、それぞれの概念をサクッと解説します。
- ウェブサーバー
HTTPリクエストを受けて、対応するリソース(HTML, CSS, JavaScriptなどの静的ファイル)を返す役割。 - リバースプロキシ
クライアントからのリクエストをバックエンドのサーバーに転送し、サーバーからのレスポンスをクライアントに返す役割。 - ロードバランサ
リクエストを複数のバックエンドサーバーへのうまく分散させる役割。
つまり、Nginxは基本的にウェブサーバーとして使われる。
でも、その一部の機能であるリバースプロキシやロードバランサといった単体の機能を切り出して使うこともあると理解すると良いと思います。
Nginxの特徴
Nginxの特徴は以下の通りです。
- ハイパフォーマンス
動作が高速。
非同期イベント駆動型の設計により、リソースの消費を抑えつつ効率的に同時接続の処理ができる。 - 静的コンテンツ配信
静的ファイル(HTML、CSS、JavaScript、画像など)の高速配信に優れる。 - リバースプロキシ
セキュリティの強化、負荷分散、キャッシュ機能などを備える。
最近では全世界のウェブサーバーの3分の1がNginxになったと言われていて、シェアとしてはトップクラスです。
このシェアの高さを考えても、Nginxを学んでおく価値は十分にあると思います。
Nginxの内部構造
Nginxは「マスタープロセス」と「ワーカープロセス」の二つで構成されています。
- マスタープロセス
設定ファイルの読み込み・検証 / ワーカープロセスの管理
※ rootユーザーで起動。 - ワーカープロセス
実際のリクエストの処理
※ nginxやwwwなどの一般ユーザーで起動。
マスタープロセスという親プロセスがいて、その配下に複数のワーカープロセスがぶら下がっているというイメージで考えると良いと思います。
また、ワーカープロセスは複数のクライアントからのリクエストを非同期に処理できるので、システム全体の処理能力を向上することができています。(つまりI/Oを多重化することで処理能力を上げている)
Nginxで使うファイル名と一般的な保存先ディレクトリ
よく使う設定ファイルの場所とファイル名が以下となります。
dir | file / dir | 内容 |
---|---|---|
/etc/nginx/ | nginx.conf | nginxの全体的な設定 |
conf.d/ | 個々のサーバーの設定ファイルを格納 | |
sites-available/ と sites-enabled/ | サイトの設定はavailableに書き、enableより参照させる(シンボリックリンク) | |
/var/log/nginx/ | access.log | アクセスログ |
error.log | エラーログ | |
/user/share/nginx/html/ または /var/www/html/ | – | デフォルトのドキュメントディレクトリ。ウェブサイトの静的コンテンツが保存される |
これらのディレクトリは、nginx周りの設定の際によく使うことになります。
Nginxのインストールと初期設定: 最初の一歩
Nginxのインストールと初期設定について解説します。
パッケージの種類についても必要最低限の内容をさらっと解説していきますので、さらっと目を通してみてください。
パッケージの種類
Nginxには二つのパッケージが用意されています。
- nginx Mainline
最新の開発版で、新機能が搭載されたもの。安定性は保証されていない。 - nginx Stable
安定版で新機能の追加は控えめ。安定性とセキュリティが重視される。
Nginxの変更は、まずMainlineに反映されます。
そしてMainlineに取り込まれたもののうち、重大なバグ修正のみがStableに取り込まれる流れです。
毎年4月にメジャーアップデートとしてMainlineからStableに分岐し、同時に古いStable版はサポート終了になります。
Nginxのインストール
Ubuntu環境では、以下の流れでインストールを行います。
# パッケージリストの更新
sudo apt-get update
# nginxのインストール
sudo apt-get install nginx
簡単にインストールする場合にはこれで良いですが、このコマンドでインストールされるのはStable版になります。
また、Ubuntuのリポジトリの場合には最新のStable版とは限らないので、特定のバージョンを使いたい場合にはNginxの公式リポジトリを追加する必要があります。
インストールされたファイルの全体構造
Nginxのインストールによって生成されるファイルの全体構造を見てみましょう。
種類としては意外と少ないので、ざっと眺めて全体感をつかんでおきましょう。
Dir / File | 内容 |
---|---|
/etc/nginx | Nginxの主要設定ファイルを格納するディレクトリ。 ここにはnginx.confという主要な設定ファイルと、サイト固有の設定を含むサブディレクトリ(/etc/nginx/sites-available/ と /etc/nginx/sites-enabled/)がある。 |
/var/www/html | デフォルトで設定されたWebルートディレクトリで、Webサイトのファイルを置く場所。 |
/var/log/nginx/access.log | Nginxのアクセスログが格納され、すべてのリクエスト情報がここに記録される。 |
/var/log/nginx/error.log | Nginxのエラーログが格納され、問題が発生した場合にはこのログを確認する。 |
ファイアウォールの設定
ファイアウォールはNginxではなくOS側で設定するものではありますが、必ず設定することになるのでここで説明します。
ここではUbuntuなどで使われるufwコマンドを使った例を示します。
# ufwを有効化する / 外部からのアクセスをすべて閉じる
sudo ufw enable
# HTTP(80), HTTPS(443), SSH(22)を解放する
sudo ufw allow 80
sudo ufw allow 443
sudo ufw allow 22
# ufwの状態や設定を確認する
sudo ufw status
CentOSなど別のOSをお使いの場合には別のコマンドが用意されていることがあります。お使いのOSに合わせて設定を進めて下さい。
起動、終了、再起動、設定ファイルの再読み込み
UbuntuやCentOS7以降で使われるsystemdを使ったコマンド例を掲載します。
# 起動
sudo systemctl start nginx
# 終了
sudo systemctl stop nginx
# 再起動
sudo systemctl restart nginx
# 設定ファイルの再読み込み
sudo systemctl reload nginx
# nginxサービスをシステムの起動時に自動的に起動
sudo systemctl enable nginx
Nginxコマンドの使い方
一般的にはシステムのサービスとしてNginxを管理するために、前にご紹介したsystemctl
コマンドを使用するのが推奨されています。
一方、Nginxコマンドを使うとNginxの内部動作に直接影響を与えるので、設定ファイルの構文チェックやログファイルの再オープンなどはnginxコマンドの方が適している場合があります。
# Nginxを起動する("/etc/nginx/nginx.conf"を読み込み)
nginx
# Nginxを即座に停止
nginx -s stop
# Nginxをグレースフルに終了(現在の接続がすべて終了したらNginxを停止)
nginx -s quit
# 設定ファイルを再読み込み
nginx -s reload
# 既存のログファイルを閉じて、新しいログファイルを開く
nginx -s reopen
# 設定ファイルの構文チェック
nginx -t
# Nginxのバージョンを表示
nginx -v
# 別パスにある設定ファイあるを指定してNginxを起動
nginx -c /path/to/file
必要に応じてsystemctlコマンドとnginxコマンドを使い分けてみて下さい。
簡単な静的サイトをNginxで構築
Nginxの操作に慣れるには、まず静的なサイトを構成してみるのがおすすめです。
Webアプリケーションのようにユーザー側のリクエストに応じて返すデータが異なると、設定ファイルなどが煩雑になるためです。
基本操作
まずはNginxのインストールと起動を行います。
sudo apt-get update
sudo apt-get install nginx
sudo systemctl start nginx
この状態でWebブラウザからhttp://localhostにアクセスすると、Nginxのデフォルトのウェルカムページが表示されるはずです。
Webサーバーの構築
HTML、CSS、JavaScriptなどの静的ファイルをサーバー上に配置します。
これらのデータはnginxのルートドキュメントディレクトリ(/var/www/html
)に配置して下さい。
設定ファイルの構造
Nginxの主な設定ファイルは/etc/nginx/nginx.confにあります。ところが、個々のサイトの設定は/etc/nginx/sites-available/
にあるファイルに書くことが一般的です。
例えばドメインexample.com
に対する設定は以下のように書きます。
server {
# 80番ポート(HTTP)でリクエストを受け付ける
listen 80;
# ドメイン名
server_name example.com;
location / {
# リクエストされたURLのファイルがある場所を指定
root /var/www/example.com;
# リクエストを受けた時に提供するファイル名
index index.html;
}
}
ファイル名は分かりやすいものでOKです。例えば、今回はexample.comというウェブサイトの設定なので、/etc/nginx/sites-available/example.comなどとしておけば良いと思います。
また、sites-availableディレクトリに配置した設定ファイルを有効化するには、/etc/nginx/sites-enabled/ディレクトリへのシンボリックリンクを作成します。(つまり、参照先を明示する)
# シンボリックリンク(ショートカットのようなもの)を作成する
sudo ln -s /etc/nginx/sites-available/exapmle.com /etc/nginx/sites-enabled/
Nginxでは、デフォルトでsites-enabledディレクトリ内の設定ファイルを読み込みますが、site-availableディレクトリ内は読み込みません。
そのため、Nginxの読み込み対象のディレクトリにシンボリックリンクを配置することで、Nginxの設定対象範囲に含めることになります。
最後に、設定の変更を反映させるためにNginxをリロードします。
sudo systemctl reload nginx
これで先ほどセットしたページが読み込まれるようになるはずです。
Nginxで実装するアクセス制限
Nginxでは、設定ファイルを使ってさまざまなレベルのアクセス制限を行うことができます。
ちなみにファイアウォールはサーバー自体にアクセスできるかどうかを制御するものであるのに対して、アクセス制限はサーバーに入ってからの権限を細かく設定するという違いがあります。
Basic認証によるアクセス制限
Nginxではユーザー名とパスワードによる認証を利用してアクセス制限することができます。
location / {
auth_basic "closed site";
auth_basic_user_file conf/.htpasswd;
}
この場合、ユーザー名とパスワードは.htpasswdファイルに記載することになります。
ここで、htpasswdファイルに暗号化せず平文で記載してしまうと誰かに読まれた時に非常にリスキーです。そのため、ユーザー名・パスワードの登録にあたってはApacheのhtpasswdコマンドなどを使って暗号化しておきます。
# Apacheが未インストールの場合
sudo apt-get install apache2-utils
# 新しいファイルを作成(-cオプションを外すと上書きしない)
sudo htpasswd -c /etc/nginx/.htpasswd username
ただ、ここまでの例ではHTTPプロトコルによるアクセスを前提にしてきたため、このBasic認証を設定した場合には第三者に通信が傍受されてIDやパスワードが盗まれてしまう場合があります。(認証情報はBase64エンコードで送信されるので、簡単にデコードできるため)
これを避ける方法としては、HTTPではなくHTTPSで通信する方法があります。
IPアドレスによるアクセス制限
本来であればファイアウォールで制御するIPアドレスごとの許可・不許可も、Nginxのアクセス制限を使うことでIPアドレスごとの制御ができます。
location / {
deny <deny ip address>;
allow <allow ip address>;
deny all;
}
実際には会員専用ページなど、特定の人にしか見せたくないページの設定をする際に便利な機能かと思います。
location /secret-page {
deny all
allow <allow ip address>;
root /var/www/html/secret;
index index.html
}
この場合、許可されているIPアドレス以外からのアクセスでは、403 ForbiddenというHTTPステータスコードが表示されてアクセスができません。
動的なWebアプリをNginxで構築する方法
一つ前のセクションでは静的サイトの構成をご紹介しましたが、ここでは一歩進んで動的なWebアプリケーションの構成を考えてみます。
WebアプリケーションとWebサーバーの接続方法
動的なWebアプリケーションを動作させたい場合には、次のような通信方式によりアプリケーションサーバーと通信させます。
- FastCGI:PHPと連携するときに使用。
- Proxy Pass:Nginxがリバースプロキシとして動作する方法。HTTPリクエストをバックエンドのWebアプリに転送し、レスポンスをクライアントに返す。
- uwsgi:PythonアプリケーションをNginxに接続するためのプロトコル。
例えばDjangoを触り慣れている方であればuwsgiはごく見慣れたプロトコルだと思います。
Webアプリケーションの設定によく使われる機能
Nginxをウェブサーバーとして使用する際、Webアプリケーションの設定によく使われる機能には以下のようなものがあります。
- Location Blocks
Nginxの設定ファイルでは、location ブロックを使用して、特定のURLパターンに基づいてリクエストを処理します。これを使用して、特定のURLパターンに対するリクエストをWebアプリケーションにルーティングします。 - Reverse Proxy Settings
リバースプロキシとしてNginxを使用する際、proxy_pass ディレクティブを使用して、リクエストをバックエンドのWebアプリケーションにルーティングします。 - Load Balancing
複数のバックエンドサーバーがある場合、Nginxはロードバランサーとして機能し、リクエストを複数のサーバー間で均等に分散します。 - SSL/TLS Configuration
NginxはSSL/TLSを使用した安全な接続を提供します。これには、証明書と秘密鍵の設定が必要です。 - HTTP/2 Settings
NginxはHTTP/2をサポートしており、これを有効にすると、より高速なページのロードと優れたパフォーマンスが得られます。 - Caching Settings
Nginxは、バックエンドからのレスポンスをキャッシュして、それを再利用することができます。これにより、バックエンドのロードが軽減され、レスポンス時間が短縮されます。
FlaskアプリとuWSGIの設定方法を解説
具体的な例として、FlaskアプリケーションとuWSGIが通信できるような設定をしてみましょう。
例えば、Flaskアプリの内容を次のようにしたとしましょう。
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "Hello, World!"
これをuWSGIで動かすために、次のようなuWSGI設定ファイルを作成します。
[uwsgi]
module = app:app
master = true
processes = 5
socket = app.sock
chmod-socket = 660
vacuum = true
die-on-term = true
module = app:app
とすることで、app.pyのappオブジェクトをアプリケーションとして使うことを示しています。
この設定ファイルを元にuWSGIを起動するには、次のコマンドを実行します。
uwsgi --ini app.ini
このコマンドを実行することで、app.sockというUNIXソケットが作成されて、uWSGIとFlaskアプリケーションの間の通信ができるようになりました。
続いてNginxの設定です。
server {
listen 80;
server_name example.com;
location / {
include uwsgi_params;
uwsgi_pass unix:/path/to/your/app.sock;
}
}
uwsgi_passディレクティブには、先ほどapp.iniで指定したsocketとして指定したファイルパスを指定します。
最後にNginxにこの設定を有効化するため、シンボリックリンクの作成と再起動をするコマンドを実行します。
sudo ln -s /etc/nginx/sites-available/app /etc/nginx/sites-enabled/
sudo service nginx restart
以上で、Nginxは80ポートで受け取ったHTTPリクエストをUNIXソケットを通じてuWSGIに転送できるようになるはずです。
HTTPSを使ったセキュアな接続
HTTPSは、HTTPの問題点だったセキュリティの脆弱性を改善した通信方法です。
最近ではGoogleがHTTPS対応していないサイトに対して警告を出すなどペナルティを課しているので、最近ではHTTPS対応は必須になってきました。ここでは、このHTTPSをNginxで使うための基礎知識を共有します。
SSL/TLSについて知ろう
SSL(Secure Sockets Layer)と、その後継規格のTLS(Transport Layer Security)は、インターネット上でデータ暗号化して傍受されても大丈夫なように送受信するプロトコルです。
HTTPS(HTTP over SSL/TLS)はこの技術を使っているので、ウェブブラウザとウェブサーバー間の通信は暗号化されます。例えばクレジットカード番号やパスワードなどの機密情報を盗まれることのないよう、HTTPS通信でやり取りされるのが基本です。
証明書の取得方法
サーバー証明書は認証局から取得していくことになります。
これまではサーバー証明書を取得するには費用が必要でしたが、Let’s Encryptなどの認証局を使うことで無料で証明書の発行をしてもらえることもできます。
証明書を取得するには、まずCSR(Certificate Signing Request)というファイルを生成した上で、これを認証局に提出し、証明書を取得する流れとなります。
CSRには「ドメイン名」や「組織名」などが書かれており、このファイルを元に認証局がサイトの正当性を審査することになります。
nginxにサーバー証明書を設定しよう
証明書を取得したら、それをNginxに設定することでHTTPSを有効化します。
server {
listen 443 ssl;
server_name example.com;
# 証明書のパスを指定
ssl_certificate /etc/nginx/ssl/example.com.crt;
# 秘密鍵のパスを指定
ssl_certificate_key /etc/nginx/ssl/example.com.key;
}
上記の方法では/etc/nginx/conf.d/ディレクトリにファイルを格納しているので、sites-availableディレクトリに格納する場合と違ってシンボリックリンクを作成する必要はありません。(conf.dディレクトリはNignxが自動的に読み込むため)
HTTPからHTTPSへの自動リダイレクトをするには、以下を書きます。
server {
listen 80;
server_name example.com;
location / {
return 301 https://$host$request_uri;
}
}
ちなみにLet’s Encryptを使った証明書の取得と設定に関しては、簡単なコマンドの実行で取得が完了するので便利です。
sudo certbot --nginx -d example.com -d www.example.com
--nginx
フラグを使うことでサーバー設定を自動的に行ってくれます。また、サーバー証明書を取得するだけでなく、証明書の自動更新も設定してくれます。
-d
フラグに続けて、証明書を取得するドメイン名を指定してください。
トラブルシューティングとメンテナンス
Nginxではなんらかのタイミングでエラーが発生したり、予期せぬエラーが発生しないようにメンテナンスをする必要があります。
ここではログファイルの役割や調べ方、基本的なメンテナンスについてお伝えしていきます。
Nginxのログファイル
Nginxのログファイルには、アクセスログとエラーログの二つがあります。
アクセスログ
サーバーへの全てのリクエストについて、次のような情報を記録します。
- リクエストしたIPアドレス
- リクエスト日時
- HTTPメソッド
- リクエストURI
- ステータスコード
- ユーザーエージェント
サイト訪問者の行動を分析したり、エラーの原因調査に使います。
エラーログ
次のようなサーバーのエラー情報を記録します。
- 設定エラー
- サーバーの問題
- クライアントからのリクエストに対するエラー
これらのログはデフォルトで/var/log/nginx/
ディレクトリ内に記録されていきます。
メンテナンスの考え方
Nginxの基本的なメンテナンスをまとめると次のようなものがあります。
- 定期的な更新:Nginxのバージョンを定期的に更新します。セキュリティパッチを当てたり、新機能を適用するのが目的です。
- ログのモニタリング:ログを定期的に確認します。エラーなどの異常を発見したら対策を行います。
- パフォーマンスチューニング:Nginxの設定を最適化します。リソース使用量の監視とボトルネックの特定をしましょう。
- バックアップとリストア:重要な設定ファイルは定期的にバックアップをとります。必要な時にはリストアしましょう。
まとめ
以上、Nginxの基本的な知識を一つの記事にまとめてみました。全体のイメージはつきましたでしょうか?
ご覧の通り、Nginxを理解するための鍵は設定ファイルにあります。
簡単なWebサイトからconfファイルの内容を理解しつつ、少しずつ複雑なサイトにも対応できるようになっていきましょう。
冒頭でも紹介しましたが、Nginxの全体像を知る上で『Nginx 実践ガイド』はおすすめです。Kindle Unlimitedなら無料で読めちゃいますので、気になった方はざっとで良いので目を通してみましょう。
コメント