NGINXで発生した404エラー時にアプリ側のエラー画面を表示させる
更新日: 2022/10/28
概要
NGINX 側で静的ファイルを見せていた場合、静的ファイルが見当たらなかった場合 NGINX 側で404エラーを出すことになる。これをリバースプロキシしているアプリ側が作成する404ページに置き換えたい。
結論だけで良い方はこちらへ。
試してみる
気になったときは Docker を使って検証。
通常の404ページを表示してみる
docker コンテナ起動
docker run --name test_nginx -d -p 8999:80 nginx
http://localhost:8999 でデフォルトの画面が見えることを確認。
docker の中に入る
docker exec -it test_nginx
編集したいので vim を入れる
apt update
apt install vim
デフォルトの設定を確認
vim /etc/nginx/conf.d/default.conf
# default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
...
404ページを表示できるように設定を変更
(ついでにスペースもこんなにいらないので消した)
vim /etc/nginx/conf.d/default.conf
...
#error_page 404 /404.html;
error_page 404 /404.html;
...
404.html ファイルを作成
※ 検証のためだけなのでHTMLの書き方も無視します。
echo "test 404 page!" > /usr/share/nginx/html/404.html
設定を読み込ませるためにリロード
リロードする前に http://localhost:8998/aaaa にアクセス。
するとデフォルトの以下のような画面が出る。

ここでリロードして
service nginx reload
再度同じように実行してみると、test 404 page!
とかかれた独自のエラーページが見えることがわかる。
アプリのURLを指定する
簡単なアプリを作る(Flask)
どこかローカル環境で python の仮想環境を作る。
python3 -m venv venv
source venv/bin/activate
flask のチュートリアルをもじって404の内容を示すページを作成。
# error.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
@app.route("/error/404")
def error_404():
return "<p>404 error from flask</p>"
実行する
flask --app error run -p 5555
http://localhost:5555/と http://localhost:5555/error/404にそれぞれ表示したい文字が出ることが確認できる。
NGINX と組み合わせる
vim /etc/nginx/conf.d/default.conf
...
#error_page 404 /404.html;
error_page 404 http://$host:5555/error/404;
...
NGINX をリロード
service nginx reload
すると、http://localhost:8998/aaaa にアクセスすると、http://localhost:5555/error/404 にリダイレクトされていることがわかります。
結論
error_page
の構文でアプリ側のURLを指定するとリダイレクトされる。他のエラーも同様に可能です。
error_page 404 <URL>
参考
error_page - NGINX
Handling Errors - NGINX
終わりに
共通化することで、アプリ側で生成する404ページはリニューアルしたのに、 NGINX で表示している静的なファイルとして作成した404ページの更新忘れたということは無くせるはずです。