NGINX rewriting rule for getting clean URL - wordpress

What would be the nginx rewrite rule to redirect my wordpress permalink structure from /%category%/%postname%/ to /%postname%/?

In summary, you need to let NGINX know that if that file doesn't exist, to not throw a 404 error, but rather call index.php. Wordpress is smart enough to parse the URL as parameters, and serve the correct page.
Add this snippet in your server configuration block:
location / {
try_files $uri $uri/ /index.php?$args;
}
Here is a complete example from nginx.org:
# Upstream to abstract backend connection(s) for php
upstream php {
server unix:/tmp/php-cgi.socket;
server 127.0.0.1:9000;
}
server {
## Your website name goes here.
server_name domain.tld;
## Your only path reference.
root /var/www/wordpress;
## This should be in your http block and if it is, it's not needed here.
index index.php;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
location / {
# This is cool because no php is touched for static content.
# include the "?$args" part so non-default permalinks doesn't break when using query string
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
#NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
include fastcgi.conf;
fastcgi_intercept_errors on;
fastcgi_pass php;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires max;
log_not_found off;
}
}

Related

Yii2 after server change can't authenticate via query param auth

I upgraded my Yii2 application version to the latest - 2.0.46 and changed server from apache to Nginx and now I can't make API GET request from my application using query param auth Given error below
<response>
<name>Unauthorized</name>
<message>Your request was made with invalid credentials.</message>
<code>0</code>
<status>401</status>
<type>yii\web\UnauthorizedHttpException</type>
</response>
My API controller looks like this
public function behaviors(): array
{
$behaviors = parent::behaviors();
$behaviors['authenticator'] = [
'class' => CompositeAuth::class,
'authMethods' => [
QueryParamAuth::class,
]
];
$behaviors['language'] = [
'class' => LanguageSelector::class
];
return $behaviors;
}
I read that similar problem people had with apache servers and editing .htaccess helped, but what about Nginx? Or maybe problem is with new Yii2 version!?
API call example that I am making - examplesite/api/controller/method/?access-token=myaccesstoken&id=myID&lang=lv-LV
As my application is using only get requests, old version and new version uses same DB and on old version API call like example given (with good data) works fine. Can enyone help me?
UPDATE: Nginx config
server {
listen 443 ssl;
# server_name exsampleserver;
server_name exampleserverIP
# add_header Strict-Transport-Security 'max-age=31536000; includeSubDomains; preload';
ssl_certificate /etc/nginx/ssl/certdomainexample.crt;
ssl_certificate_key /etc/nginx/ssl/certdomainexample.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
access_log /var/log/nginx/app.log upstream_time;
error_log /var/log/nginx/app-ssl.error.log notice;
root /srv/www/web/frontend/web;
index index.php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location /api/ {
try_files $uri $uri/ /api/index.php?query_string;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_read_timeout 1200;
fastcgi_send_timeout 1200;
fastcgi_connect_timeout 1200;
fastcgi_buffers 4 256k;
fastcgi_busy_buffers_size 256k;
fastcgi_temp_file_write_size 256k;
fastcgi_pass_header Authorization;
}
location ~ /\.ht {
deny all;
}
location ~ /\.git {
deny all;
}
}
With a help from tech group we founded that working with symlinks in Nginx config $query_params wont work.
So instead of
location /api/ {
try_files $uri $uri/ /api/index.php?query_string;
}
need to add
location /api/ {
try_files $uri $uri/ /api/index.php$is_args$args;
}
into Nginx config
Directory structure:
examplesite:
- api
+ models
+ controllers
+ web
- backend
+ models
+ controllers
+ web
+ common
+ console
- frontend
+ models
+ controllers
+ web
+ vendor
+ composer.json
Nginx config for Yii2 advanced app
This config will allow you to use fallowing domain rules:
examplesite.test/api - api folder app
examplesite.test/admin - backend folder app
examplesite.test/ - frontend folder app
Disclaimer
Use this config only in test environments and if you know how nginx works. For production sites better ask for a specialist help.
server {
#listen *:443 ssl http2;
listen *:80;
server_name examplesite.test;
#include /etc/nginx/ssl-snippets/ssl-snippet.conf;
# LOGS - config
access_log /var/log/nginx/examplesite.access.log;
error_log /var/log/nginx/examplesite.error.log;
# NGINX - config (sizes, charset, caching, ...)
client_max_body_size 32m;
client_body_buffer_size 32m;
charset utf-8;
gzip on;
gzip_types
text/plain
text/css
text/xml
application/xml
application/xml+rss
text/javascript
application/json
application/x-javascript
application/javascript;
# BASE ROOT DIRECTORY for Yii advanced app setup. Default must be the path to your app composer.json. Let suppose it in /var/www/examplesite
set $base_root /var/www/examplesite;
# BASE PHP-FPM SOKET - this is passed to nginx fastcgi_pass, uncoment or add needed version
set $php_server unix:/run/php/php7.4-fpm.sock;
#set $php_server unix:/run/php/php8.0-fpm.sock;
#set $php_server unix:/run/php/php8.1-fpm.sock;
root $base_root;
index index.php index.html;
# FRONTEND APP - location config
location / {
root $base_root/frontend/web;
try_files $uri $uri/ /frontend/web/index.php$is_args$args;
# omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
location ~ ^/.+\.(css|less|js|map|ico|png|jpe?g|gif|webp|svg|eot|ttf|woff|woff2|mp4|mov|swf|txt|pdf)$ {
expires 365d;
log_not_found off;
access_log off;
try_files $uri =404;
}
location ~ ^/assets/.+\.php(/|$) {
deny all;
}
}
# API APP - location config
location /api {
root $base_root/api/web/;
# redirect to the URL without a trailing slash (uncomment if necessary)
#location = /api/ {
# return 301 /api;
#}
location = /api {
try_files $uri /api/web/index.php$is_args$args;
}
# omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
location ~ ^/api/.+\.(css|less|js|map|ico|png|jpe?g|gif|webp|svg|eot|ttf|woff|woff2|mp4|mov|swf|txt|pdf)$ {
rewrite ^/api(/.+)$ $1 break;
log_not_found off;
access_log off;
try_files $uri =404;
}
location ~ ^/api/assets/.+\.php(/|$) {
deny all;
}
try_files $uri $uri/ /api/web/index.php$is_args$args;
}
# BACKEND APP - location config
location /admin {
root $base_root/backend/web/;
# redirect to the URL without a trailing slash (uncomment if necessary)
#location = /admin/ {
# return 301 /admin;
#}
# prevent the directory redirect to the URL with a trailing slash
location = /admin {
try_files $uri /backend/web/index.php$is_args$args;
}
# omit static files logging, and if they don't exist, avoid processing by Yii (uncomment if necessary)
location ~ ^/admin/.+\.(css|less|js|map|ico|png|jpe?g|gif|webp|svg|eot|ttf|woff|woff2|mp4|mov|swf|txt|pdf)$ {
rewrite ^/admin(/.+)$ $1 break;
log_not_found off;
access_log off;
try_files $uri =404;
}
location ~ ^/admin/assets/.+\.php(/|$) {
deny all;
}
# if your location is "/backend", try use "/backend/backend/web/index.php$is_args$args"
# bug ticket: https://trac.nginx.org/nginx/ticket/97
try_files $uri $uri/ /backend/web/index.php$is_args$args;
}
# PHP FILES HANDLE
location ~ ^/.+\.php(/|$) {
rewrite (?!^/((frontend|api|backend)/web|api|admin))^ /frontend/web$uri break;
rewrite (?!^/api/web)^/api(/.+)$ /api/web$1 break;
rewrite (?!^/backend/web)^/admin(/.+)$ /backend/web$1 break;
fastcgi_pass $php_server;
fastcgi_split_path_info ^(.+\.php)(.*)$;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
try_files $fastcgi_script_name =404;
}
# OTHER LOCATIONS AND RESTRICTIONS
location = /robots.txt { access_log off; log_not_found off; }
location = /favicon.ico { access_log off; log_not_found off; }
location ~* /\. { access_log off; log_not_found off; deny all; }
}

Enabling wordpress with a flask app using nginx

Is it possible to enable wordpress on /blog of an existing flask application using nginx? Here is the config i've been working with but not getting anywhere with it. I can get either flask or wordpress to work through nginx but
1) not both at the same time
2) not wordpress with /blog option enabled (wordpress works at / but not /blog)
server {
listen 80;
server_name 0.0.0.0;
#### if I enable the flask app, the blog doesn't work, so how can I keep this as well as add /blog ####
# location / {
# include uwsgi_params;
# uwsgi_pass unix:/var/www/html/cr_webapp/my_app.sock;
#}
#### if I change / to /blog, it starts looking in /usr/share/nginx/html location ####
location = / {
#root /var/www/html/blog;
index index.php;
try_files $uri $uri/ /blog/index.php?q=$uri?$args;
}
location = /favicon.ico {
root /var/www/html/blog;
log_not_found off;
access_log off;
}
location = /robots.txt {
root /var/www/html/blog;
allow all;
log_not_found off;
access_log off;
}
location ~ \.php$ {
root /var/www/html/blog;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
root /var/www/html/blog;
expires max;
log_not_found off;
}
}
I've looked at a link but the solution didn't work for me. Also, when I use /blog, it defaults to a --prefix location, so not sure how I can change that - a link
Is what I am trying to do possible? or i've been ignorant this whole time.
To run WordPress under the /blog prefix, and assuming that it's installed in a directory with the same name, you set root to the directory above.
Use the ^~ modifier, and nested location blocks for anything that belongs to WordPress. See this document for details.
location ^~ /blog {
root /var/www/html;
index index.php;
try_files $uri $uri/ /blog/index.php?q=$uri?$args;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires max;
log_not_found off;
}
}
Assuming that your existing flask configuration works, these lines should be fine:
location / {
include uwsgi_params;
uwsgi_pass unix:/var/www/html/cr_webapp/my_app.sock;
}
The following lines are unrelated to WordPress or flask. If the files exist, set a value for root which points to where the files are located.
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
log_not_found off;
access_log off;
}

How to remove index,php from CI project url to make clean url in nginx Hostwinds server, when CI project is inside subdirectory?

"I'm setting up an Nginx server on Hostwinds for CI project which is in a subdirectory. Where I want to make a clean URL by removing index.php. Initially, this project was running on Apache server and with the help of .htaccess file, I have made a clean URL by removing index.php. But .htaccess file not works on the Nginx server. So, tell me what codes should I use to remove index.php from URL in 'Hostwinds' Server.
In subdirectory home page of projects opens but when you click on any of its links it will redirects you to 404 page.
I have tried various solution which is available on the internet but none of them worked for me. I have used this code inside nginx.conf file.
some of them:-
1)
location /category/subcategory {
try_files $uri $uri/ /category/subcategory/index.php;
}
2)
location /subfoldername/ {
root /usr/share/nginx/www/subfoldername;
try_files $uri $uri/ /index.php?$query_string;
}
3)
location /api/ {
alias /var/www/api/;
try_files $uri $uri/ /api/index.php;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_index index.php;
fastcgi_pass backend;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
4)
location /nested {
alias /var/www/nested/public;
try_files $uri $uri/ /index.php$is_args$args;
}
...http {...
server {
listen 443 ssl http2;
#listen [::]:443 ssl http2 ipv6only=off;
server_name example.com;
location / {
index index.html index.htm index.php;
try_files $uri $uri/ #backend;
}
location #backend {
include proxy_params_common;
# === MICRO CACHING ===
# Comment the following line to disable 1 second micro-caching for dynamic
HTML content
include proxy_params_dynamic;
}
# Enable browser cache for static content files (TTL is 1 hour)
location ~* \.(?:json|xml|rss|atom)$ {
include proxy_params_common;
include proxy_params_static;
expires 1h;
}
# Enable browser cache for CSS / JS (TTL is 30 days)
location ~* \.(?:css|js)$ {
include proxy_params_common;
include proxy_params_static;
expires 30d;
}
# Enable browser cache for images (TTL is 60 days)
location ~* \.(?:ico|jpg|jpeg|gif|png|webp)$ {
include proxy_params_common;
include proxy_params_static;
expires 60d;
}
# Enable browser cache for archives, documents & media files (TTL is 60 days)
location ~* \.
(?:3gp|7z|avi|bmp|bz2|csv|divx|doc|docx|eot|exe|flac|flv|gz|less|mid|midi|mka|mkv|mov|mp3|mp4|mpeg|mpg|odp|ods|odt|ogg|ogm|ogv|opus|pdf|ppt|pptx|rar|rtf|swf|tar|tbz|tgz|tiff|txz|wav|webm|wma|wmv|xls|xlsx|xz|zip)$ {
set $CACHE_BYPASS_FOR_STATIC 1;
include proxy_params_common;
include proxy_params_static;
expires 60d;
}
# Enable browser cache for fonts & fix #font-face cross-domain restriction (TTL is 60 days)
location ~* \.(eot|ttf|otf|woff|woff2|svg|svgz)$ {
include proxy_params_common;
include proxy_params_static;
expires 60d;
#add_header Access-Control-Allow-Origin *;
}
# Prevent logging of favicon and robot request errors
location = /favicon.ico {
include proxy_params_common;
include proxy_params_static;
expires 60d;
log_not_found off;
}
location = /robots.txt {
include proxy_params_common;
include proxy_params_static;
expires 1d;
log_not_found off;
}
# Deny access to files like .htaccess or .htpasswd
location ~ /\.ht {
deny all;
}
}
Initially link:- www.example.com/index.php/search-result
resulted in link:- www.example.com/search-result

nginx and API versioning in Accept header or URL

So I have decided to do two kind of wrong, slightly inspired by Troy Hunt.
I would like my API to accept version specification through Accept header but also in the URL, e.g. /v1.
For now, I have made an nginx config which works with Accept header, but trying out various methods, I have not been able to get the /v1
What I want to achieve is that the URL passed to my application, does not include the version part as the role of the version is simply to point at a root directory.
map $http_accept $api_version {
default 0;
"application/vnd.it.echo.api+json; version=1" "v1";
}
server {
listen 80;
server_name api.app;
index index.html index.htm index.php;
charset utf-8;
sendfile off;
rewrite_log on;
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location / {
if ($api_version = 0) {
return 307 https://echo.it;
}
try_files $uri $uri/ #api;
}
location /v1 {
set $api_version "v1";
rewrite ^/.+/(.+)$ /$1 last;
}
location #api {
root /home/vagrant/api/$api_version/public/;
error_log /var/log/nginx/api.$api_version.app-error.log error;
try_files $uri $uri/ /index.php?$query_string;
}
error_page 404 /index.php;
location ~ \.php$ {
root /home/vagrant/api/$api_version/public/;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~ /\.ht {
deny all;
}
}
The problem appears to be with the rewrite rule in the /v1 location directive not taking effect.

Nginx config is not case insensitive to image files

Images are only displaying if they have the correct case. These need to be case insensitive please see my config file.
The image I have having trouble with works at:
http://domain.com/sites/default/files/vimages/imagename.jpg
but not at
http://domain.com/sites/default/files/vimages/imagename.JPG
server {
listen 80;
server_name domain.com;
root /home/domain.com/www; ## <-- Your only path reference.
access_log /home/domain.com/logs/access.log;
error_log /home/domain.com/logs/error.log;
# Enable compression, this will help if you have for instance advagg‎ module
# by serving Gzip versions of the files.
gzip_static on;
gzip on;
location = /favicon.ico {
log_not_found off;
access_log off;
}
location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}
# This matters if you use drush
location = /backup {
deny all;
}
# Very rarely should these ever be accessed outside of your lan
location ~* \.(txt|log)$ {
allow 192.168.0.0/16;
deny all;
}
location ~ \..*/.*\.php$ {
return 403;
}
# No no for private
location ~ ^/sites/.*/private/ {
return 403;
}
# Block access to "hidden" files and directories whose names begin with a
# period. This includes directories used by version control systems such
# as Subversion or Git to store control files.
location ~ (^|/)\. {
return 403;
}
location / {
# This is cool because no php is touched for static content
try_files $uri #rewrite;
}
location #rewrite {
# Some modules enforce no slash (/) at the end of the URL
# Else this rewrite block wouldn't be needed (GlobalRedirect)
rewrite ^ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
#fastcgi_pass 127.0.0.1:9000;
fastcgi_read_timeout 180;
fastcgi_intercept_errors on;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 52w;
add_header Cache-Control "max-age=31449600, no-transform, public";
log_not_found off;
}
# Catch image styles for D7 too.
location ~* ^/sites/.*/files/styles/ {
try_files $uri #rewrite;
}
location ~* /sites/.*/files/vimages/ {
try_files $uri #rewrite;
}
# Fighting with ImageCache? This little gem is amazing.
location ~ ^/sites/.*/files/imagecache/ {
try_files $uri #rewrite;
}
}
Nginx is working against the filesystem and has no control over the name of the files when serving from a directory.
If you want case insensitive you need to do a rewrite.

Resources