So,
I've got a server with around 30 virtual host configurations, each in their own separate file. My main aim at this point is to name the access log based on the $host variable.
At the moment, I'm using the following, inside of my HTTP block to be applied to all conf files:
http {
access_log /var/log/nginx/$host.access.log
}
I'd like to be able to rewrite the above $host without the www., and just keep the domain itself. I've found the following solution for that:
if ($domain ~* www\.(.*)) {
set $domain $1;
rewrite ^(.*)$ http://$domain$1 permanent;
}
Only problem is.. 'IF' Directives are not allowed inside of the 'http' block.. Is there anyway I can achieve this, whilst still being within the 'http' block? Maybe using 'map'?
Thanks in advance,
Tom
You should use a map
http {
map $host $hostw {
default $host;
~*^www\.(.*) $1;
}
access_log /var/log/nginx/$hostw.access.log
}
I have a Lumen api project with multiple git tags for api versioning. So I have to deploy multiple checkouts of the project.
The folder structure on the server looks like this:
var
www
api-staging
master
v1
public
index.php
...
v2
public
index.php
...
lastest
public
index.php
...
...
Now I'd like to serve the projects via nginx so that the url looks something like this.
http://BRANCH.domain.tld/VERSION/ eg. http://master.domain.tld/lastest/
I have tried a lot with regexp, but nothing really worked. I hope you can help me out.
You will need to capture the BRANCH using a regular expression server_name statement. See this document for more.
The root is constructed by appending /public to the captured VERSION, which requires a regular expression location and an alias statement. See this document for more.
For example:
server {
...
server_name ~^(?<branch>.+)\.domain\.tld$;
location ~ ^/(?<version>[^/]+)/(?<name>.*)$ {
alias /var/www/api-staging/$branch$version/public/$name;
if (!-e $request_filename) { rewrite ^ $version/index.php last; }
location ~ \.php$ {
if (!-f $request_filename) { return 404; }
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
...
}
}
}
I have the following url:
mywebsite.com/template/product.html
and I want to rewrite it as
mywebsite.com/product
location / {
alias /var/www/web/;
rewrite ^/(mywebsite.com/template/.*)\.html$ /$1 last;
}
Not sure if you want to handle the domain as a generic variabile.
Anyway, if you setup a server conf for mywebsite.com, this configuration should fit your case.
server {
error_log logs/mywebsite.com.log debug;
server_name mywebsite.com;
root /var/www/web/mywebsite.com;
# this directive handle the redirects from old name.html to new format
location /template/ {
rewrite ^/template/([^.]+)\.html$ /$1 redirect;
}
# given new new url format this directive match the name and
# read the file
location ~* ^/([^.]+)$ {
try_files /template/$1.html /template/notfound.html;
}
}
The regular expression you wrote did not match the product name. Now the group should fit your requirements. I have also modified the rewrite flag last in redirect because I suppose you want redirect a browser or a bot to the new urls.
Trying to achieve constant language code in url's 1st segment with nginx regex location configuration and could not find the correct syntax.
Necessary result:
example.com stays example.com
example.com/en stays example.com/en
example.com/en/ stays example.com/en or example.com/en/ (don't care)
example.com/en/etc stays example.com/en/etc
example.com/etc changes to example.com/en/etc
example.com/etc/segment changes to example.com/en/etc/segment
Currently I have found out this code but it still stuck in somewhere. It makes permanent loop and doesn't not use $1 argument.
location ~ "^/(?![a-z]{2}/)(.+)$" {
rewrite / /en/$1 permanent;
}
#Using handler here for removing index.php in uri (example.com/index.php -> example.com);
location / {
index index.htm index.html index.php;
try_files $uri $uri/ #handler;
}
location #handler {
rewrite / /index.php?$query_string;
}
UPDATE:
Answer can be found in this question: https://stackoverflow.com/a/33913261/2662849
I try to get an / to every urls end:
example.com/art
should
example.com/art/
I use nginx as webserver.
I need the rewrite rule for this..
For better understanding check this:
http://3much.schnickschnack.info/art/projekte
If u press on a small thumbnail under the big picture it reloads and shows this url:
http://3much.schnickschnack.info/art/projekte/#0
If i now have a slash on all urls (on the end) it would work without a reload of the site.
Right now i have this settings in nginx-http.conf:
server {
listen *:80;
server_name 3much.schnickschnack.info;
access_log /data/plone/deamon/var/log/main-plone-access.log;
rewrite ^/(.*)$ /VirtualHostBase/http/3much.schnickschnack.info:80/2much/VirtualHostRoot/$1 last;
location / {
proxy_pass http://cache;
}
}
How do I configure nginx to add a slash? (I think i should a rewrite rule?)
More likely I think you would want something like this:
rewrite ^([^.]*[^/])$ $1/ permanent;
The Regular Expression translates to:
"rewrite all URIs without any '.' in them that don't end with a '/' to the URI + '/'"
Or simply:
"If the URI doesn't have a period and does not end with a slash, add a slash to the end"
The reason for only rewriting URI's without dots in them makes it so any file with a file extension doesn't get rewritten. For example your images, css, javascript, etc and prevent possible redirect loops if using some php framework that does its own rewrites also
Another common rewrite to accompany this would be:
rewrite ^([^.]*)$ /index.php;
This very simply rewrites all URI's that don't have periods in them to your index.php (or whatever file you would execute your controller from).
rewrite ^([^.\?]*[^/])$ $1/ permanent;
to avoid querystrings of a rest url getting a / tagged on.
e.g.
/myrest/do?d=12345
For nginx:
rewrite ^(.*[^/])$ $1/ permanent;
Odd that this is the first result in Google, but doesn't have a satisfactory answer. There are two good ways to do this I know of. The first is to straight-up check if the request will hit a file and only apply a rewrite condition if not. E.g.
server {
# ...
if (!-f $request_filename) {
rewrite [^/]$ $uri/ permanent;
}
location / {
# CMS logic, e.g. try_files $uri $uri /index.php$request_uri;
}
# ...
}
The second, which many prefer as they'd rather avoid any use of if that isn't 100% necessary, is to use try_files to send the request to a named location block when it won't hit a file. E.g.
server {
# ...
location / {
try_files $uri $uri/ #cms;
}
location #cms {
rewrite [^/]$ $uri/ permanent;
# CMS logic, e.g. rewrite ^ /index.php$request_uri;
}
# ...
}
it's too late but I want to share my solution, I've met issue with trailing slash and nginx.
#case :
# 1. abc.com/xyz => abc.com/xyz/
# 2. abc.com/xyz/ => abc.com/xyz/
# 3. abc.com/xyz?123&how=towork => abc.com/xyz/?123&how=towork
# 4. abc.com/xyz/?123&ho=towork => abc.com/xyz/?123&how=towork
and this is my solution
server {
....
# check if request isn't static file
if ($request_filename !~* .(gif|html|jpe?g|png|json|ico|js|css|flv|swf|pdf|xml)$ ) {
rewrite (^[^?]+[^/?])([^/]*)$ $1/$2 permanent;
}
....
location / {
....
}
}
server {
# ... omissis ...
# put this before your locations
rewrite ^(/.*[^/])$ $1/ permanent;
# ... omissis ...
}
If you want some kind of requests (say other than GET ones) to be prevented from doing this (usually it's about POST requests, as rewrite turns any request method into GET, which may break some of your site's dynamic functionality), add an if clause:
server {
# ... omissis ...
# put this before your locations
if ($request_method = "GET" ) {
rewrite ^(/.*[^/])$ $1/ permanent;
}
# ... omissis ...
}
You can also put the rewrite in a location block (if too), to make it more specific.
using the rewrites from anthonysomerset in a Wordpress, I experimented problems accesing to /wp-admin dashboard due to reirection loop. But i solve this problem using the above conditional:
if ($request_uri !~ "^/wp-admin")
{
rewrite ^([^.]*[^/])$ $1/ permanent;
rewrite ^([^.]*)$ /index.php;
}
If nginx behind proxy with https, this snippet do correct redirect for $scheme
map $http_x_forwarded_proto $upstream_scheme {
"https" "https";
default "http";
}
server {
...
location / {
rewrite ^([^.\?]*[^/])$ $upstream_scheme://$http_host$1/ permanent;
}
...
}
And on the upstream proxy pass the X-Forwarded-Proto header like:
location / {
proxy_set_header X-Forwarded-Proto $scheme;
...
}
This rule solves query string case too:
location ~ ^/([^.]*[^/])$ {
if ($query_string) {
return 301 $scheme://$host/$1/?$query_string;
}
return 301 $scheme://$host/$1/;
}
The regex has taken from #marc's answer:
rewrite ^([^.\?]*[^/])$ $1/ permanent;
The extra slash ^/ in regex is added to improve readability
Try this: ^(.*)$ http://domain.com/$1/ [L,R=301]
This redirects (Status code 301) everything ($1) without a "/" to "$1/"