Have deployed my Rails 5.2 app via Capistrano, and am having problems with ActionCable. I am using Nginx, Puma and Lets Encrypt.
I have tried many combinations of configuration, but each time am receiving the same error. I am not sure how to debug this issue, and suggestions as well and any tips on re-arranging my ngnx.conf would be well-appreciated.
Have changed the real website to website.com
nginx.conf
upstream puma {
server unix:///home/deploy/apps/website/shared/tmp/sockets/website-puma.sock;
}
server {
server_name website.com www.website.com;
root /home/deploy/apps/website/current/public;
index index.html;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #puma;
location #puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
location /cable {
proxy_pass http://puma;
proxy_http_version 1.1;
proxy_set_header Upgrade websocket;
proxy_set_header Connection Upgrade;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 10M;
keepalive_timeout 10;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/website.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/website.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.website.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = website.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name website.com www.website.com;
return 404; # managed by Certbot
}
config/production.rb
config.action_cable.mount_path = '/cable'
config.action_cable.url = 'wss://website.com/cable'
config.action_cable.allowed_request_origins = [ 'https://website.com', 'http://website.com' ]
Error Message
Reviewed posts
Rails5 Action Cable Nginx 404 and 502 errors
ActionCable on AWS: Error during WebSocket handshake: Unexpected response code: 404
Actioncable Nginx and Puma WebSocket handshake: Unexpected response
UPDATE
Updated nginx.conf
upstream puma {
server unix:///home/deploy/apps/immersive/shared/tmp/sockets/immersive-puma.sock;
}
server {
if ($host = www.immersive.ch) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = immersive.ch) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
server_name immersive.ch www.immersive.ch;
return 404; # managed by Certbot
}
server {
server_name immersive.ch www.immersive.ch;
root /home/deploy/apps/immersive/current/public;
index index.html;
location ^~ /assets/ {
gzip_static on;
expires max;
add_header Cache-Control public;
}
try_files $uri/index.html $uri #puma;
location #puma {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_pass http://puma;
}
location /cable {
proxy_pass http://puma;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_request_headers on;
proxy_buffering off;
proxy_redirect off;
break;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 10M;
keepalive_timeout 10;
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/immersive.ch/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/immersive.ch/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
production.rb
config.action_cable.mount_path = '/cable'
config.action_cable.url = 'wss://immersive.ch/cable'
config.action_cable.allow_same_origin_as_host = true
config.action_cable.allowed_request_origins = [ '*' ]
#config.action_cable.allowed_request_origins = [ 'https://immersive.ch', 'http://immersive.ch' ]
Partial output of curl
> GET /cable HTTP/1.1
> Host: immersive.ch
> User-Agent: curl/7.54.0
> Accept: */*
> Origin: https://immersive.ch
> Sec-WebSocket-Key: MIN4DsiwEAutsE11kgG5rg==
> Upgrade: websocket
> Connection: Upgrade
> Sec-WebSocket-Version: 13
>
< HTTP/1.1 404 Not Found
< Server: nginx/1.15.5 (Ubuntu)
< Date: Tue, 16 Apr 2019 20:10:43 GMT
< Content-Type: text/plain
< Transfer-Encoding: chunked
< Connection: keep-alive
< Cache-Control: no-cache
< X-Request-Id: 7a9aa8f1-676d-419b-9e4f-0c1bb38bcaa2
< X-Runtime: 0.004730
<
* Connection #0 to host immersive.ch left intact
Page not found%
puma.rb
threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }.to_i
threads threads_count, threads_count
port ENV.fetch("PORT") { 3000 }
environment ENV.fetch("RAILS_ENV") { "development" }
workers 2
daemonize true
plugin :tmp_restart
EDIT 2
/var/logs/nginx/access.log
HTTP/1.1" 200 4447 "https://immersive.ch/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
xxx.xxx.xxx.xxx - - [16/Apr/2019:22:33:58 +0200] "GET /cable HTTP/1.1" 404 24 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
xxx.xxx.xxx.xxx - - [16/Apr/2019:22:33:59 +0200] "GET /cable HTTP/1.1" 404 24 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36"
puma.error.log
I, [2019-04-16T22:39:06.100106 #21136] INFO -- : [80dc2a43-13e1-499e-a8f6-9fd54d48270b] Started GET "/cable" for xxx.xxx.xxx.xxx at 2019-04-16 22:39:06 +0200
I, [2019-04-16T22:39:06.103811 #21136] INFO -- : [80dc2a43-13e1-499e-a8f6-9fd54d48270b] Started GET "/cable/"[non-WebSocket] for xxx.xxx.xxx.xxx at 2019-04-16 22:39
E, [2019-04-16T22:39:06.103943 #21136] ERROR -- : [80dc2a43-13e1-499e-a8f6-9fd54d48270b] Failed to upgrade to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: close, HTTP_UPGRADE: )
I, [2019-04-16T22:39:06.104062 #21136] INFO -- : [80dc2a43-13e1-499e-a8f6-9fd54d48270b] Finished "/cable/"[non-WebSocket] for xxx.xxx.xxx.xxx at 2019-04-16 22:39
puma.access.log
2019-04-16 20:58: HTTP parse error, malformed request (127.0.0.1): #<Puma::HttpParserError: Invalid HTTP format, parsing fails.>
ActionCable answers 404 when Origin header is missing or does not match/invalid.
Check that it's not you regular 404:
curl -v 'https://your_site.com/cable' -H 'Origin: https://your_site.com' -H 'Sec-WebSocket-Key: MIN4DsiwEAutsE11kgG5rg==' -H 'Upgrade: websocket' -H 'Connection: Upgrade' -H 'Sec-WebSocket-Version: 13'
When everything is fine there'll be HTTP/1.1 101 Switching Protocols, on origin mismatch - just Page not found body, or your regular 404 page if there's some other routing trouble.
Make sure allowed_request_origins in settings is correct. Note that it includes port, if it's non-standard. Check which Origin browser sends in devtools
Also there's config.action_cable.allow_same_origin_as_host = true (the default, needs correct Host and X-Forwarded-Proto headers)
Then we need nginx to pass all the headers that are being used to reconstruct origin:
location /cable {
proxy_pass http://puma;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme; # <- most probably this one is missing
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass_request_headers on; # this is default, but just to be sure
proxy_buffering off;
proxy_redirect off;
break;
}
Update:
Remaining two cases when activecable responds with this is failed connection authentication and missing websocket driver(should not be the case for puma)
Related
I have Nginx server with domain name example.com and it servers
location / => for web, running docker at port 8080
location /api => for API, running docker at port 8090
There is another backend service running in docker at port 9000, which wants to call the API https://example.com/api ... If I try it as localhost:8090 then no issue.
But using https://example.com/api via Nginx returns 301 Moved permanent error.
That is, calling from the same system to Nginx is not working.
Not sure what is wrong.
Please find the nginx conf:
map $sent_http_content_type $expires {
default off;
text/html epoch;
text/css max;
application/javascript max;
~image/ max;
}
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
include /etc/nginx/conf.d/*.conf;
server {
listen [::]:443 ssl http2 ipv6only=on; # managed by Certbot
listen 443 ssl http2; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
index index.html index.htm index.nginx-debian.html;
server_name example.com;
location / {
proxy_pass http://localhost:8080/;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_set_header X-NginX-Proxy true;
}
location /api/v1/socketio/ {
proxy_pass http://lb_autosys_api/socket.io/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
location /api/v1/ {
proxy_pass http://localhost:8090/;
}
gzip on;
gzip_types text/plain application/javascript application/x-javascript text/javascript text/xml text/css;
gzip_min_length 1000;
gunzip on;
gzip_vary on;
expires $expires;
}
server {
if ($host = example.com) {
return 301 https://$host$request_uri;
}
listen 80 default_server;
listen [::]:80 default_server;
server_name example.com;
return 301 https://$host$request_uri;
}
I have a rails 6 app with /cable websocket and nginx reverse proxy
I put same config as another server (who works fine) :
in production.rb
config.action_cable.url = 'wss://domain.fr:8001/cable'
config.action_cable.allowed_request_origins = ['https://domain.fr', 'http://domain.fr']
config.action_cable.mount_path = '/cable'
in routes :
mount ActionCable.server => '/cable'
in JS :
ActionCable.createConsumer 'wss://domain.fr:8001/cable'
in proxy :
server {
listen 443 ssl http2;
server_name domain.fr;
if ($host ~ '^www\.') { return 301 https://domain.fr$request_uri; }
ssl_certificate /etc/letsencrypt/live/domain.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.fr/privkey.pem;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/domain.fr/fullchain.pem;
ssl_session_timeout 5m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_dhparam /home/liberty/dhparams.pem;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-Proto https;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Forwarded-Ssl on; # Optional
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host $host;
location / {
proxy_pass http://127.0.0.1:90;
}
location /cable {
proxy_pass http://127.0.0.1:8001;
}
access_log /var/log/rsh_proxy.access.log;
error_log /var/log/rsh_proxy.error.log;
location ~*^.+(swf|jpg|jpeg|gif|png|ico|css|zip|tgz|gz|rar|bz2|doc|xls|exe|pdf|ppt|txt|tar|mid|midi|wav|bmp|rtf|js)$ {
proxy_pass http://127.0.0.1:90;
proxy_cache cache;
proxy_cache_valid 9999d;
expires max;
}
}
in vhost :
server {
listen 8001 default_server;
listen [::]:8001 default_server ipv6only=on;
server_name domain.fr;
root /var/www/domain/public;
passenger_enabled on;
passenger_app_group_name MYAPP_action_cable;
passenger_app_type rack;
passenger_startup_file cable/config.ru;
passenger_force_max_concurrent_requests_per_process 0;
access_log /var/log/rsh_cable.access.log combined;
error_log /var/log/rsh_cable.error.log;
}
I try restart nginx but nothing new
the error in chrome console :
WebSocket connection to 'wss://domain.fr:8001/cable' failed: Error in connection establishment: net::ERR_SSL_PROTOCOL_ERROR
PS : port in firewall as open ;)
EDIT : exemple of log in /var/log/rsh_cable.access.log :
37.170.142.84 - - [29/Jul/2020:02:34:13 +0200] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03\x9F\x19\x1E\xA7\x96\xDBC\x98\x92\xCC.<S\xBC\x02\x04Jd\xB4M\x03uK\xA8\x1D\xEE\x0B\x96\xA2]\x1A\xD6 \x08\x1C\xC73/f\x8CaA\xFD/\xAA\xFE\xC1\xCB\x9A+\x9A(8)\xD7\xE1\xB8nR\x15!\x99\xD4^\xEA\x00\x22\x9A\x9A\x13\x03\x13\x01\x13\x02\xCC\xA9\xCC\xA8\xC0+\xC0/\xC0,\xC00\xC0\x13\xC0\x14\x00\x9C\x00\x9D\x00/\x005\x00" 400 157 "-" "-"
37.170.142.84 - - [29/Jul/2020:02:34:17 +0200] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03" 400 157 "-" "-"
37.170.142.84 - - [29/Jul/2020:02:34:32 +0200] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03Y\xBD\x08i\x1D\x9C\x83{\x0B\xE3\x9E\x02P\x99\xBDJ#\xD5\xFB50\x17 T\x10\xB3\x09O\xFA9\x07: \xEE\x1A\xE9x\xC3oI\xE1\xB7b\x5C\xD3\xF8\xE1\x03\xF0\x86(\xAB\xB1\xB9\xEA=d\x19\xB0ul\x8D\xF0\xED\x8B\x00 \xDA\xDA\x13\x03\x13\x01\x13\x02\xCC\xA9\xCC\xA8\xC0+\xC0/\xC0,\xC00\xC0\x13\xC0\x14\x00\x9C\x00\x9D\x00/\x005\x01\x00\x01\x93\x9A\x9A\x00\x00\x00\x00\x00\x0E\x00\x0C\x00\x00\x09domain.fr\x00\x17\x00\x00\xFF\x01\x00\x01\x00\x00" 400 157 "-" "-"
37.170.142.84 - - [29/Jul/2020:02:34:32 +0200] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03\xA30O\xF7\xF0\x09" 400 157 "-" "-"
37.170.142.84 - - [29/Jul/2020:02:34:54 +0200] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03\x97\x04b" 400 157 "-" "-"
37.170.142.84 - - [29/Jul/2020:02:34:54 +0200] "\x16\x03\x01\x02\x00\x01\x00\x01\xFC\x03\x03\xEAx\x19\x0Bg\xEB:E\x13x\x87WVd\xD4\xCFXA-\xD4\x09v\x17\xCC\xA4x\x19xP\xCA\xAB\xD8 )\x07+\xF4\xFA=U\xB1z\xDE\xD9\x1D\x11\xCFE\xF3\x97/\xC1y!\xE7u\xE68#&\xD7\xCF\xEB\xB5\x90\x00 JJ\x13\x03\x13\x01\x13\x02\xCC\xA9\xCC\xA8\xC0+\xC0/\xC0,\xC00\xC0\x13\xC0\x14\x00\x9C\x00\x9D\x00/\x005\x01\x00\x01\x93JJ\x00\x00\x00\x00\x00\x0E\x00\x0C\x00\x00\x09domain.fr\x00\x17\x00\x00\xFF\x01\x00\x01\x00\x00" 400 157 "-" "-"
In config you should specify final actioncable url that is going to be accessible by the end user.
Since you're using additional proxy - that is going to be wss://www.domain.fr/cable, and your port 8001 should be closed in firewall for everything except the proxy, since it's not ssl-terminated (hence the ssl error)
Also make sure that http 1.1 is correctly proxied with necessary headers:
location /cable {
proxy_pass http://127.0.0.1:8001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# not always needed, but in some setups can be necessary:
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-By $server_addr:$server_port;
proxy_set_header X-Real-IP $remote_addr;
}
I'm trying to connect to an ActionCable websocket and everything works fine running locally with just Puma and without nginx.
However, when I try to do the exact same thing on my staging environment, the connection is immediately closing after connecting. I am able to get the downstream welcome messages and maybe a ping.
However, the connection abruptly closes without any of the onClose callbacks so my guess is nginx is not letting the connection persist.
Here is my sites nginx configuration.
upstream app {
# Path to Puma SOCK file, as defined previously
server unix:/home/deploy/my-app/shared/tmp/sockets/puma.sock fail_timeout=60;
keepalive 60;
}
server {
listen 80;
server_name localhost;
# websocket_pass websocket;
root /home/deploy/my-app/current/public;
try_files $uri/index.html $uri #app;
location #app {
proxy_pass http://app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
#location / {
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header Host $host;
# proxy_redirect off;
# proxy_http_version 1.1;
# proxy_set_header Connection '';
# proxy_pass http://app;
#}
location ~ ^/(assets|fonts|system)/|favicon.ico|robots.txt {
gzip_static on;
expires max;
add_header Cache-Control public;
}
location /cable {
proxy_pass http://app;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
I also found this error in nginx error logs:
2019/02/11 21:08:35 [error] 10233#10233: *2 recv() failed (104: Connection reset by peer) while proxying upgraded connection, client: x.x.x.x, server: localhost, request: "GET /cable/ HTTP/1.1", upstream: "http://unix:/home/deploy/wr-api/shared/tmp/sockets/puma.sock:/cable/", host: "x.x.x.x"
So after some time, we noticed that the staging environment cable.yml had this value for url:
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
Removing that value and all other values except for adapter: staging fixed it for us.
New cable.yml staging config:
staging:
adapter: redis
Working!
Hello I am trying to setup a reverse proxy with nginx and docker container rails app, public static files are served correctly but can not access to my app. the nginx error log says:
2018/12/08 16:46:45 [error] 4093#4093: *350 could not find named location "#puma", client: xx.xxx.xxx.xx, server: my.app, request: "GET /en/users/sign_in HTTP/2.0",host: "my.app", referrer: "https://my.app/"
my nginx config is this:
upstream puma {
server 0.0.0.0:3000;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name my.app;
root /var/www/myapp/public;
# SSL
ssl_certificate /etc/letsencrypt/live/my.app/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my.app/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/my.app/fullchain.pem;
include snippets/letsencrypt.conf;
include snippets/ssl.conf;
# reverse proxy
location / {
proxy_pass http://puma; # => http://0.0.0.0:3000
proxy_set_header Host $http_host; # => $host
proxy_set_header X-Forwarded-Proto $scheme; # => "https"
proxy_set_header X-Forwarded-Host $host; # => 0.0.0.0
proxy_set_header X-Forwarded-Port $server_port; # => 3000
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_cache_bypass $http_upgrade;
# index fallback
try_files $uri $uri/ /index.html;
}
# . files
location ~ /\. {
deny all;
}
# assets, media
location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?)$ {
expires 7d;
access_log off;
}
# svg, fonts
location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
add_header Access-Control-Allow-Origin "*";
expires 7d;
access_log off;
}
# gzip
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml application/json application/javascript application/xml+rss application/atom+xml image/svg+xml;
# error pages
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/myapp/public;
}
error_page 404 /404.html;
location = /404.html {
root /var/www/myapp/public;
}
}
# subdomains redirect
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name _ *.my.app;
# SSL
ssl_certificate /etc/letsencrypt/live/my.app/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/my.app/privkey.pem;
ssl_trusted_certificate /etc/letsencrypt/live/my.app/chain.pem;
include snippets/letsencrypt.conf;
include snippets/ssl.conf;
return 301 https://my.app$request_uri;
}
# HTTP redirect
server {
listen 80;
listen [::]:80;
server_name _ .my.app my.app;
include snippets/letsencrypt.conf;
return 301 https://my.app$request_uri;
}
the rails container start thru docker-compose with this setup:
version: '3.2'
services:
web:
command: rails server -p '3000' -b '0.0.0.0' -e production
ports:
- '3000:3000'
I have tried also with unix socket to connect puma and nginx without success
I'm trying to follow this article:
https://www.digitalocean.com/community/tutorials/how-to-deploy-a-rails-app-with-puma-and-nginx-on-ubuntu-14-04
with a fresh Amazon Linux EC2 instance. I'm using the out-of-the-box /etc/nginx/nginx.conf file, and added my config file to /etc/nginx/sites-default/default
Puma seems to be running fine:
/home/ec2-user/flviewer/shared/log/puma_error.log: [8006] *
Listening on
unix:///home/ec2user/flviewer/shared/sockets/tmp/puma.sock
But this shows up in /var/log/nginx/error.log:
2016/12/12 05:33:00 [error] 11018#0: *1 open()
"/usr/share/nginx/html/flviewer" failed (2: No such file or
directory), client: 173.73.119.219, server: localhost, request: "GET
/flviewer HTTP/1.1", host: "54.86.222.53"
Why the heck is it looking in '/usr/share/nginx/html/flviewer' when it should be looking at the socket i opened?
here is my config as dumped by 'nginx -T':
# configuration file /etc/nginx/sites-available/default:
upstream app {
# Path to Puma SOCK file, as defined previously
server unix:/home/ec2-user/flviewer/shared/tmp/sockets/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name localhost;
root /home/ec2-user/flviewer/current/public;
try_files $uri/index.html $uri #app;
location #app {
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_redirect off;
#proxy_http_version 1.1;
proxy_set_header Connection '';
proxy_pass http://app;
#autoindex on;
}
location ~ ^/(assets|fonts|system)/|favicon.ico|robots.txt {
gzip_static on;
expires max;
add_header Cache-Control public;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
Nothing worked. I stripped /etc/nginx.conf down to just this, and am up and running. I had to throw away all of the boilerplate that was in nginx.conf. This works:
config file:
# Run nginx as a normal console program, not as a daemon
daemon off;
user ec2-user;
# Log errors to stdout
error_log /dev/stdout info;
events {} # Boilerplate
http {
# Print the access log to stdout
access_log /dev/stdout;
# Tell nginx that there's an external server called #app living at our socket
upstream app {
server unix:/home/ec2-user/flv/shared/tmp/sockets/puma.sock fail_timeout=0;
}
server {
# Accept connections on localhost:2048
listen 80;
server_name localhost;
# Application root
root /home/ec2-user/flv/shared/public;
# If a path doesn't exist on disk, forward the request to #app
try_files $uri/index.html $uri #app;
# Set some configuration options on requests forwarded to #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;
}
location ~ ^/(assets|fonts|system)/|favicon.ico|robots.txt {
gzip_static on;
expires max;
add_header Cache-Control public;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
}
I think it has to do with using the default nginx config file. Try moving /etc/nginx/sites-available/default to /etc/nginx/sites-enabled/flviewer.
$ mv /etc/nginx/sites-available/default /etc/nginx/sites-enabled/flviewer
Then reload and restart nginx.