目次
「root html」の実際のパスの調べ方
参考にした記事
実際に調べてみた
「root html」の実際のパスの調べ方
結論
- 「root html」は、
--prefixの値からの相対パスである。変更されていなければ、デフォルト値は/usr/local/nginx。その場合、「root html」の実際のパスは/usr/local/nginx/htmlとなる。--prefixの値はnginx -Vで確認できる。nginx -Vはコンパイル時のオプションを表示する -
--prefixの値は、nginxのインストール方法やディストリビューションによって異なるものが設定されている - 「root html」は、
rootディレクティブのデフォルト値
参考にした記事
この記事に全てが書いてあります。
root htmldefines the relative path, relative to the value of--prefixin Nginx configuration. In your case, the value of--prefixis/usr/share/nginx. So,root htmlmeans, the directory named "html" inside/usr/share/nginxis parsed to serve the requested file (50x.html). In the end, the request will look for the file at/usr/share/nginx/html/50x.html.root htmlis also the default value when no root is defined in a Nginx configuration.
- (訳)
root htmlは、Nginxの設定において--prefixの値からの相対パスを定義する。 あなたのケースでは、--prefixの値は/usr/share/nginx。なので、root htmlは/usr/share/nginxにある"html"という名のディレクトリを解析して、リクエストされたファイル(50x.html)を提供することを意味する。最終的にそのリクエストは、/usr/share/nginx/html/50x.htmlのファイルを探す。root htmlは、nginxの設定の中でrootディレクティブが定義されていない場合のデフォルト値でもある。
より詳しい情報として、以下の2つの記事を紹介しています。1つ目は、--prefixについての説明です。
--prefix=path
defines a directory that will keep server files. This same directory will also be used for all relative paths set by configure (except for paths to libraries sources) and in the nginx.conf configuration file. It is set to the/usr/local/nginxdirectory by default.
- (訳)
サーバファイルを保存するディレクトリを定義する。同名のディレクトリは、nginx.conf設定ファイルで設定された全ての相対パスにも使用される(ライブラリソースへのパスは除く)。デフォルトで/usr/local/nginxディレクトリに設定される。
2つ目は、rootディレクティブについての説明です。「root htmlがrootディレクティブのデフォルト値であること」が分かります。
以下の記事でも同じようなことが書いてありました。新たに、--prefixの値は「nginxのインストール方法やディストリビューションによって異なる」ことが分かりました。
If your configuration does not include a root /some/absolute/path; statement, or it includes one that uses a relative path like root some/relative/path;, then the resulting path depends on compile-time options. Probably the only case that would allow you to make an educated guess as to what this means for you would be, if you downloaded and compiled the source yourself. In that case, the paths would be relative to whatever
--prefixwas used. If you didn't change it, it defaults to/usr/local/nginx. You can find the parameters nginx was compiled with vianginx -V, it lists--prefixas the first one. Since therootdirective defaults tohtml, this would, of course, result in/usr/local/nginx/htmlbeing the answer to your question. However, if you installed nginx in any other way, all bets are off. Your distribution might use entirely different default paths. Learning to figure out what kind of defaults your distribution of choice uses for things is another task entirely.
- (訳)
設定がroot /some/absolute/path;ステートメントを含んでいないか、root some/relative/path;のような相対パスを使っているステートメントを含む場合、結果のパスはコンパイル時のオプションに依存する。おそらく、これが意味することについて、自分でソースをダウンロードしてコンパイルした場合のみ、経験に基づく推測が可能だろう。その場合、パスは--prefixが使用されたものからの相対パスとなる。もしそれを変更していなければ、デフォルトは/usr/local/nginxになる。nginx -Vを用いて、nginxがコンパイルされたパラメータを見つけることができる。--prefixが最初のものとしてリストされている。rootディレクティブのデフォルトはhtmlなので、/usr/local/nginx/htmlが質問の答えになる。しかし、それ以外の方法でnginxをインストールした場合、すべての賭けは失敗する。あなたのディストリビューションでは、まったく異なるデフォルトパスが使用されているかもしれない。 選択したディストリビューションがどのようなデフォルトを使用しているかを把握するのとは、まったく別の仕事だ。
実際に調べてみた
私はDockerのnginxコンテナを使用しています。以下は設定ファイルの一部です。
server {
listen 80;
listen [::]:80;
server_name localhost;
# 省略
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# 省略
location ~ \.php$ {
root html;
# 省略
}
# 省略
}
ここに「root html」があります。
nginxコンテナの中でnginx -Vを実行したところ、こうなりました。
configure arguments: --prefix=/etc/nginx .....省略
つまり「root html」の実際のパスは/etc/nginx/htmlとなります。
自分の目で確かめてみる
自分の目で確かめたくて、少し実験をしました。設定ファイルを以下のように変更します。
server {
# 省略
location / {
root html;
}
# 省略
}
「root html」の実際のパスは/etc/nginx/htmlであると仮定して、nginxコンテナ内の/etc/nginx/htmlにindex.htmlを置きます。これが正しければ、index.htmlをリクエストした時に表示されるはずです。
詳しい手順は以下です。
①環境を準備する
ホスト側に以下の構造を作ります。
-
default.conf
設定ファイルを変更するには、コンテナ内の設定ファイルをホスト側にコピーし、自分のエディタ(私はVSCode)で編集します。 今回変更するのはdefault.confなので、このファイルをホスト側にコピーします。
.
|____nginx
| |____default.conf <-----ここにコピーする
| |____Dockerfile
|
|____public
|____index.html <-----中身は適当に。これが表示されるかの実験。
これはコンテナが存在している状態でないとできないので、初めての場合はとりあえずコンテナを起動します。初めの方に簡単なセットアップが書かれています。適宜書き換えて実行します。
↓
docker run --name nginx-container -v ./public:/usr/share/nginx/html:ro -d nginx:1.25
・docker hubの「nginx:1.25」イメージを使用します。
index.htmlも適当に作成します。
②設定ファイルを変更する
コンテナが起動できたので、コンテナ内のdefault.confをホスト側にコピーします。
- コンテナの外で
docker cp nginx-container:/etc/nginx/conf.d/default.conf ./nginx/default.confを実行。
構文はdocker cp コンテナ名またはコンテナID:コピー元のパス コピー先のパスです。
コピーされるので、default.confを変更します。
server {
# 省略
location / {
root html;
}
# 省略
}
③コンテナ内に/etc/nginx/html/index.htmlを用意する
「root html」の実際のパスは/etc/nginx/htmlと仮定しています。しかし、デフォルトのnginxコンテナには、この htmlディレクトリが存在しません(コンテナの中に入って確かめることができます。コンテナに入るにはdocker exec -it nginx-container /bin/bashを実行)。
nginxコンテナの/etc/nginxにあるのは、以下のディレクトリとファイルです。
/etc/nginx ls
conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
このままでは実験ができないので、あらかじめDockerfileでhtmlディレクトリを作成します。
- Dockerfile
FROM nginx:1.25
RUN mkdir -p /etc/nginx/html
Dockerfileはイメージの設計書みたいなものです。Dockerifleを基にイメージを作成し、そのイメージを基にコンテナが作成されます。
index.htmlは適当に作成しておきます。このファイルをhtmlディレクトリに置くには、コンテナ起動時にバインドマウントすることで実現できます(次で説明)。
④新しい内容でコンテナを起動し直す
今nginxコンテナを起動しているのは、「コンテナ内の設定ファイルをホスト側にコピーしたかったから」というだけです。公式のnginxイメージ「nginx:1.25」をそのまま使いました。しかし、ここまでで、コンテナ内に新たなディレクトリを作ったり、設定ファイルを変更したので、新しい内容が反映されたコンテナを使いたいです。
-
docker stop nginx-containerで現在のコンテナ停止 -
docker rm nginx-containerで現在のコンテナ削除 - 自作のDockerfileからイメージを作成
docker build -t nginx-image ./nginxを実行。
・-t イメージ名:タグ名でイメージ名をつける。タグ名を指定しなければ、自動でlatestがつく。
・./nginxはDockerfileのあるディレクトリ。 - イメージからコンテナを起動
docker run --name new-nginx-container -v ./public:/etc/nginx/html -v ./nginx/default.conf:/etc/nginx/conf.d/default.conf -d -p 8080:80 nginx-imageを実行。
長いコマンドですが、これがとても便利です。
このコマンドは、新しいコンテナの名前をnew-nginx-containerとし、2つのバインドマウント(-v)と、8080番でアクセスできるようにしています。イメージは自作した「nginx-image」を使います。コマンド実行後の状態↓↓
ホスト側 コンテナ側
. :
|____nginx |__etc
| | | |__nginx
| | : |__conf.d
| ***|************************************************|**********************
| * |___default.conf バインドマウント |___default.conf *
| ***************************************************************************
| |___Dockerfile :
| |
|____public *************************************** |__html *******************
* |____index.html バインドマウント |____index.html *
* *
***************************************************************************
-
default.conf・・・ファイル同士のバインドマウント -
index.html・・・ディレクトリ同士のバインドマウント
バインドマウントは、ファイル単位でもディレクトリ単位でもできます。
バインドマウントは、ホスト側にあるファイルをコンテナ側に「見せる」。ホスト側の内容を「被せる」イメージです。まるでコピーしたように見えます。
ディレクトリ単位の場合、コンテナ側に既存のファイルがあっても、ホスト側とまるっきり同じ内容になります。なのでファイルが消えたように思うのですが、消えておらずマウントを解除すると元に戻ります。
ファイルの変更をリアルタイムで反映するバインドマウント
バインドマウントをしなければ、新たにファイルの内容を変更しても反映されません。反映させるには、そのファイルをコンテナ側にコピーするか、イメージのビルドからし直す必要があり、逐一手間がかかります。ただのタイプミスでもこれをしないといけません。
ファイルの内容を変更したらリアルタイムで反映されたら便利です。そこでバインドマウントをしました。これで、index.htmlと設定ファイルdefault.confを自由に変更できます。
忘れずに
default.confを変更したら、コンテナ内でnginx -s reloadを実行し、設定ファイルをリロードします。
⑤index.htmlにアクセスする
ブラウザから、http://localhost:8080/index.htmlでアクセス(リクエストを送信)します。「root html」が/etc/nginx/htmlと解釈されるならば、私のリクエストは/etc/nginx/html/index.htmlとなり、そこに用意してあるindex.htmlが返ってくるはずです。
作成したファイルが表示され、意図した結果になりました。つまり、
「root html」は--prefix=/etc/nginxからの相対パスです。
※/etc/nginxは設定ファイルが入っている場所なので、その中にドキュメントルートがあるのは適切でないと思います。絶対パスを使った方がいいと思いました。