Nginx Several projects in different directories - nginx

first of all apologies for my English, since it is not very good. I am a novice in nginx and I have a fundamental doubt:
What is the easiest way to serve several projects with nginx (separated in different directories), using a single machine, with the same ip and same port?
example.com/project1
example.com/project2
example.com/project3
A cordial greeting.

You will want several location directives inside a single server block to do what you need to do for each project. What goes inside of the location directives really depends on the type of projects they are. I have some WordPress instances, for example, that would have fastcgi config lines inside of those location directives.
Example:
server {
listen 80;
server_name example.com;
location /project1 {
# What goes here depends on what type of project this is.
}
location /project2 {
# What goes here depends on what type of project this is.
}
location /project3 {
# What goes here depends on what type of project this is.
}
}

Related

Add child-site to path of parent site in Nginx

In the interests of keeping my codebase modular, I have two static websites - site_a, which is the parent site, and site_b, which may be considered a child site. I am trying to find the right way to append site_b to a path of site_a, such that site_a/path is equivalent to the site_b's / directory.
Note that each site instance has its own set of static resources (img, css, js), and should be referenced from the corresponding web directory on the server, and there may be some overlap in the names of some of the resources (eg. style.css) and folders (eg. /img/..).
Any pointers of help would be very much appreciated!
What you are searching is a proxy_pass (Or I think it would work in your case).
site_a configuration:
location = /path {
return 301 /path/;
}
location = /path/ {
proxy_pass http://site_b/;
}
This should work if you only want it to be exactly like this, be careful, because the /path part is changed by / , but if you need the rest of the url, you could do:
location = /path {
return 301 /path/;
}
location /path/ {
proxy_pass http://site_b/;
}
Like this, site_a/path/pathtoglory/ would show site_b/pathtoglory/.
Choose whichever you like the most (or fits your actual situation).
Any more info on proxy_pass for special configurations can be found here:
https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/

select server block based on existence of certain query parameters

I have a single page application, I want to make it crawlable so I have generated snapshots. My application stack is rails + unicorn + nginx(as reverse proxy).
Now, Aws Opsworks generates a nginx config from this cookbook. I ssh-ed into the system & modified the default config to include the following lines to redirect all requests from search engine bots as follows(they convert the url which contains #! & send a new request with _escaped_fragment_ in query parameters):
if ($args ~ "_escaped_fragment_=(.+)") {
rewrite ^ /snapshots$uri$1?;
}
Everything worked great when I loaded the url in the browser. The issue I am facing is with automating the same thing using chef. Since the code I added was in the config file generated using default cookbook by opsworks, I need a way to define a nginx server block to achieve this. So, I defined the following server block.
server {
listen 80;
server_name example.com;
if ($args ~ "_escaped_fragment_=(.+)") {
set $foo $1;
rewrite ^ /snapshots$uri$foo?;
}
}
But nginx will never select this block given there already exists another server block with the same server_name. So, is there a way that I can define a server block to be selected by nginx based on the existence of _escaped_fragment_ in the $args ?
Something as follows(I know this won't work since regex doesn't match query parameters)
server {
listen 80;
server_name example.com(.+)_escaped_fragment_=(.+);
...
}
In order to do this in chef, you need to create a custom cookbook (if you don't have one already) and a recipe in it which would overwrite the opsworks generated file with your preferred file. In the cookbook you'd need 2 files, nginx template and a recipe to overwrite the default template with the custom one:
mycookbook -> templates -> default -> custom_nginx.erb
mycookbook -> recipes -> customise_nginx.rb
Content of (1):
whatever you want your nginx config file to be, so:
server {
listen 80;
server_name example.com;
if ($args ~ "_escaped_fragment_=(.+)") {
set $foo $1;
rewrite ^ /snapshots$uri$foo?;
}
}
Content of (2):
template "/etc/nginx/sites-enabled/<nginx file name>" do
source "custom_nginx.erb"
user "root"
group "root"
mode "644"
end
service "nginx" do
action :reload
end
Then add mycookbook::customise_nginx to the custom setup recipe section in your layer settings.
If you don't have a custom cookbook already, a bit more set up will be needed:
https://www.digitalocean.com/community/tutorials/how-to-create-simple-chef-cookbooks-to-manage-infrastructure-on-ubuntu
http://docs.aws.amazon.com/opsworks/latest/userguide/workingcookbook-installingcustom-enable.html
Edit:
If you want to keep opsworks config file, you have two options: to take the template that opsworks is using, I'm guessing this one? https://github.com/aws/opsworks-cookbooks/blob/release-chef-11.10/nginx/templat‌​es/default/site.erb, create a copy and put your changes there in file 1 as above. Or use chef to modify the existing file content - for example using FileEdit library (check the second answer to this question)

Config for Enabling SSI nginx?

I want to do server side include and i have nginx server installed in my machine and i cant find a way to enable ssi in nginx.conf file?
all i can find from the internet is
syntax: ssi on | off;
default:
ssi off;
context: http, server, location, if in location
Enable ssi on the location context. In my case i want it on root
location / {
ssi on;
}
It looks like you were having the same problem I was having; finding a crystal clear explanation of how to enable SSI on NGINX. Crystal Clear entails not just which syntax to use, but the format, and exactly where to include it. I figured it out and it's not that difficult, but the lack of clear instructions on the internet was frustrating.
You'll need to open up the nginx.conf file and look for the section that is formatted as follows (I've included the 'ssi on' syntax as well):
location / {
root E:\website\FinalJRLWeb;
index index.html index.shtml;
ssi on;
}
It took me a bit to realize the location, but it's really as simple as adding the line 'ssi on' right underneath the specified index file names (and it should be able to really go anywhere you'd like, I don't imagine the order matters, just as long as it's within the two brackets {}).
After that, to verify that SSI is working on your NGINX server, add the following line anywhere in the 'body' tag of a blank html page
<!--#echo var="DATE_LOCAL" -->
and save it with the extension .shtml in your web server's root directory.
You should see the server's local date and time displayed upon visiting your page. I realize this is almost a year old, but after my frustration trying to find clear instructions, I wanted to do my best to try and provide clear instructions for anyone else that may need them. So hopefully this will help someone out!
Here's NGINX's documentation page on SSI (which honestly was not helping me as much as I would have liked, but it nonetheless is useful, and can only become more and more useful)
http://nginx.org/en/docs/http/ngx_http_ssi_module.html#ssi_last_modified
By default ssi is only apply to the text/html MIME Type; which might offer you frustration, though clearly documented here http://nginx.org/en/docs/http/ngx_http_ssi_module.html#ssi_types
you may need to add
ssi on;
ssi_types *; # Or something more specific
Enabling SSI on NGINX for a single domain
To enable SSI for just one domain (limiting possible security holes), you can add it as follows to the .conf file for that domain - in Debian these are (controversially for some) stored in the Apache-like system under "etc/nginx/sites-available".
server {
server_name mydomain.com;
root /home/username/html;
index index.html index.shtml;
location / {
ssi on;
...otherstuffhere
}
}
The crucial parts:
index index.html index.shtml;
ssi on;

How to make nginx to stop processing other rules and serve a specific location?

I have this config that works as expected in an empty server { } definition
location ^~ /foo/ {
alias /var/www/foo/;
}
But when I move this in a considerably bigger server definition (one used for a WordPress multi-site config), it will stop working and wordpress will respond to it (which obviously was not my intent).
I tried to put at the begining or end of server block, but this didn't change it.
How can I force Nginx to use this location?
You are probably looking for break.
location ^~ /foo/ {
alias /var/www/foo/;
break;
}
From the HttpRewriteModule documentation:
last - completes processing of current rewrite directives and
restarts the process (including rewriting) with a search for a match
on the URI from all available locations.
break - completes processing of current rewrite directives and
non-rewrite processing continues within the current location block
only.
Note that outside location blocks, last and break are effectively the
same.
Location blocks in Nginx are exclusive. If you use location ^~ then other rules probably expiry headers for static objects will not apply unless you copy those rules as nested under the same location block.
If you could share your full config then I can make it work for you. Most likely you need to use nested location blocks.
location = /aliasname/ {
alias /path/to/alias/
}
Trailing slash will be a problem if it is not present in URI.
See https://www.digitalocean.com/community/tutorials/understanding-nginx-server-and-location-block-selection-algorithms#matching-location-blocks

How to disable Nginx index directory to only allow MaxCDN / NetDNA CDN?

I have a very large CDN purge server. It is structured like so
site.com/
site.com/assets/
site.com/assets/products/3424/imgs/large.jpg
site.com/assets/products/3424/imgs/med.jpg
site.com/assets/products/3424/imgs/small.jpg
site.com/assets/products/3424/xml/xml.xml
site.com/assets/products/3424/swf/swfvideo.jpg
site.com/assets/products/3424/html5/video.ogg
site.com/assets/products/3424/mp3/mp3.jpg
and so on.. there are large directories. I was wondering if I can disable ALL access to the directory listings /assets/, /products/, /3424/ - so basically the only people that can see the directories are the CDN purge bot. I want the CDN to be able to cache all the index folders and directories. Users would see forbidden on the directory but obviously they can see files..
I believe this can be accomplished by simply adding lines similar to this in the virtual server's config file:
server {
listen 80; # look familiar?
...
# something similar to this
if ($remote_addr != cdnIP) {
location /assets {
deny all;
}
}
}
Check out the configuration wiki on nginx's site for more about syntax and working with the config files to get them just how you want them.

Resources