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;
}
Related
I have two docker container of my 2 different net core API project running on my machine (Linux) on respective ports 3333:80 and 6666:8088. I have deployed their front end part on Nginx server each having its own configuration in sites-available folder.
The problem is that my 1st container (API) is working fine, getting response from front end application as well as from Postman but the 2nd container is not working, throwing this error HTTP 502 bad gateway and error msg:
recv() failed (104: Connection reset by peer) while reading response header from upstream
What's wrong over here? Kindly help me to resolve this issue. Following are my config files:
nginx.conf:
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Basic Settings
##
client_max_body_size 50M;
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;
site1.conf
server {
listen 80 default_server;
server_name _;
root /var/www/app.admin-crm.com;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:3333/api/;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded_Host $server_name;
add_header Access-Control_Allow-Credentials true;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
client_max_body_size 50M;
}
location / {
try_files $uri $uri/ /index.html;
}
}
site2.conf:
server {
listen 8088 default_server;
server_name _;
root /var/www/stilaar-web;
index index.html;
location /api/ {
proxy_pass http://127.0.0.1:6666/api/;
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded_For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded_Host $server_name;
add_header Access-Control_Allow-Credentials true;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
client_max_body_size 50M;
}
location / {
try_files $uri $uri/ /index.html;
}
}
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 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;
}
Ok, so I have pretty much the standard nginx config for serving a unicorn rails server (listens to a socket file and also serves static files from the rails_app/public directory).
However, I want to do the following:
serve static files from
rails_app/public (as currently is
done)
serve static files with url /reports/ from a different root (like /mnt/files/)
I tried adding the following to my nginx config:
location /reports/ {
root /mnt/matthew/web;
}
but it didn't work.
Any ideas how I can get this to happen?
(below is my entire nginx.conf file:
worker_processes 1;
pid /tmp/nginx.pid;
error_log /tmp/nginx.error.log;
events {
worker_connections 1024; # increase if you have lots of clients
accept_mutex off; # "on" if nginx worker_processes > 1
# use epoll; # enable for Linux 2.6+
# use kqueue; # enable for FreeBSD, OSX
}
http {
# nginx will find this file in the config directory set at nginx build time
include mime.types;
# fallback in case we can't determine a type
default_type application/octet-stream;
# click tracking!
access_log /tmp/nginx.access.log combined;
sendfile on;
tcp_nopush on; # off may be better for *some* Comet/long-poll stuff
tcp_nodelay off; # on may be better for some Comet/long-poll stuff
gzip on;
gzip_http_version 1.0;
gzip_proxied any;
gzip_min_length 500;
gzip_disable "MSIE [1-6]\.";
gzip_types text/plain text/html text/xml text/css
text/comma-separated-values
text/javascript application/x-javascript
application/atom+xml;
# this can be any application server, not just Unicorn/Rainbows!
upstream app_server {
server unix:/home/matthew/server/tmp/unicorn.sock fail_timeout=0;
}
server {
# enable one of the following if you're on Linux or FreeBSD
listen 80 default deferred; # for Linux
# listen 80 default accept_filter=httpready; # for FreeBSD
client_max_body_size 4G;
server_name _;
keepalive_timeout 5;
location /reports/ {
root /mnt/matthew/web;
}
# path for static files
root /home/matthew/server/public;
try_files $uri/index.html $uri.txt $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;
}
# Rails error pages
error_page 500 502 503 504 /500.html;
location = /500.html {
root public;
}
}
}
location #app is looking for the files in /home/matthew/server/public, as that's the parent root specified. If your try files statement is matching files in location /reports/ that has a different root, those files won't be found. You need to set things up like this:
location /reports/ {
root /mnt/matthew/web;
try_files $uri/index.html $uri.txt $uri.html $uri #foo;
}
root /home/matthew/server/public;
try_files $uri/index.html $uri.txt $uri.html $uri #app;
location #foo {
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;
root /mnt/matthew/web
}
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;
}