I want to disable the access to an app during a certain period of the day.
Is it possible to do something like this in Nginx?
if(hour > '04:00:00' && hour < '05:00:00') {
root /var/www/maintenance;
} else {
root /var/www/site;
}
Server Fault is a question and answer site for system and network administrators. It only takes a minute to sign up.
Sign up to join this communityI want to disable the access to an app during a certain period of the day.
Is it possible to do something like this in Nginx?
if(hour > '04:00:00' && hour < '05:00:00') {
root /var/www/maintenance;
} else {
root /var/www/site;
}
I can only think of 2 ways of doing this (other than the cron changing the symlink):
1) http://nginx.org/en/docs/http/ngx_http_ssi_module.html#variables
2) Create a very small PHP/Python/Whatever app that returns 200 if not maintenance hours and 403 otherwise. Use the http auth module. http://nginx.org/en/docs/http/ngx_http_auth_request_module.html
Just create a bash script to update a file and set it as a cronjob, e.g:
#!/usr/bin/env bash
SiteStatus="$1"
SiteStatusConfig="/etc/nginx/status.conf"
if [ "$SiteStatus" = "maintenance" ]; then
echo "root /var/www/maintenance;" > $SiteStatusConfig
else
echo "root /var/www/site;" > $SiteStatusConfig
fi
nginx -s reload
Then just place into your nginx site config (replacing root directive):
include status.conf;
Then the cronjob:
0 4 * * * /opt/scripts/nginx-site-script.sh maintenance
0 5 * * * /opt/scripts/nginx-site-script.sh
Trying to do this in nginx, via an if statement and the like can slow nginx down as nginx evaluates the server block (stored in memory) with each request.
The approach I typically use for this is to include a downtime handler whenever I first enable an app in nginx. Here's example config:
location /app_1/ {
proxy_pass http://127.0.0.1:8001/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
error_page 502 =200 /502-app_1-maintenance.html;
}
location /502-app_1-maintenance.html {
root /var/www/html/error;
try_files $uri /502-app_1-maintenance.html;
}
Whenever nginx cannot connect to app_1 on port 8001, it produces a 502 error. That error is redirected via error_page 502 =200 /502-app_1-maintenance.html;
to a custom page in the second location block that contains a simple "App 1 Under Maintenance" message. Visitors will get this custom "Under Maintenance" page any time app_1 is down. That seamlessly handles unscheduled as well as scheduled downtimes.
In this example, the response code to the user for this maintenance page is a 200 (OK), however, you can change that to an error response if you prefer by changing =200
to the return code of your choice.
You can also add a bit of javascript to have the page reload periodically. Since the url of the maintenance page is the same as the app's url, when app_1 comes back online, it will replace the maintenance page on the next auto-reload.
In your case, since you want to disable public access during certain times, you could combine this nginx configuration with a scheduled app shutdown via crontab. If you wanted, you could then bring your app up on a different port while you perform maintenance. As long as it's not listening on its usual port, visitors will see the Under Maintenance page.