Planned outages should replace application errors with a small response that still works when the application is unavailable. A static maintenance document served directly by Nginx gives visitors a clear message while the affected URLs report a temporary server condition.
An Nginx marker-file check runs for each request, so creating the file turns maintenance mode on without another reload. A named error location serves the document with 503 Service Temporarily Unavailable and Retry-After, while the URI map keeps robots.txt on its existing route.
Use a site-wide 503 response only for a short outage window. Search crawlers may reduce or stop crawling when the response remains in place for more than roughly 1-2 days, and deleting the marker file restores the existing application routes immediately.
Related: How to plan a website redesign
$ sudo nginx -T
This command prints the complete loaded configuration and may expose inline credentials or private upstream addresses, so review its output locally.
$ sudo install --directory --owner=root --group=root --mode=0755 /var/www/maintenance
$ sudoedit /var/www/maintenance/maintenance.html
<!doctype html> <html lang="en"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Scheduled maintenance</title> <h1>Scheduled maintenance</h1> <p>The website is temporarily unavailable.</p> <p>Check https://status.example.com for updates.</p> </html>
The document remains independent of application templates, external stylesheets, and scripts that may be unavailable during the outage.
$ sudoedit /etc/nginx/conf.d/maintenance-map.conf
map $uri $maintenance_marker { default /etc/nginx/maintenance.enabled; /maintenance.html ""; /robots.txt ""; }
Another exact URI can use an empty value when an essential status or administration route must remain reachable.
$ sudoedit /etc/nginx/sites-available/example.com
error_page 503 @maintenance; if (-f $maintenance_marker) { return 503; } location @maintenance { root /var/www/maintenance; rewrite ^ /maintenance.html break; add_header Retry-After 3600 always; } location = /maintenance.html { internal; }
The example.com file in /etc/nginx/sites-available represents the active server block identified earlier. The internal location prevents the standalone file from becoming a normal public URL.
$ sudo nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Related: How to test Nginx configuration
$ sudo nginx -s reload
On systemd-managed hosts, the packaged service manager provides the equivalent reload path.
Related: How to manage the Nginx service
$ sudo touch /etc/nginx/maintenance.enabled
This marker makes every non-exempt route return the maintenance response. Removing the marker restores the existing routes without another reload.
$ curl --include --silent --show-error https://www.example.com/robots.txt HTTP/1.1 200 OK ##### snipped ##### Content-Type: text/plain Content-Length: 24 ##### snipped ##### User-agent: * Disallow:
$ curl --include --silent --show-error https://www.example.com/ HTTP/1.1 503 Service Temporarily Unavailable ##### snipped ##### Content-Type: text/html Content-Length: 301 ##### snipped ##### Retry-After: 3600 <!doctype html> <html lang="en"> ##### snipped ##### <title>Scheduled maintenance</title> <h1>Scheduled maintenance</h1> <p>The website is temporarily unavailable.</p> ##### snipped #####
Tool: HTTP Header Checker