Last week we published a blog about Creating NGINX Rewrite Rules. In this complementary blog, we’ll discuss how to convert Apache HTTP server rewrite rules to NGINX Plus syntax (the conversions are the same for NGINX Open Source). You need to convert to NGINX rewrite rules when you place NGINX Plus in front of your Apache servers to take over as the reverse proxy or load balancer, or when you replace Apache web servers with NGINX Plus web servers. Keep in mind that NGINX and NGINX Plus do not support per‑directory configuration files (Apache’s .htaccess files), so you need to convert them in particular.

We’ll assume you’re familiar with Apache rewrite rules and with how NGINX Plus processes URLs. For a review of the return, rewrite, and try_files directives in NGINX Plus and NGINX, see Creating NGINX Rewrite Rules.

Converting a Rule that Adds the www Prefix

This Apache rule adds the www prefix to the URL:

RewriteCond %{HTTP_HOST} RewriteRule (.*)$1

The following NGINX Plus configuration is the correct conversion. The first server block matches requests to and redirects them permanently to The second server block matches the rewritten URL (and all other requests to

# USE THIS CONVERSION server { listen 80; server_name; return 301$request_uri; } server { listen 80; server_name; # ... }

The following might seem like a natural way to convert the Apache rule to an NGINX rewrite rule, but we don’t recommend it. Compared to the recommended conversion, it requires two extra processing stages: NGINX Plus must first check the if condition, and then evaluate the regular expression in the rewrite directive (simple as it is).

# NOT RECOMMENDED server { listen 80; server_name; if ($http_host = { rewrite (.*)$1; } # ... }

Converting an “Is Not” Rule

This Apache rule matches URLs that are “not and not” (you could call this “upside‑down” logic) and rewrites them to

RewriteCond %{HTTP_HOST} ! RewriteCond %{HTTP_HOST} ! RewriteRule (.*)$1

For the NGINX Plus conversion, we explicitly define a server block that combines the “positive” versions of the Apache RewriteCond directives (that is, it matches URLs that start with or, and another server block that matches what is now better characterized as “everything else.” For an explanation of how the second server block works, see “Redirecting All Traffic to the Correct Domain Name” in Creating NGINX Rewrite Rules.

server { listen 80; server_name; # ... } server { listen 80 default_server; server_name _; return 301$request_uri; } distributes a basic default .htaccess file with the following Apache directives that enable pretty permalinks:

<IfModule mod_rewrite.c> RewriteEngine On RewriteBase / RewriteRule ^index.php$ - [L] RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.php [L] </IfModule>

Here’s the NGINX Plus equivalent:

location / { try_files $uri $uri/ /index.php?$args; }

For more information about enabling pretty permalinks for WordPress with NGINX, see WordPress permalinks at

Converting Rules that Forward Dynamic Requests to an App Server

Administrators often use Apache rewrite rules like the following to serve static assets directly if they exist and forward dynamic requests to an application server.

DocumentRoot /var/www/ RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteRule ^.*$ %{DOCUMENT_ROOT}/system/maintenance.html [L] RewriteCond %{REQUEST_FILENAME} -f RewriteRule ^(.*)$ $1 [QSA,L] RewriteCond %{REQUEST_FILENAME}/index.html -f RewriteRule ^(.*)$ $1/index.html [QSA,L] RewriteCond %{REQUEST_FILENAME}.html -f RewriteRule ^(.*)$ $1.html [QSA,L] RewriteRule ^/(.*)$ balancer://app-server_cluster%{REQUEST_URI} [P,QSA,L]

Specifically, the blocks of rules perform these functions:

  • The DocumentRoot directive specifies the local disk directory where content is stored.
  • The first block of rules detects whether the file /system/maintenance.html exists – it’s a common practice among website administrators to create this file as a signal that the website is temporarily unavailable due to maintenance. If file exists, it is served no matter what file is requested (effectively, the rule rewrites all requests to maintenance.html). Presumably, the rewrite results in the sending of a maintenance notification to the browser.
  • The next three blocks serve these static assets if they exist:
    • The requested file
    • The index.html file in the directory named at the end of the URL
    • Any file with the .html extension
  • The final rule comes into play if none of the three types of file exist. It passes the request to a cluster of application servers.

Here’s the conversion for NGINX Plus. The root directive corresponds to the Apache DocumentRoot directive. The try_files directive replaces the remaining rules, using a named location (@app-server_cluster) as the final rewrite and defining a corresponding location block that proxies requests to the application server:

location / { root /var/www/; try_files /system/maintenance.html $uri $uri/index.html $uri.html @app-server_cluster; } location @app-server_cluster { proxy_pass http://app-server; }

The post Converting Apache Rewrite Rules to NGINX Rewrite Rules appeared first on NGINX.