Nginxで特定の時間(01:00-02:00など)にメンテナンスページを表示して、ユーザーのシステム利用を制限する方法を解説します。
環境ですが、OSはRed Hat EnterPrise Linux 10を利用し、nginxはDockerで構築しています。詳細な環境情報は以下の記事を参照してください。
メンテナンスページを表示する方法としてぱっと思いついたのは次の2つの方法ですが、今回は追加のソフトウェアインストールなどが不要なcronを利用した方法を解説します。
1.LUAモジュールを利用し、nginx.conf内で時間判定してメンテナンスページにリダイレクトする
2.cronを利用し、メンテナンスページコンテンツの有無でリダイレクトする
事前準備:タイムゾーンの設定
指定時間の判定を行うため、タイムゾーンは日本時間(JST)にしておく必要があります。
OSのタイムゾーンを確認します。以下のようにJSTとなっていれば問題ありません。
date
2025年 6月 13日 金曜日 01:33:42 JST
JSTでなかった場合は、以下のコマンドでJSTに設定します。
sudo timedatectl set-timezone Asia/Tokyo
次にnginxのコンテナのタイムゾーンをdocker-compose.ymlで設定します。environmentにTZ環境変数を”Asia/Tokyo”で追加します。
nginx:
container_name: nginx
image: docker.io/library/nginx:1.25.1-alpine
depends_on:
- pleasanter
network_mode: "host"
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
#タイムゾーンの設定
environment:
- TZ=Asia/Tokyo
コンテナを再起動し、nginxコンテナに接続し、同じようにdateコマンドでタイムゾーンを確認します。
podman-compose down
podman-compose up -d
podman exec -it nginx /bin/sh
cronを利用した時間指定のメンテナンスページ表示
メンテナンスページの準備
Dockerコンテナを稼働させているサーバー上にメンテナンスページのコンテンツを作成します。まずはコンテンツ格納用ディレクトリをdocker-compose.ymlと同じ場所に作成し、その中でコンテンツを作成します。
cd /opt/pleasanter
sudo mkdir ./html
touch ./html/maintenance.html
sudo chown -R pleasanter:pleasanter ./html
上記で作成したメンテナンスページのコンテンツを、Dockerコンテナで参照できるようにdocker-compose.ymlを編集し、ホストマシンのディレクトリをコンテナにマウントします。volumesに「./html:/var/www/html:ro」を追加し、ホストマシンの「./html」がコンテナの「/var/www/html」にマウントされるようにします。
nginx:
container_name: nginx
image: docker.io/library/nginx:1.25.1-alpine
depends_on:
- pleasanter
network_mode: "host"
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
- ./html:/var/www/html:ro
environment:
- TZ=Asia/Tokyo
コンテナを再起動し、マウントされていることを確認します。
podman-compose down
podman-compose up -d
podman exec -it nginx /bin/sh
ls /var/www/html/
適当なメンテナンスページを作成します。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>メンテナンスのお知らせ</title>
</head>
<body>
<h1>メンテナンス中</h1>
<p>毎日01:00~05:00の間はメンテナンス時間のためシステムはご利用いただけません。</p>
</body>
</html>
nginx設定ファイルにメンテナンスページの表示条件を追加
nginx設定ファイル(/opt/pleasanter/nginx.conf)にメンテナンスページが存在する場合、全てのリクエストをメンテナンスページへ誘導する設定を追加します。
try_files ディレクティブは、リクエストされたパスに対して、指定した複数のファイルやディレクトリを順番にチェックし、最初に存在したものを返します。ですので
「try_files /maintenance.html $uri @app;」の動きは以下のようになります。
1.最初に”maintenance.html”の存在をチェックし、存在すればそのまま返却
2.”maintenance.html”が存在しない場合は、リクエストされたURI($uri)を @appへ引き継ぎます
@appは「名前付きロケーションブロック」で 「location @app」で処理を行うことを意味します。ここでは通常のリクエスト処理を意味します。
server {
listen 80;
server_name <サーバーのIPアドレス or ホスト名>;
root /var/www/html;
location / {
try_files /maintenance.html $uri @app;
}
location @app {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location = /maintenance.html {
default_type text/html;
try_files /maintenance.html = 404;
}
}
コンテナに入り、設定ファイルの内容をテストします。
podman exec -it nginx /bin/sh
nginx -t
問題なければ以下のような表示がでます。
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
コンテナを再起動し、メンテナンスページが表示されるか確認しましょう。現時点ではメンテナンスページが存在するので常に表示されると思います。また、手動でメンテナンスページのファイル名をリネームし、リネームした場合は通常の画面が表示されることを確認しましょう。
ここまでくれば、あとはcronの設定をするだけです!
podman-compose down
podman-compose up -d
cronの設定
「/var/www/html/maintenance.html」が存在する場合は、このメンテナンスページに遷移するようnginx側の設定が出来ました。あとはcronで指定した時間にリネームをすることで任意の時間にメンテナンスページを表示することが出来ます。
「/opt/pleasanter/sh」フォルダを作成し、その中にメンテナンス開始時間にリネームするシェル「maintenance_start.sh」を用意します。
mv /opt/pleasanter/html/maintenance_bk.html /opt/pleasanter/html/maintenance.html
同じようにメンテナンス終了時間にリネームするシェル「maintenance_stop.sh」を用意します。
mv /opt/pleasanter/html/maintenance.html /opt/pleasanter/html/maintenance_bk.html
シェルのログを出力するフォルダも作成しておきます。
sudo dir -p /opt/pleasanter/log
sudo chown pleasanter:pleasanter /opt/pleasanter/log
作成したシェルを手動で実行し、メンテナンス画面への切り替わりが正しく行われることを確認しましょう。
作成したシェルをcronに登録します。今回は「pleasanter」ユーザーのcronに登録します。以下のコマンドでcron編集画面を表示します。
sudo crontab -u pleasanter -e
毎日01:00にメンテナンス画面を表示し、02:00にメンテナンス画面の表示を終了したい場合は以下のような内容でcron登録します。cronの登録方法は他のサイトで多くの情報がありますので割愛します。
0 1 * * * /opt/pleasanter/sh/maintenance_start.sh >> /opt/pleasanter/log/maintenance_start.log 2>&1
0 2 * * * /opt/pleasanter/sh/maintenance_stop.sh >> /opt/pleasanter/log/maintenance_stop.log 2>&1
以上