Q:

Nginx holding page without rewriting images

I am trying to set up a holding page for a WordPress site on Nginx. The holding page already existed but the site used to be on an Apache server before we moved it over.
I can get it to redirect to the holding page if maintenance mode is enabled, but the holding.png image does not display. Here is my Nginx code:
server {
        # Set to on to enable holding page
        set $maintenance off;

        if ($maintenance = on) {
                rewrite ^(.*)$ /holding.html break;
        }
}

The holding image is located in the root of the project, just like the holding page HTML file.

A:

First of all, I would make Nginx send a 503 (Service Unavailable) HTTP response code while in maintenance mode. This prevents search engines from indexing your maintenance page while being offline.
Second, I would put all of the static assets for the maintenance page in a separate directory (e.g. maintenance_files) so that they are nicely coupled together and can be easily excluded from the rewrite.
Also, I would want to have a way to exclude some people so that they are able to do their maintenance tasks. This can be done by IP or by checking for a cookie. You could then set/unset the cookie using a piece of javascript that you paste into your browser inspector.
server {
  error_page 503 @maintenance;

  # Set to 1 to enable holding page
  set $maintenance 0;

  # Always allow access for clients that have the 'maintainer' cookie set
  if ($http_cookie ~* "maintainer") {
    set $maintenance 0;
  }

  location / {
    if ($maintenance) {
      return 503;
    }
  }

  location @maintenance {
    # You might want to use a different document root for the maintenance
    # files so you can freely move and shuffle in the default document root
    # during maintenance. 
    #root /var/www/maintenance/;

    if ($uri !~ ^/maintenance_files/) {
      rewrite ^(.*)$ /holding.html break;
    }
  }
}

In order to get maintenance access, paste this in your browser inspector:
document.cookie="maintainer=1";

To remove that cookie:
document.cookie = "maintainer=; expires=Thu, 01 Jan 1970 00:00:00 UTC";

Alternatively, instead of having a variable $maintenance that you set to 1, you could check for a file being present on disk. This way you wouldn't have to reload your Nginx configuration in order to put your site in maintenance mode. However, you would add an addition disk lookup on each request which might be a reason to choose for your option. In that case, run the following command after changing the $maintenance value:
sudo service nginx force-reload 

