Nginx forward www and non-www requests to one directory? - nginx

I have a MediaTemple server from which I serve many websites. I use nginx and have the follow config file. I am correctly forwarding all non-www traffic (ie, http://example.com) to the appropriate directory. However, all the www traffic is returning 404 because my config file is looking for /directory-structure/www.sitename.com instead of /directory-structure/sitename.com
How can I have both www and non-www requests go to one directory? Thanks.
server {
listen 80;
server_name _;
root /var/www/vhosts/$host/httpdocs/;
error_page 404 /;
location / {
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
#fastcgi_pass php;
fastcgi_pass 127.0.0.1:9000;
}
location ~* \.(?:ico|css|js|gif|jpe?g|png)$ {
expires max;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
# this prevents hidden files (beginning with a period) from being served
location ~ /\. { access_log off; log_not_found off; deny all; }
}

Starting with version 0.7.40 Nginx accepts regular expressions in server_name and captures. Thus it's possible to extract a domain name (without www) and use this variable in root directive:
server_name ~^(?:www\.)?(.+)$ ;
root /var/www/vhosts/$1/httpdocs;
Starting with 0.8.25 it is possible to use named captures:
server_name ~^(?:www\.)?(?P<domain>.+)$ ;
root /var/www/vhosts/$domain/httpdocs;
Another syntax to define named captures is (?<domain>.+) (PCRE version 7.0 and later). More on PCRE versions here

Try this and add the following in the above server config:
if ($host = "www.example.com") {
rewrite (.*) http://example.org$1;
}
What happens here, we are instructin nginx to serve the pages as http://example.com even though the browser URL reads http://www.example.com - I hope this works.
UPDATE
Try this for a generic version:
if ($host ~* "www.(.*)") {
rewrite ^ http://$1$request_uri?;
}

Given the potential issues with if as linked to in RakeshS's answer's comments, as well as the fact that RakashS's answer didn't work for me anyway, here's a solution that should be safer and worked for me with Nginx 1.0.14.
Add an additional server entry for each one of your server sections that does a rewrite:
server {
server_name www.yourwebsite.com;
rewrite ^ $scheme://yourwebsite.com$request_uri permanent;
}

Related

NGINX Cache Busting CSS JS URL Rewrite

I'm new to NGINX and trying to set up a portfolio. I've gotten my site working with the exception of a few errors that I noticed through Google Chrome DevTools.
I notice that javascript files aren't loading and have the incorrect path. For example, it tries to load http://site/assets/js/site.1617886701.js but the actual file is http://site/assets/js/site.js
Likewise with a css file I have: It tries to load http://site/assets/css/templates/home..css (for some reason it adds an extra .?) when it should be loading this file: http://site/assets/css/templates/home.css
This is my NGINX config file:
server {
listen 80;
listen [::]:80;
root /var/www/html/;
index index.php index.html index.htm;
server_name site wwww.site.com;
client_max_body_size 100M;
location / {
try_files $uri $uri/ /index.php?$uri&$args;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
location /assets {
rewrite uikit.min.(\d+).js uikit.min.js permanent;
rewrite uikit-icons.min.(\d+).js uikit-icons.min.js permanent;
rewrite uikit.app.min.(\d+).css uikit.app.min.css permanent;
try_files $uri =404;
expires max;
access_log off;
add_header Pragma public;
add_header Cache-Control "public, must-revalidate, proxy-revalidate";
}
}
From my googling online it says something about cache busting. Some people have suggested matching the file names in the NGINX config file which I'm not sure how to do or to change the paths to match the hexadecimal versions which I also don't know where to begin.
I would really appreciate any help from the pros! Thanks so much
For example, it tries to load http://site/assets/js/site.1617886701.js but the actual file is http://site/assets/js/site.js
It is not NGINX, it's your web application, which constructs such cache-busting URLs, which expect extra configuration on the side of NGINX.
The way to deal with it, is a rewrite in NGINX:
rewrite ^(.+)\.(\d+)\.(css|js)$ $1.$3 last;
This will rewrite, e.g. any /some/<foo>.<digits>.js to /some/<foo>.js.
It tries to load http://site/assets/css/templates/home..css
Obviously, a bug in your web application's code. Shouldn't be attempted to be fixed in NGINX.

Nginx location rules not applying

I want to run both WordPress and YOURLS on one domain which is configured by a NGINX server block (not the default site). Since both need to handle URLs differently, they need different try_files directives. WordPress sits on the root of the domain (domain.tld), while YOURLS is being installed to the /g/ directory. Despite the two location rules, I get 404s on any links generated by YOURLS (e.g. domain.tld/g/linkname, all are redirects to external URLs), though I can access the admin backend.
As far as I read, declaring to location rules (one for /g/, and one for /) should suffice in order to let NGINX handle the direct and the /g/ URLS differently - is there something in wrong in my thinking?
The try_files rules are correct and do work well on other single-application server block (WordPress as well as YOURLS on installs on separate server blocks).
The server block definition config looks like this:
server {
listen [::]:80;
listen 80;
server_name domain.tld www.domain.tld;
return 301 https://domain.tld$request_uri;
}
server {
listen [::]:443 ssl;
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/domain.tld/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.tld/privkey.pem;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
root /var/www/html/domain.tld;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html index.php;
server_name domain.tld www.domain.tld;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors off;
}
location /g/ {
try_files $uri $uri/ /yourls-loader.php$is_args$args;
expires 14d;
add_header Cache-Control 'public';
}
location / {
try_files $uri $uri/ /index.php?$args;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}
The problem with the location /g/ try_files directive is that the path to the YOURLS loader isn't correct. If the URL handler (yourls-loader.php) lies within the /g directory, the path to it has to be changed to include the /g directory:
try_files $uri $uri/ /g/yourls-loader.php$is_args$args;
The location rule does not imply that each path is handled from that location as well, but rather from the root path given above.

How does one host a Kohana installation from a subdirectory on Nginx?

I am attempting to host a Kohana installation on Nginx. The difference is that I am trying to serve it up from a subdirectory as opposed to the web root itself.
The problem:
When trying to access the url, http://myproject.tld/Project/Welcome, I am given the error message: No input file specified.
Upon investigation, I noticed that this is in fact being rewritten as http://myproject.tld/index.php/Project/Welcome/ when it should be http://myproject.tld/Project/index.php/Welcome/
as seen here:
2014/01/02 23:10:57 [debug] 20952#0: *30 http copy filter: 0 "index.php/Project/Welcome?"
2014/01/02 23:10:57 [debug] 20952#0: *30 http finalize request: 0, "index.php/Project/Welcome?" a:1, c:1
Now, I understand fully why it is happening. Because I am hosting from a subdirectory that will exist within the request_uri and is appended to the url rewrite. If I were serving from the document root this wouldn't be an issue. What I'm hoping is someone can point me in the correct direction for solving this particular hiccup.
Setup Information:
nginx/1.4.4
Kohana 3.3.1
Server configuration:
server {
listen 80;
server_name mydomain.tld;
access_log /home/<user>/logs/mydomain-access.log;
error_log /home/<user>/logs/mydomain-error.log debug;
# main root
root /home/<user>/domains/mydomain.tld;
index index.php index.html;
location / {
expires off;
try_files $uri $uri/;
}
# Prevent access to hidden files
location ~ /\. {
deny all;
}
location /Project/ {
rewrite ^(.+)$ index.php$request_uri last;
}
location ~* \.php {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param KOHANA_ENV development;
fastcgi_cache off;
fastcgi_index index.php;
}
}
To get http://myproject.tld/Project/index.php/Welcome/ rewriting you should configure Kohana in /application/bootstrap.php - base_url to /Project/ in Kohana::init() block.

Moodle 2.3 with Nginx vs slash argument rewrite

I'm trying to setup Moodle 2.3 (not 2.5) ver with nginx latest build. There was some advice on this site before. One of them: Moodle 2.0 with Nginx backend.
Apparently as anybody knows, Moodle is using path_info rules to post URL's like this: http://example.com/moodle/pluginfile.php/26/mod_scorm/content/1/index.html. To escape all this nightmare, Moodle is offering to disable "Slash arguments" in UI. Which is great. But not for SCORM player which is forcing "Slash argument" despite the previous option. So with disabled "Slash arguments" everything is working and normal. But my only goal is to use SCORM player.
I tried to use the rewrite rule from the link above:
rewrite ^(.*\.php)(/)(.*)$ $1?file=/$3 last;
which is not working in 2.3-2.5 ver. I assume it worked in 1.9.
Now Moodle is using different path:
http://example.com/moodle/pluginfile.php/26/mod_scorm/content/1/index.html
Some of nginx rules:
location ^~ /moodle {
location ~* ^.+\.(?:css|js|htc|xml|jpe?g|gif|png|ico|bmp|svg|swf|pdf|docx?|xlsx?|tiff?|txt|rtf|cgi|bat|pl|dll|aspx?|class|otf|ttf|woff|eot|less)$ {
add_header Access-Control-Allow-Origin *;
access_log off;
expires 30d;
tcp_nodelay off;
try_files $uri =404;
}
location ~* ^/moodle/.*\.php$ {
include includes/fastcgi_params.conf;
try_files $uri #dynamic;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fastcgi_path_info;
fastcgi_read_timeout 1200;
fastcgi_keep_conn on;
fastcgi_pass 127.0.0.1:9090;
}
rewrite (^.*\.php)(/.*) $1 last;
}
Please advise how to solve this.
(Answered by the OP in a question edit. Converted to a community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
I solved this by putting rewrite directive in {server} not in {location} section. In my scenario moodle is installed under subfolder: example.com/moodle.
server {
server_name example.com www.example.com;
rewrite ^/moodle/(.*\.php)(/)(.*)$ /moodle/$1?file=/$3 last;
location ^~ /moodle {
try_files $uri $uri/ /index.php?q=$request_uri;
index index.php index.html index.htm;
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 127.0.0.1:9090;
include includes/fastcgi_params.conf;
}
}
}

nginx rewrite mystery - duplicating hostname and losing https

I am replacing lighttpd with nginx on my development server. I got it working with PHP and SSL, but I'm stumped by what should be a simple rewrite. I need to rewrite URLs from
http[s]://dev.foo.com/signup/123456
to
http[s]://dev.foo.com/signup/index.php?attcode=123456
The rule I am using is:
rewrite ^/signup/([0-9]+)$ /signup/index.php?attycode=$1 last;
I have tried numerous variations on this, moved it around, put it inside a location block. What happens is the URL is rewritten to:
http://dev.foo.com/dev.foo.com/signup/123456
The hostname is inserted, and it seems to always lose https and go to http.
My nginx.com server section is below. I have read and re-read the nginx docs (as they are) and searched the nginx mailing list, but nothing I've tried has solved this problem.
Ubuntu 8.0.4 LTS in case that matters.
Thanks.
server {
listen 80;
listen 443 default ssl;
server_name dev.foo.com dev.bar.com localhost;
root /var/www/foo;
index index.php index.html;
# ssl cert stuff omitted
charset utf-8;
access_log /var/log/www/dev.access.log main;
location ~ /\. {
deny all;
}
location ~* ^.+\.(inc|tpl|sql|ini|bak|sh|cgi)$ {
deny all;
}
location ~* ^/(scripts|tmp|sql)/ {
deny all;
}
rewrite ^/robots.txt$ /robots_nocrawl.txt break;
rewrite ^/signup/([0-9]+)$ /signup/index.php?attycode=$1 last;
location / {
try_files $uri $uri/ /error_404.php;
}
location ~ \.php$ {
fastcgi_pass localhost:51115;
fastcgi_index index.php;
fastcgi_intercept_errors on;
include fastcgi_params;
fastcgi_param SERVER_NAME $http_host;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
error_page 404 /error_404.php;
}
Don't put HTTP and HTTPS in the same server block. Separate them into two almost-identical server blocks, one for HTTP and one for HTTPS. Otherwise you will confuse all kinds of Nginx internals.

Resources