I have a VPS with a Rails 4 app running on Ubuntu with NginX and Unicorn.
Since I want all pages to be SSL secured, all requests to http:// are forwarded to https:// which is working fine.
This is my NginX configuration:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events { worker_connections 1024; }
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_types text/plain text/xml text/css text/comma-separated-values;
upstream app_server { server 127.0.0.1:8080 fail_timeout=0; }
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server {
listen 80;
server_name myapp.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
server_name myapp.com;
root /home/rails/public;
index index.htm index.html;
ssl on;
ssl_certificate /etc/ssl/myapp.com.crt;
ssl_certificate_key /etc/ssl/myapp.com.key;
location / {
try_files $uri/index.html $uri.html $uri #app;
}
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_pass http://app_server;
}
}
}
How can I make it that all requests to http://myapp.com and https://myapp.com are forwarded to https://www.myapp.com?
Thanks for any help.
You can go about this two ways:
In your Rails app, detect if the requested URI contains a www and give a 30(1|2) redirect based on that (probably easiest).
Create an additional vhost in Nginx listening on myapp.com and only have it do redirects to www.myapp.com.
server {
listen 443;
server_name myapp.com;
[add ssl config]
return 301 https://www.myapp.com$request_uri;
}
Related
I have installed nginx (version 1.6.3) on my amazon ec2 server with unicorn, Rails 4.2.0 and Ruby 2.1.3. Amazon load balancing is enabled on my system. The domain looks like abc.example.com. If no redirection code is written on nginx conf file, then both https://abc.example.com and http://abc.example.com seem working. But when I try to redirect all http requests to https, then sometimes it works for few seconds and then appear blank page, and sometimes it appears blank page from the beginning. Sometimes it shows 503 error too. The redirection code is:
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
My nginx conf file looks like this:
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
server {
listen 80;
listen 443 ssl;
client_max_body_size 4G;
server_name abc.example.com;
root '/var/www/html/example/public';
try_files $uri/index.html $uri.html $uri #unicorn;
location #unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded_Proto $scheme;
if ($http_x_forwarded_proto != 'https') {
rewrite ^ https://$host$request_uri? permanent;
}
proxy_redirect off;
proxy_pass http://unicorn;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /var/www/html/example/public;
}
}
}
So, how to resolve this issue?
Please move the redirection to its own block;
Can you please use this as your redirection:
server {
server_name domain.com.au;
server_tokens off;
return 301 https://$host$request_uri;
}
I prefer not to use IF Condition in Nginx unless I have to. See if this works if not we can work on it.
Also please remove listen 80; if everything suppose to go to ssl then you can forget port 80.
listen 443 default deferred;
try it and let me know if you need more help.
Can you please adjust this setting to fit yours then restart the Nginx:
upstream unicorn {
server unix:/tmp/unicorn.production_domain.sock fail_timeout=0;
}
server {
server_name domain.com;
server_tokens off;
return 301 https://$host$request_uri;
}
server {
listen 443 default deferred;
ssl on;
ssl_certificate /etc/ssl/SSL.crt;
ssl_certificate_key /etc/ssl/domain.com.key;
server_name domain.com.au;
root /var/www/public_html/production.domain.com;
access_log /var/www/public_html/production.domain.com/log/nginx.access.log;
error_log /var/www/public_html/production.domain.com/log/nginx.error.log ;
try_files $uri/index.html $uri #unicorn;
location #unicorn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn;
}
error_page 500 502 503 504 /public/500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
What do you have in your unicorn.rb?
I developed rails app and it's working on domain mpm.head-system.com
On my VPS the app is located in /home/mobile_market path.
This is nginx.conf:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events { worker_connections 1024; }
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_types text/plain text/xml text/css text/comma-separated-values;
upstream app_server {
server 127.0.0.1:8080 fail_timeout=0;
}
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
This is sites-enabled/default config:
server {
listen 80;
root /home/mobile_market/public/;
server_name mpm.head-system.com;
index index.htm index.html;
location / {
try_files $uri/index.html $uri.html $uri #app;
}
location ~* ^.+\.(jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|mp3|flv|mpeg|avi)$ {
try_files $uri #app;
}
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
Everything works fine, and now I have a new rails app (redmine) on the same VPS.
Now I setup redmine on the same VPS and it works on the 3000 port - mpm.head-system.com:3000
How can I change nginx.conf to setup my redmine app on subdomain like - redmine.head-system.com ?
How connect application, which running on other port, as subdomain? (because in /etc/hosts I can set IP without port only).
I know that I need to use proxy_pass and virtual host, but I don't know how :(
Please, help...
Add new confing file to /etc/nginx/sites-enabled: redmine.config
server {
listen 80;
root /home/redmine/;
server_name redmine.head-system.com;
index index.htm index.html;
location / {
try_files $uri/index.html $uri.html $uri #app;
}
location ~* ^.+\.(jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|mp3|flv|mpeg|avi)$ {
try_files $uri #app;
}
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://localhost:3000;
}
}
I just deployed my Rails 4 app on a VPS with Ubuntu, Unicorn and NginX.
For my app I need to use SSL, so I have this ApplicationController:
class ApplicationController < ActionController::Base
force_ssl
...
end
This is my nginx.conf:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events { worker_connections 1024; }
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_types text/plain text/xml text/css text/comma-separated-values;
upstream app_server { server 127.0.0.1:8080 fail_timeout=0; }
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server {
listen 80;
server_name myapp.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
server_name myapp.com;
root /home/rails/public;
index index.htm index.html;
ssl on;
ssl_certificate /etc/ssl/myapp.com.crt;
ssl_certificate_key /etc/ssl/myapp.com.key;
location / {
try_files $uri/index.html $uri.html $uri #app;
}
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_pass http://app_server;
}
}
}
Everything seems to be working OK. When a request for an http page comes, it gets forwarded to https, which is nice.
However, when trying to change the locale of the application in the browser (through the languages menu), I get this error message in the browser:
Safari can't open the page https://app_server/en/sessions/new
because Safari can't find the server "app server"
In the URL it also says: https://app_server/en/sessions/new
What am I missing here?
I am fairly new to NginX, so maybe someone can help me out here?
Any general advice on how to enhance my code is highly appreciated.
You're using proxy_pass http://app_server; which set Host header to app_server by default. Add proxy_set_header Host $host;, so your application will get right Host.
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $host;
proxy_redirect off;
proxy_pass http://app_server;
}
I am trying to get my Rails 4 working with SSL on a VPS with Ubuntu and NginX. I retrieved an SSL certificate from StartSSL.com and the installation on the server seems to have been successful.
However, I can't get my app to work with https. It only works with http at this moment.
When I try to access it in the browser through https I am getting this error:
2014/06/04 18:05:56 [error] 23306#0: *3 "/home/rails/public/index.html" is forbidden (13: Permission denied), client: 23.251.149.69, server: myapp.com, request: "GET / HTTP/1.0", host: "myapp.com"
This would be my NGINX configuration file in /etc/nginx/nginx.conf:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events { worker_connections 1024; }
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
server_names_hash_bucket_size 64;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_types text/plain text/xml text/css text/comma-separated-values;
upstream app_server { server 127.0.0.1:8080 fail_timeout=0; }
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
server {
listen 80;
server_name myapp.com;
rewrite ^ https://$server_name$request_uri? permanent;
}
server {
listen 443;
server_name myapp.com;
root /home/rails/public;
ssl on;
ssl_certificate /etc/ssl/myapp.com.crt;
ssl_certificate_key /etc/ssl/myapp.com.key;
}
}
What am I missing here and how can this be fixed?
I answered this over on DigitalOcean, but I noticed it here too.
You have an upstream set but no proxy_pass. I assume you're using something like Unicorn to serve the app? You probably need to adjust the server block listening on 443 to act as a reverse proxy for what ever is acting as an upstream server. Something like:
server {
listen 443;
server_name myapp.com;
root /home/rails/public;
index index.htm index.html;
ssl on;
ssl_certificate /etc/ssl/myapp.com.crt;
ssl_certificate_key /etc/ssl/myapp.com.key;
location / {
try_files $uri/index.html $uri.html $uri #app;
}
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
I'm hosting an API for a mobile app developed in Rails 4 on DigitalOcean using the One-Click Ubuntu 12.10 Installation droplet. Therefore nginx and Unicorn are preconfigured and running. When I try to open a file from Rails public folder on my web browser, it works.
But when I try to use any of the other paths defined in the routes.rb file I don't get any answer. My requests are loading until they time out. This changes when I type rails s -e production on the server – then everything works as expected. Therefore it must be a problem with nginx or something. What am I missing?
Here's my nginx sites-enabled/default file content (I don't know if that's the thing to look for, but maybe):
server {
listen 80;
root /home/rails/public;
server_name _;
index index.htm index.html;
location / {
try_files $uri/index.html $uri.html $uri #app;
}
#location ~* ^.+\.(jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|mid$
location ~* ^.+\.(jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rt$
try_files $uri #app;
}
location #app {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://app_server;
}
}
UPDATE: Here is my nginx.conf file in case this helps:
user www-data;
worker_processes 4;
pid /var/run/nginx.pid;
events { worker_connections 1024; }
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip on;
gzip_disable "msie6";
gzip_types text/plain text/xml text/css text/comma-separated-values;
upstream app_server { server 127.0.0.1:8080 fail_timeout=0; }
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
UPDATE 2: And here my unicorn.conf file:
listen "127.0.0.1:8080"
worker_processes 2
user "rails"
working_directory "/home/rails"
pid "/home/unicorn/pids/unicorn.pid"
stderr_path "/home/unicorn/log/unicorn.log"
stdout_path "/home/unicorn/log/unicorn.log"
I had the same issue and running bundle install on the root of my app (on digitalocean droplet) resolved my issue. I think I have to build that into my capistrano script