Using Rails 4.3. I have the following line in production.rb:
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
config.action_controller.asset_host = "https://assets.example.com"
And the following in example.conf nginx:
upstream example {
server unix:/home/deployer/example/shared/tmp/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name example.com;
client_max_body_size 4G;
keepalive_timeout 10;
error_page 500 502 503 504 /500;
root /home/deployer/example/current/public;
try_files $uri/index.html $uri.html $uri #example;
location #example {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://example;
}
location = /50x.html {
root html;
}
location = /404.html {
root html;
}
location #503 {
error_page 405 = /system/maintenance.html;
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html break;
}
rewrite ^(.*)$ /503.html break;
}
if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
return 405;
}
if (-f $document_root/system/maintenance.html) {
return 503;
}
}
I notice that my subdomain http://assets.example.com is the mirror of my main domain https://example.com, instead of just serving the assets. For example, https://assets.example.com/blog/1 is the same for https://www.example.com/blog/1.
How do I prevent that? I just want https://assets.example.com to serve static assets.
I think that you should split your nginx server section into two sections, one for the web, the other one for the static assets site.
The server section for the web should remain essentially the same as in your original post, it should perhaps just react on the full hostname:
server_name www.example.com;
The static site server section should be an amended copy of the main site section, with the following principal differences:
the server_name should contain assets.example.com
the section should contain NO proxy_pass directive, static assets are meant to be served statically, i.e. directly by nginx, without having to go through Rails
the root will be the same as in the main site
the asset files will be served directly from the root, relatively, so if there is /assets/ in your URLs (which there probably is), then the assets should be found and served directly from your public/assets physical directory.
Update: sample nginx configuration:
upstream example {
server unix:/home/deployer/example/shared/tmp/sockets/puma.sock fail_timeout=0;
}
# main site config
server {
listen 80;
server_name www.example.com;
client_max_body_size 4G;
keepalive_timeout 10;
error_page 500 502 503 504 /500;
root /home/deployer/example/current/public;
try_files $uri/index.html $uri.html $uri #example;
location #example {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://example;
}
location = /50x.html {
root html;
}
location = /404.html {
root html;
}
location #503 {
error_page 405 = /system/maintenance.html;
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html break;
}
rewrite ^(.*)$ /503.html break;
}
if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
return 405;
}
if (-f $document_root/system/maintenance.html) {
return 503;
}
}
server {
listen 80;
server_name assets.example.com;
client_max_body_size 4G;
keepalive_timeout 10;
root /home/deployer/example/current/public;
location = /404.html {
root html;
}
if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
return 405;
}
if (-f $document_root/system/maintenance.html) {
return 503;
}
}
Related
I am working on a Ruby on Rails project on an Ubuntu server. Whenever I try and access the app, I am always greeted with:
Welcome to nginx!
If you see this page, the nginx web server is successfully installed and working. Further configuration is required.
Here is my code from the "sites_enabled" directory:
pstream unicorn_site {
server unix:/tmp/unicorn.site.sock fail_timeout=0;
}
server {
listen 80;
client_max_body_size 4G;
keepalive_timeout 10;
error_page 500 502 504 /500.html;
error_page 503 #503;
server_name http://[ip_address];
root /data/site/current/public;
try_files $uri/index.html $uri #unicorn_site;
location #unicorn_site {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://unicorn_site;
# limit_req zone=one;
access_log /var/log/nginx/site.access.log;
error_log /var/log/nginx/site.error.log;
}
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location = /50x.html {
root html;
}
location = /404.html {
root html;
}
location #503 {
error_page 405 = /system/maintenance.html;
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html break;
}
rewrite ^(.*)$ /503.html break;
}
if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)){
return 405;
}
if (-f $document_root/system/maintenance.html) {
return 503;
}
}
I am not sure what the problem is as the app seems to have everything it need to be working correctly. I can provide any part of the code anyone needs. Help is much appreciated.
EDIT: I am also always getting this error when I attempt to load the page:
2018/06/15 15:39:10 [warn] 15280#0: server name "http://[ip_address]" has suspicious symbols in /etc/nginx/sites-enabled/site:14
EDIT 2: Here is nginx.conf
user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
worker_connections 768;
}
http {
##
# Basic Settings
##
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;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
##
# Gzip Settings
##
gzip on;
gzip_disable "msie6";
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
Move 'try_files $uri/index.html $uri #unicorn_site;' under location /
location / {
try_files $uri/index.html $uri #unicorn_site;
}
The server_name http://[ip_address]; looks wrong. try server_name example.com
Have you configured ruby_passenger line ?
Follow this carefully and your deployment should be successful
Choose your ubuntu version there and proceed
https://gorails.com/deploy/ubuntu/16.04
I've got a problem with proxying of subdomain's name from nginx to rails server. In my rails app I have links like tenant1.localhost:3000, tenant2.localhost:3000, etc. and it works fine. On production I use Nginx + Puma and nginx doesn't proxy to puma any request if I open link with subdomain.
nginx.conf
upstream puma_muninn {
server app:3000;
}
server {
listen 80;
client_max_body_size 4G;
keepalive_timeout 10;
error_page 500 502 504 /500.html;
error_page 503 #503;
server_name localhost puma_muninn;
server_name ~^(?<subdomain>.+)localhost$;
root /var/www/muninn/public;
try_files $uri/index.html $uri #puma_muninn;
location #puma_muninn {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://$subdomain.puma_muninn;
# limit_req zone=one;
access_log /var/www/muninn/log/nginx.access.log;
error_log /var/www/muninn/log/nginx.error.log;
}
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location = /50x.html {
root html;
}
location = /404.html {
root html;
}
location #503 {
error_page 405 = /system/maintenance.html;
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html break;
}
rewrite ^(.*)$ /503.html break;
}
if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
return 405;
}
if (-f $document_root/system/maintenance.html) {
return 503;
}
location ~ \.(php|html)$ {
return 405;
}
}
production.rb
config.action_dispatch.tld_length = 2
But as I said puma doesn't even get requests from nginx.
Any ideas?
A domain in nginx.conf has to be specific instead of localhost.
After adding SSL I have noticed a strange behaviour: All API POST requests using HTTP protocol in the address are being turned into GET requests and this is why I am getting ActionController::RoutingError (No route matches [GET] "/api/v2/users") error.
My nginx.conf:
upstream unicorn_staging.xxxxx.com {
server unix:/srv/www/xxxxx/shared/sockets/unicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name staging.xxxxx.com xxxxx dublin;
access_log /var/log/nginx/staging.xxxxx.com.access.log;
keepalive_timeout 5;
root /srv/www/xxxxx/current/public/;
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
# If you don't find the filename in the static files
# Then request it from the unicorn server
if (!-f $request_filename) {
proxy_pass http://unicorn_staging.xxxxx.com;
break;
}
}
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
deny all;
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /srv/www/xxxxx/current/public/;
}
}
server {
listen 443;
server_name staging.xxxxx.com xxxxx dublin;
access_log /var/log/nginx/staging.xxxxx.com-ssl.access.log;
ssl on;
ssl_certificate /etc/nginx/ssl/staging.xxxxx.com.crt;
ssl_certificate_key /etc/nginx/ssl/staging.xxxxx.com.key;
keepalive_timeout 5;
root /srv/www/xxxxx/current/public/;
location / {
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
# If you don't find the filename in the static files
# Then request it from the unicorn server
if (!-f $request_filename) {
proxy_pass http://unicorn_staging.xxxxx.com;
break;
}
}
error_page 500 502 503 504 /500.html;
location = /500.html {
root /srv/www/xxxxx/current/public/;
}
}
I am using Ruby on Rails, Nginx and unicorn. I have set force_ssl to true in rails so it automatically redirects all the requests to https.
Access log when using https:
[01/Apr/2016:08:58:28 +0000] "GET /api/v2/users HTTP/1.1" 404 15384 "-" "XxxxStaging/28 CFNetwork/758.2.8 Darwin/15.0.0"
Access log when using http:
[01/Apr/2016:09:00:08 +0000] "POST /api/v2/users HTTP/1.1" 201 1620 "-" "curl/7.43.0"
Using the websocket-rails gem, I'm able to successfully get a websocket connection straight through puma in development, however, when deployed to production and attempting to access the websocket through nginx (passing off to puma) I have a couple of errors: one in the nginx error log:
[info] 14340#0: *7 upstream timed out (110: Connection
timed out) while proxying upgraded connection, client: 123.45.67.89, server:
foo.com, request: "GET /websocket HTTP/1.1", upstream:
"http://unix:///opt/oneconnect/shared/tmp/sockets/puma.sock:/websocket", host:
"foo.com"
... and one on the javascript console:
WebSocket connection to 'ws://foo.com/websocket' failed: Error during WebSocket handshake: Unexpected response code: 301
I found that nginx (the version I'm using is 1.4.6) is capable of websocket use but requires special configuration, which I've already attemped (getting the errors above). Here's my nginx.conf:
upstream oneconnect {
server unix:///opt/oneconnect/shared/tmp/sockets/puma.sock;
}
server {
listen 80;
listen 443 ssl;
#ssl on;
ssl_certificate /etc/ssl/foo.com.crt;
ssl_certificate_key /etc/ssl/foo.com.key;
root /opt/oneconnect/current/public;
try_files $uri #oneconnect;
access_log /opt/oneconnect/current/log/nginx.access.log;
error_log /opt/oneconnect/current/log/nginx.error.log info;
server_name foo.com;
location ~ ^/(assets)/ {
root /opt/oneconnect/current/public;
gzip_static on;
expires max;
add_header Cache-Control public;
}
location /websocket/ {
proxy_pass http://oneconnect;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location #oneconnect {
proxy_read_timeout 300;
proxy_connect_timeout 300;
proxy_redirect off;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_pass http://oneconnect;
}
}
I'm assuming that I'm missing something simple, but I'm stumped at this point and have Googled until my eyes started bleeding. If anyone could help it would be much appreciated, or maybe just point me to how to debug these connections (it seems hard to get debug info from a ws connection). Thanks for your time.
Assuming u have already initializer for eventmachine
config/initializers/eventmachine.rb
Thread.new { EventMachine.run } unless EventMachine.reactor_running? && EventMachine.reactor_thread.alive?
nginx site conf:
upstream puma_project_production {
server unix:/var/www/project/shared/tmp/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
client_max_body_size 4G;
keepalive_timeout 10;
error_page 500 502 504 /500.html;
error_page 503 #503;
server_name localhost project.local;
root /var/www/project/current/public;
try_files $uri/index.html $uri #puma_project_production;
location #puma_project_production {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma_project_production;
# limit_req zone=one;
access_log /var/www/project/shared/log/nginx.access.log;
error_log /var/www/project/shared/log/nginx.error.log;
}
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location = /50x.html {
root html;
}
location = /404.html {
root html;
}
location #503 {
error_page 405 = /system/maintenance.html;
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html break;
}
rewrite ^(.*)$ /503.html break;
}
if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
return 405;
}
if (-f $document_root/system/maintenance.html) {
return 503;
}
location /websocket {
proxy_pass http://puma_project_production;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location ~ \.(php|rb)$ {
return 405;
}
}
simple question, How can I deploy my Rails Application into a port of my website? I know i can specify the port when running using Mongrel or Webrick, but this time, I have to deploy it into production. I think passenger can manage this but I dont know how. I tried search but still I can't find the solution. Please help :)
Thanks!
Follow-up:
I am using Ubuntu 10.04 LTS and my Passenger runs with Apache.
If you're using Passenger with Apache or nginx. It will use the default port, 80. You can change this in the config file based on which web server you use.
# HTTPS server
server {
listen 80;
listen 8080;
server_name *.host.com;
root /home/app/public_html/host_production/current/public;
error_page 500 502 504 /500.html;
location = /50x.html {
root html;
}
location = /404.html {
root html;
}
error_page 503 #503;
location #503 {
error_page 405 = /system/maintenance.html;
if (-f $document_root/system/maintenance.html) {
rewrite ^(.*)$ /system/maintenance.html break;
}
rewrite ^(.*)$ /503.html break;
}
try_files $uri /system/maintenance.html #passenger;
location #passenger {
passenger_enabled on;
passenger_min_instances 5;
rails_env production;
}
if ($request_method !~ ^(GET|HEAD|PUT|POST|DELETE|OPTIONS)$ ){
return 405;
}
if (-f $document_root/system/maintenance.html) {
return 503;
}
location ~ ^/(assets|images|javascripts|stylesheets|swfs|system)/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location ~ \.php$ {
deny all;
}
access_log /dev/null;
error_log /dev/null;
}
nginx+passenger config