Nginx勉強用スクラップ

はじめに
業務ではk8sを使用しているが、最近Nginxで静的コンテンツを表示することが多く、
なんとなくで使用していたNginxを本格的にものにしてみたくなった。
Udemyで海外講義を見たりしたが、なかなか英語が入ってこないので、
Kindleで0円だったnginxプロキシ構築完全マスター で基本から勉強してみたいと思う。
Dockerfileの作成
手元のNginx設定は汚したくないのでDockerでNginxを起動しようと思う。
設定ファイルもローカルから見れるようにしていじれるようにしたいので、
リポジトリ内で下記コマンド実行。
docker cp sample-container:/etc/nginx ./nginx-config
FROM nginx:latest as production
# 設定ファイルもCOPYする
COPY ./nginx-config /etc/nginx
COPY ./pages /var/www/html
EXPOSE 3333
ポートを3333にしているので、
default.confのserver設定を修正。
server {
# これはDockerで起動しているポートを指定
listen 3333;
listen [::]:3333;
dockerコマンドを毎回打ち込むのは面倒なので、
よく使いそうなコマンドをMakefileに記載。
restart:
docker rm -f sample-container && docker build -t sample-container . && docker run -d --name sample-container -p 3333:3333 sample-container
container:
docker exec -it sample-container /bin/bash
ps:
docker ps
down:
docker rm -f sample-container
logs:
docker logs sample-container
起動
make restart
これで無事にhttp://localhost:3333
でデフォルトのNginx画面が表示。

現在のディレクトリ構造が下記のような感じ。
tree
.
├── Dockerfile
├── Makefile
├── nginx-config
│ ├── conf.d
│ │ └── default.conf
│ ├── fastcgi_params
│ ├── mime.types
│ ├── modules -> /usr/lib/nginx/modules
│ ├── nginx.conf
│ ├── scgi_params
│ └── uwsgi_params
└── pages
├── index.html
└── test-page
└── sample
└── index.html
aliasとrootの違い
default.conf
# リクエストで/testから始まる時のもの
location /test {
# 表示したいindex.htmlは/var/www/htmlの直下に存在する
# この場合rootにするとtestディレクトリを探すので、ディレクトリがない場合はaliasでパスを指定する
# aliasはディレクトリ自体を指定する
alias /var/www/html;
index index.html;
}
# リクエストで/test-pageから始まる時のもの
location /test-page {
# この場合/special配下のディレクトリ内のindex.htmlを探す
# rootはlocationのパスをrootディレクトリに付加する
root /var/www/html;
index index.html;
}
リクエスト
リクエストパス | 結果 |
---|---|
/test | ①301 /test/最後にスラッシュがついたパスへリダイレクト ②/test/で200 |
/test/ | 200 |
この最後にスラッシュがない場合の挙動を詳しく調べてみる
$ curl -I http://localhost:3333/test
> HTTP/1.1 301 Moved Permanently
Server: nginx/1.27.3
Date: Sat, 01 Feb 2025 11:43:05 GMT
Content-Type: text/html
Content-Length: 169
Location: http://localhost:3333/test/ 👈 ここでスラッシュがついている
Connection: keep-alive
この場合、Location: http://localhost:3333/test/
ここに完全に移動したということか。
これはNginx、ブラウザどっちの挙動なのか??
ChatGPTに聞いてみる。
最後にスラッシュがない場合http://localhost:3333/test/に完全に移動されるがこれを行なっているのは
ブラウザ?それともNginx??
このリダイレクトを行っているのはNginxです。
具体的には、Nginxの設定ファイルにおいて、
ディレクトリパスにスラッシュ(/)がない場合に自動的にリダイレクトを行う設定がされているためです。
Nginxは、リクエストされたURLがディレクトリパスである場合、最後にスラッシュを追加するリダイレクトを自動で行います。
これにより、http://localhost:3333/testがhttp://localhost:3333/test/にリダイレクトされます。
どうしてNginxがこのリダイレクトを行うのか?
HTTP仕様: URLがディレクトリを指している場合、そのディレクトリにはスラッシュが必要であると認識されます。スラッシュがないURLは、リソース(例えばファイル)とディレクトリの間で混乱が生じる可能性があります。
Nginx設定: Nginxの設定で、URLがディレクトリを示している場合に末尾のスラッシュを強制するようにリダイレクトする設定がよく使われます。
どうやらNginxのデフォルトの挙動らしい。
でも、リバースプロキシの場合はこうならない。
静的コンテンツを表示させるときのみで、スラッシュがない場合ディレクトリと認識して最後に/
をつけるらしい。
確かに、この記事のURLhttps://zenn.dev/zaki_dev/scraps/0a0cf676d4f690
で読み込んで、
ネットワークタブを見ても最後に/
はついていない。
ちなみに最後についているスラッシュのことをトレイングスラッシュ
というらしい。
なんだか頭が追いつかないので、
Nginxでトレイリングスラッシュとファイル拡張子を削除する秘伝わざをちょっと熟読してみる。
うーん。。。
301でトレイングスラッシュのパスにリダイレクトして200になるのが正しい挙動だが、
本番環境で、307 Internal Redirect (from disk cache) でLocationはトレイングスラッシュ付きのパスだが、
Request URLがhttpとhttpsから始まるリクエストがある。
うーん。。。
こんがらがってくる。
最終的には200になるので画面上は正常に表示される。
なぜ、httpとhttpsのそれぞれからリクエストを飛ばすのか??
トレイリングスラッシュの件は別のスクラップに移します。