nginx location directive - ruby-on-rails

I have an nginx server with a rails app.
my nginx.conf is
server {
listen 80;
server_name nerto.it;
root /var/www/current/public;
passenger_enabled on;
location /m {
passenger_enabled off;
index index.html index.php;
try_files $uri $uri/ /m/index.html?q=$uri;
}
...
}
It works except address like
nerto.it/mprove or nerto.it/mtry
where the initial letter is /m and nginx take this address like nerto.it/m
How can i solve it?

location /m/ {
passenger_enabled off;
index index.html index.php;
try_files $uri $uri/ /m/index.html?q=$uri;
}
or
location = /m {
...
}
It is unclear from your question what behaviour do you expect.
Please, read the documentation: http://nginx.org/r/location

I think you should try smth like this:
location ~* ^/m(.*) {
Regular expressions are specified by prepending them with the “~*” prefix (for case-insensitive matching), or with the “~” prefix (for case-sensitive matching).
nginx location directive

Related

How to rewrite clean url to .html in a nginx docker container?

I can run nginx in a Docker container, port 4000. It should serve a static website with the following structure:
/usr/share/nginx/html/
index.html
app.html
app/
some-other.html
The port was mapped to port 3000 on localhost. Now I am trying to use clean urls as following: http://localhost:3000/app. However, when I try to access this url it is redirecting me to http://localhost:4000/app/ (notice the suffixing /) with status code 301 - Moved Permanently.
I've tried using try_files in different locations and order (it's commented below). Nothing worked. In addition, I've also used a rewrite without success. Always resulting in the same redirect.
site.conf
server {
listen 4000;
server_name localhost;
root /usr/share/nginx/html;
# location / {
# index index.html
# try_files $uri $uri.html $uri/ =404;
# }
location / {
index index.html
try_files $uri #htmlext $uri/;
}
location ~ \.html$ {
try_files $uri =404;
}
location #htmlext {
rewrite ^(.*)$ $1.html last;
}
error_page 404 /404;
}
I'd expect nginx to return the content of app.html without touching the url in any form. Can't I do this without adding location /app too?

Nginx - Localhost port is lost when clicking on anchor links

I'm using Docker to run nginx on macOS to serve static files on http://localhost:8080.
When clicking on an anchor link, the port is being lost.
For example, clicking on <a href="/foo"> will link to http://localhost/foo instead of http://localhost:8080/foo.
My nginx config is:
server {
listen 80 default_server;
server_name _;
root /var/www/root;
index index.html index.php;
location ~ /\. {
deny all;
}
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}
error_page 404 /404.html;
location / {
try_files $uri $uri/ $uri.html =404;
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_pass php:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
}
}
The directory structure of /var/www/root is:
├── foo
│   └── index.html
├── bar
│   └── index.html
└── baz
└── index.html
However, when changing:
try_files $uri $uri/ $uri.html =404;
to:
try_files $uri/index.html $uri $uri/ $uri.html =404;
the anchor links link correctly.
However, the following does not work:
try_files $uri/ $uri $uri.html =404;
What is going on exactly? Is there a way to exclude $uri/index.html from try_files and have the anchor links preserve the port?
Update
This works, but I'm not quite sure why.
if (-d $request_filename) {
rewrite [^/]$ $scheme://$http_host$uri/ permanent;
}
location / {
try_files $uri $uri/ $uri.html =404;
}
I can't see the Dockerfile but I'm assuming you run the container with a port mapping of 8080:80. However, nginx is probably still sending the Host header with port 80 and the anchor tag uses that host given how the base URI is calculated:
User agents must calculate the base URI according to the following precedences (highest priority to lowest):
The base URI is set by the BASE element.
The base URI is given by meta data discovered during a protocol interaction, such as an HTTP header (see [RFC2616]).
By default, the base URI is that of the current document. Not all HTML documents have a base URI (e.g., a valid HTML document may appear in an email and may not be designated by a URI). Such HTML documents are considered erroneous if they contain relative URIs and rely on a default base URI.
Reference: https://www.w3.org/TR/html401/struct/links.html#edef-BASE
For development, it sounds like running the container with 8080:8080 should work. For production you might wanna set the appropriate server_name or Host header via an envvar.

Nginx 403: directory index of "/home/deploy/MyApp/current/public/" is forbidden

I have set up a rails project with nginx and passenger. I'm getting a 403 when trying to access the site. This is my config file at /etc/nginx/sites-enabled/mysite.com:
server {
listen 80;
server_name www.mysite.com *.mysite.com;
passenger_enabled on;
rails_env production;
root /home/deploy/mysite/current/public;
index index.html index.htm;
#try_files $uri;
# redirect server error pages to the static page /50x.html
error_page 500 502 503 504 /50x.html;
location / {
try_files $uri $uri/ /index.html;
}
location = /50x.html {
root html;
}
}
My passenger_root and passenger_ruby are correctly set in nginx.conf and I have set write/read permissions on the app's root/, root/current and root/current/public folders for the nginx user.
Any ideas? Thx in advance.
You need to specify these two options as well
passenger_root /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.9;
passenger_ruby /usr/local/rvm/wrappers/ruby-1.9.2-p290/ruby;
You can check the path of your passenger installation with
passenger-config --root
And Ruby version with
which ruby
compare these outputs with what you specify.

Nginx for multiple apps with different subdomain

Been trying to search for a time but can't seem to find a solution. I want to set multiple apps in one server via nginx. Current nginx.conf is as follows:
server {
listen 80;
server_name mydomain.co;
root /mydomain/current/public;
passenger_enabled on;
rails_env production;
}
server {
listen 80;
server_name testing.mydomain.co;
root /mydomain-test/current/public;
passenger_enabled on;
rails_env test;
}
It serves up the correct environment (test) but doesn't serve the correct codebase. I checked the directory mydomain-test via ssh and it contains the recent code but is not being served by nginx.
Basically, what I want is:
mydomain.co to serve /mydomain/current/public
testing.mydomain.co to serve /mydomain/current/public
How is this done correctly?
I believe the root directive should be in the location section. I am unsure of the rails directive and passenger_enabled directive but the rest is similar to what I use and works. Might be best to also specify the index script (i have it set to index.php but change as appropriate).
Once you have made the changes be sure to restart nginx.
server {
listen 80;
server_name mydomain.co;
location / {
root /mydomain/current/public;
index index.php;
}
passenger_enabled on;
rails_env production;
}
server {
listen 80;
server_name testing.mydomain.co;
location / {
root /mydomain-test/current/public;
index index.php;
}
passenger_enabled on;
rails_env test;
}

Deploying Rails with subdomains using capistrano to an nginx/unicorn setup -- how?

I've been following Ryan B's VPS deployment railscast:
http://railscasts.com/episodes/335-deploying-to-a-vps
nginx.conf file he suggest using doesn't work with subdomains. This is what he shows:
upstream unicorn {
server unix:/tmp/unicorn.blog.sock fail_timeout=0;
}
server {
listen 80 default deferred;
# server_name example.com;
root /home/deployer/apps/<app name>/current/public;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #unicorn;
location #unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
Does anyone know how to set things up to support subdomains?
You can uncomment line:
# server_name example.com;
replace example.com with your domain and add:
server_name example.com *.example.com;
or
server_name example.com blog.example.com;
Now all requests to domain and subdomains will go to the rails
It turns out (at least with linode.com), that handeling wildcard subdomains is pretty straight forward. You just need to add a * host to the A record.
Also, in nginix, what I did was replaced:
# server_name example.com;
with:
server_name localhost;
I'm not sure that's even needed.
My actual issue had nothing to do with either the host or nginx. My situation was that I was using a random hashed URL as a security token during registration (so a user can't hijack an existing subdomain), but the type of hash I was using had issues so I needed to modify it.
I wasn't seeing any errors, I was just being redirected back to the signup page -- as is the correct behavior when the hashed URL has problems / doesn't match.
Anyway, once I fixed that, the whole subdomain thing was a non-issue.
Hope this helps anyone else who uses hashed URLs, subdomains, and is generally new to deployment.
Cheers.

Resources