

Migrate Apache .htaccess to NGINX server block
source link: https://www.tuicool.com/articles/hit/MvMrEvf
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

At the end of last year, this blog was migrated to a new server, hosted by DigitalOcean. The old server ran on Apache but on the new server I wanted to try out the LEMP One-click application .
LEMP stands for Linux, NGINX (say: en-juhn-ex), MySQL, PHP. The old server ran on Apache, so some things needed to be migrated from Apache to Nginx.
Differences between Apache and NGINX
The biggest difference between Apache and NGINX (for me) is the fact that Apache can be configured using .htaccess files and NGINX can't. That means that any logic contained in the .htaccess file(s) must be migrated to the NGINX Server Block. A server block is the NGINX equivalent of Apache's Virtual Host.
If you want to learn more, read this excellent article about the differences between Apache and Nginx .
The old .htaccess file
So, let's have a look at the old annotated .htaccess file. There was only one file, which was located in the public_html
directory.
<IfModule mod_rewrite.c> <IfModule mod_negotiation.c> Options -MultiViews </IfModule> # set Expire and Cache Control headers for css and js <IfModule mod_expires.c> ExpiresActive On ExpiresDefault "access" ExpiresByType text/css "access plus 1 year" ExpiresByType application/javascript "access plus 1 year" ExpiresByType font/truetype "access plus 1 year" ExpiresByType font/opentype "access plus 1 year" ExpiresByType application/x-font-woff "access plus 1 year" ExpiresByType image/svg+xml "access plus 1 year" ExpiresByType application/vnd.ms-fontobject "access plus 1 year" ExpiresByType image/vnd.microsoft.icon "access plus 1 month" </IfModule> RewriteEngine On # Redirect to preferred domain RewriteCond %{HTTP_HOST} !(^barryvanveen\.test|^barryvanveen\.nl)$ [NC] RewriteRule ^(.*)$ https://barryvanveen.nl/$1 [R=301,L] # Redirect old Dutch urls to English urls RewriteRule ^over-mij$ https://barryvanveen.nl/about-me [L,R=301] RewriteRule ^over-mij/boeken-die-ik-heb-gelezen$ https://barryvanveen.nl/about-me/books-that-i-have-read [L,R=301] # Redirect to HTTPS domain RewriteCond %{HTTP_HOST} ^barryvanveen.nl$ [NC] RewriteCond %{HTTPS} !=on [NC] RewriteRule ^(.*)$ https://barryvanveen.nl/$1 [R=301,L] # Redirect assets with filehash in name to actual filename RewriteRule ^dist/css/(.*)\.[0-9a-f]{8}\.css$ /dist/css/$1.css [L] RewriteRule ^dist/js/(.*)\.[0-9a-f]{8}\.js$ /dist/js/$1.js [L] # Remove trailing slashes if not a folder RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_URI} (.+)/$ RewriteRule ^ %1 [L,R=301] # Handle request using index.php RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^ index.php [L] </IfModule>
The equivalent NGINX Server Block
And here is the NGINX Server Block that accomplices the same thing.
# map content types to expire times map $sent_http_content_type $expires { default off; text/css max; application/font-woff max; application/javascript max; ~image/ 7d; } # redirect http to https server { listen 80; listen [::]:80; server_name barryvanveen.nl; server_name www.barryvanveen.nl; return 301 https://barryvanveen.nl$request_uri; } # redirect https to domain without www. server { listen 443 ssl; listen [::]:443 ssl; server_name www.barryvanveen.nl; return 301 https://barryvanveen.nl$request_uri; ssl_certificate /path/to/certificate.pem; # managed by Certbot ssl_certificate_key /path/to/private/key.pem; # managed by Certbot } # serve website over https server { listen 443 ssl; listen [::]:443 ssl; server_name barryvanveen.nl; root /var/www/barryvanveen_nl/public_html; index index.php index.html index.htm index.nginx-debian.html; # serve website using index.php location / { try_files $uri $uri/ /index.php?$query_string; } # redirect old Dutch urls to English urls location = /over-mij { return 301 /about-me; } location = /over-mij/boeken-die-ik-heb-gelezen { return 301 /about-me/books-that-i-have-read; } # tell NGINX how to serve PHP files location ~ \.php$ { try_files $uri /index.php =404; fastcgi_split_path_info ^(.+\.php)(/.+)$; fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME $request_filename; include fastcgi_params; } # redirect assets with filehash in name to actual filename location ~ ^/dist/ { rewrite "^/dist/css/(.*)\.[0-9a-f]{8}\.css$" /dist/css/$1.css last; rewrite "^/dist/js/(.*)\.[0-9a-f]{8}\.js$" /dist/js/$1.js last; } # serve expires header expires $expires; ssl_certificate /path/to/certificate.pem; # managed by Certbot ssl_certificate_key /path/to/private/key.pem; # managed by Certbot }
Differences
Let's point out some differences that stood out for me:
-
The NGINX Server Block contains all .htaccess logic but also the logic that was in the Apache Virtual Host. This explains why the
server
,server_name
androot
directives (among others) are necessary. -
There are three
server
directives but only one actually serves the website. - We actually have to tell NGINX how to properly how to serve PHP files.
- The content types for the Expire headers have changed. This might not be due to NGINX, it is worth watching out for this if you are migrating a website.
Learn more about NGINX
One of the strong points of NGINX is that it is very opinionated. This means the docs are very clear about good and bad configurations. Please read the following links carefully if you plan a migration yourself.
-
Docs for core NGINX directives
. Check out
server
,location
andtry_files
. -
Docs for rewrite NGINX directives
. Check out
return
andrewrite
. - Read about pitfalls and common mistakes .
-
Why the NGINX
If
directive is evil .
Did you think this article was helpful? Can my server block be improved or do you have some additional resources? Let me know in a comment!
Other articles
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK