Nginx浅く理解するために触ってみた。(静的サイトの構築まで)

この記事はPlanning-Vunue アドベントカレンダー内の記事となります。

Plannning-Venue Advent Calendar 2021 - Adventar

前の記事はこちら


普段なんとなく触って構築しているNginxですが、浅く理解してその都度調べるみたいな感じだったので、ファイルの構造やよく使いそうな所をこれを機にまとめようと思いました。

抽象的で分かりやすく使わせてくれるNginxですが、しっかり調べていくと奥が深すぎる・・・ しっかり時間とって色々な機能を触っていきたいですね。


最近サーバーを増やしたので、色々ブログのネタになりそう。(今までは買っても記事に上げず、Twitterくらいだった・・・)

内蔵RAIDカードの認識や仕様でかなり時間とられたのでそこら辺も書いてESXiとりあえず入れようと思います。




次は構築編の予定(やる気があれば)


環境(今回はVMに建てました。)

  • Virtualbox 6.1.14(Windows10)
  • OS: Ubuntu Server20.04 LTS
  • vCPU:2
  • RAM:4GB
  • HDD:30GB

Nginxのおおまかな特徴

  • 静的コンテンツのWebサーバー
  • 動的コンテンツのWebサーバー
  • ロードバランサー・・・負荷分散
  • リバースプロキシー・・・クライアントからのWebアクセスを別のWebサーバーに転送。

など・・・


インストール(本当は色々な手順があるけど今回は楽に構築したかったので以下で済ました。)

sudo apt update
sudo apt install nginx


インストールできたかの確認

sudo systemctl status nginx



shirokus@shirokus:/etc$ sudo systemctl status nginx
 nginx.service - A high performance web server and a reverse proxy server
     Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
     Active: active (running) since Wed 2021-12-08 02:19:21 UTC; 42min ago
       Docs: man:nginx(8)
   Main PID: 769 (nginx)
      Tasks: 3 (limit: 4653)
     Memory: 11.5M
     CGroup: /system.slice/nginx.service
             ├─769 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
             ├─770 nginx: worker process
             └─771 nginx: worker process

Dec 08 02:19:21 shirokus systemd[1]: Starting A high performance web server and a reverse proxy server...
Dec 08 02:19:21 shirokus systemd[1]: Started A high performance web server and a reverse proxy server.


active(緑)だったら大丈夫。

心配だったら

curl localhost #VMにsshして繋いでたらlocalhost 'VMのIPアドレス'



起動・自動起動・停止

sudo systemctl start nginx #起動 
sudo systemctk enable nginx #自動起動
sudo systemctl stop enbale #停止


ファイアーウォールの設定(VM内の検証ならしなくていいかも。)

今回はufwを使用。Ubuntu20だとデフォルトで入ってたので、activeにするだけだった。

sudo ufw status#確認(今回はinactiveだったので有効化する)
sudo ufw enable #有効化


ufwの確認

shirokus@shirokus:/etc$ sudo ufw app list
Available applications:
  Nginx Full
  Nginx HTTP
  Nginx HTTPS
  OpenSSH



このVMは、作ってからopenssh-serverとnginxしか入れていないので、以下の構成になる。

Nginx Full -> ポート80と443を開く

Nginx HTTP -> 80のみ

Nginx HTTPS -> 443のみ


今回は検証環境内だけの予定だが、とりあえずHTTPSの検証も今後していきたいので、Nginx Fullにした。

※ufwをアクティブにするとsshなどで繋いでる場合はそのポリシーも書かなくてはいけない。今回はsshとnginxのみなのでufw allow 22 と ufw allow 'Nginx Full'を許可するように設定。

shirokus@shirokus:/etc$ sudo ufw status
Status: active

To                         Action      From
--                         ------      ----
22                         ALLOW       Anywhere
Nginx Full                 ALLOW       Anywhere
22 (v6)                    ALLOW       Anywhere (v6)
Nginx Full (v6)            ALLOW       Anywhere (v6)


ここで、nginxの内部構造を調べてみる。

shirokus@shirokus:~$ ps ax | grep nginx
    769 ?        Ss     0:00 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
    770 ?        S      0:00 nginx: worker process
    771 ?        S      0:00 nginx: worker process
   2498 pts/0    S+     0:00 grep --color=auto nginx


nginxを起動すると、二種類のプロセスが動いており、psコマンドで確認すると"nginx: mastre process"と"nginx: worker process"が存在している。

大まかな解釈をすると

mastre(root) ->設定ファイルを読み込み、ネットワークの通信に使うソケットの待ち受けを想定して、wokerを起動・監視する


worker (一般ユーザー)->ネットワーク処理のイベントループを処理し、masterが待ち受けを設定したソケットを使って接続を受け付ける。ネットワークやファイルIOの実施やHTTP, SSL/TLSのプロトコル処理も担う。


また、nginxは内部で機能ごとのモジュールに分かれており、コンパイル時のフラグによってモジュールを組み込むかどうかを指定できる。


nginxのログファイルの場所(中身を見たい場合はviかcatで見る。)

アクセスログ -> 

/var/log/nginx/access.log

エラーログ ->

/var/log/nginx/error.log


ディレクティブとコンテキスト

nginxは設定ファイルで指定されたディレクティブによって制御されるモジュールからできている。


ディレクティブ(種類)

|-> シンプルディレクティブ・・・ 名前とパラメータが空白で分けられ、セミコロン(;)で終わる

->ブロックディレクティブ・・・ 基本的には、シンプルディレクティブと同じ構造。セミコロンの代わりに大括弧({ })で囲まれている。


ブロックディレクティブが大括弧内に他のディレクティブを持つことができる場合はコンテキスト(events, http, server, locationなど)

最も外側のコンテキストをmainコンテキスト。ディレクティブによって作成されたコンテキストは、コンテキストを作成したディレクティブの名前を付けて<ディレクティブ>コンテキスト。

httpというディレクティブは、Webサーバーの設定を記述するためのコンテキストを作成するが、httpディレクティブによって作成されたコンテキストを"httpコンテキストと呼ぶ"。


静的なWebサイトの構築

Webサイトをnginxで構築する例

Jekyllなどを使えば、静的サイトの生成もできるらしい。


構成としてはhttpコンテキストの中でincludeによって読み込まれる想定でserverディレクティブを書く。serverディレクティブを書いた設定ファイルを/etc/nginx/conf.d以下に配置すると設定が読み込まれるようになる。


まずは初期状態のnginx.confを見てみよう。(場所は/etc/nginx/nginx.conf)

※解説したいとこだけ抜粋してます。本当はもっとある。

shirokus@shirokus:~$ cat /etc/nginx/nginx.conf
user www-data; #ユーザー名
worker_processes auto; #workerプロセス名。autoだとコア数と同等の数を起動。
pid /run/nginx.pid; #プロセスPID
include /etc/nginx/modules-enabled/*.conf;

events { #コンテキスト
        worker_connections 768; #1つのworker往路セスが同時に受け付けられる接続数。クライアントの数だけではない。
        # multi_accept on;
}

http { #コンテキスト

        ##
        # Basic Settings
        ##

        sendfile on;
        tcp_nopush on;
        tcp_nodelay on;
        keepalive_timeout 65;
        types_hash_max_size 2048;
        # server_tokens off;

        # server_names_hash_bucket_size 64;
        # server_name_in_redirect off;

        include /etc/nginx/mime.types;
        default_type application/octet-stream;

        # Logging Settings
        access_log /var/log/nginx/access.log; #ログの保存場所
        error_log /var/log/nginx/error.log; #ログの保存場所


        include /etc/nginx/conf.d/*.conf; 
        include /etc/nginx/sites-enabled/*;
}


httpコンテキストには、Webサーバー全体の設定を記述する。httpコンテキストの中でバーチャルホストを記述するserverコンテキストやserverコンテキストの中で、URLのパスごとの動作を記述する、locationコンテキストにも書ける。

httpコンテキストには、バーチャルホストに共通の設定を書く。複数のバーチャルホストを構築するときでも、バーチャルホスト毎の設定が最小限に済む。

※バーチャルホスト・・・1つのサーバーで複数のドメインを運用すること。Webやメールサーバーなど


テストサイトの作成

sudo vi /etc/nginx/sites-available/example.com
server {
  listen 80;
  server_name example.com;
  root /var/www;
  index index.html;
}

を書き込み、etc+wq! を押して保存する。


/etc/nginx/nginx.confではなく、/etc/nginx/sites-available にドメインやサイトの設定を書いた理由は、ドメインごとにconfigを分けられるから。1つのNginxに対して1つのサイトしか運用しないのであれば、nginx.confでも良いのですが、バーチャルホスト運用をする場合が多いので、特定のドメインだけ削除したい & ドメインごとに設定を管理したいときは /etc/nginx/sites-available と /etc/nginx/sites-enabledを使います。

(あとnginx.confに書くと長くなるし見にくい・・・ なので個人的にはサイトごと(ドメイン)にsites-availableに書いたほうが楽である。)

ディレクトリの作成

sudo mkdir -p /www/dir
sudo vi /www/dir/index.html
<!DOCTYPE html>
<html>
        <head>
        <meta charset = "utf-8">
        <title> Test Site</title>
        </head>

        <body>
        <h1>Hello nginx</h1>
        </body>
</html>

保存したら、以下のコマンドを実行。

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo systemctl restart nginx


Welcome to Nginx!から自分の書いたhtmlが表示されればOK!



次は、Reactや静的サイトジェネレータを使って簡易なブログ構築やCGI,Proxy辺りを詳しく触っていきたいと思う。

参考にさせていただいた文献