I use Active Storage successfully when developing (Disk storage), but when application is deployed (Amazon S3 storage) all my attachments are not found.
Uploading works without any problems - files appear in S3 bucket and active storage database records are created. But any time I use .variant() or url_for(), all those files are missing.
Rails logs doesn't tell me anything, as if request did not happen at all. That makes me think that my web server configuration is wrong.
This is my current nginx configuration:
upstream my_app {
server unix:/srv/example.com/current/tmp/sockets/unicorn.sock fail_timeout=0;
}
server {
listen 80;
server_name example.com;
return 301 https://example.com$request_uri;
}
server {
listen 443 ssl;
server_name example.com;
root /srv/example.com/current/public;
include h5bp/directive-only/ssl.conf;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
include h5bp/basic.conf;
include h5bp/auth.conf;
try_files $uri/index.html $uri #unicorn;
location #unicorn {
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;
proxy_pass http://my_app;
}
access_log /var/log/nginx/example.com/access.log;
error_log /var/log/nginx/example.com/error.log;
charset utf-8;
error_page 404 /404.html;
error_page 502 503 #maintenance;
if (-f /srv/example.com/shared/maintenance.txt) {
return 503;
}
location #maintenance {
root /srv/maintenance;
rewrite ^(.*)$ /index.html break;
}
}
basic.conf is from here: https://github.com/h5bp/server-configs-nginx/tree/master/h5bp
auth.conf is only HTTP simple authentication.
Nginx log shows lines like this:
2018/03/12 11:48:32 [error] 9402#9402: *16285 open() "/srv/example.com/current/public/rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--fe2fe760c83020f37a9fe8f78bcb4fc958744008/test-powerpoint-document.pptx" failed (2: No such file or directory), client: xxx.xx.xxx.xx, server: example.com, request: "GET /rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBDZz09IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--fe2fe760c83020f37a9fe8f78bcb4fc958744008/test-powerpoint-document.pptx?disposition=upload HTTP/1.1", host: "example.com"
What am I missing?
In case anyone stumbles into the same issue, I fixed my case by commenting out the following:
# h5bp/location/expires.conf
location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|mp4|ogg|ogv|webm|htc)$ {
access_log off;
add_header Cache-Control "max-age=2592000";
}
Now all images display and attachments download without any issue.
Related
I am deploying an app with a React front end created using create-react-app and a Rails API as the backend. I do not know much about configuring web servers and proxies so I am not sure exactly how to get it to work in production. I am deploying the app to Ubuntu on an Amazon EC2 instance. Nginx is the web server. I need to configure it so that Nginx serves the static files from the client/build directory and then any requests made to /api go to the Rails app running on port 3001. Right now Nginx is serving the index.html and the Javascript is running properly but requests to /api are not going to the right place. Any thoughts on how to configure Nginx to do this? Here is my /etc/nginx/sites-enabled/default file:
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name mydomain.com;
passenger_enabled on;
rails_env staging;
root /home/ubuntu/app-name/current/client/build;
index index.html;
location /api {
proxy_pass http://127.0.0.1:3001;
}
}
What am I missing? How do I get the Rails app to run on port 3001 and have all requests to /api go there? Do I need a separate server block in this config?
I don't know if you already solved your issue and if this solution will apply to you but I think it might be useful for other people searching on this issue.
I am using Puma as the application server to run my rails 5 api.
This is the configuration file for my dev environment:
upstream app {
# Path to Puma SOCK file, here is where you make the connection to your application server
server unix:/path/to/your/puma.sock fail_timeout=0;
}
server {
listen 80;
server_name mydomain.com;
# this is where my react-app is located
root /var/www/development/ram/public/;
index index.html index.htm;
# Serve the static content (React app)
location / {
try_files $uri /index.html =404;
}
location /api {
# Insert your public app path
root /your/rails-app/path/public;
proxy_pass http://app;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 4G;
keepalive_timeout 10;
}
So comparing, I think your problem might be solved by adding a root directive pointing to your rails api public directory
I hope this can give you some hints on how to configure yours
Here is my working nginx config
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 80 default_server;
root /home/deploy/www/sublime/current/public;
index index.html;
server_name domain.com;
access_log /home/deploy/www/sublime/logs/access.log;
error_log /home/deploy/www/sublime/logs/errors.log;
server_name localhost;
passenger_enabled on;
passenger_app_env production;
location ~* ^.+\.(jpeg|gif|png|jpg) {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
}
location /api {
# Insert your public app path
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri /index.html;
}
}
You can use this repos to see rails configuration
https://github.com/Eth3rnit3/rails-react
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.
There are a ton of these questions, I've read a lot of them, still unable to figure out what's going wrong for me.
The error log in my console
2016/08/02 09:43:27 [error] 5484#0: *2 directory index of
"/home/deploy/appname/current/" is forbidden, client: 173.245.52.241,
server: localhost, request: "GET / HTTP/1.1", host: "appname.com"
Here's my nginx conf
upstream puma {
server unix:///home/deploy/appname/shared/tmp/sockets/appname-puma.sock;
}
server {
listen 80 default_server deferred;
server_name appname.com;
root /home/deploy/appname/current/public;
access_log /home/deploy/appname/current/log/nginx.access.log;
error_log /home/deploy/appname/current/log/nginx.error.log info;
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;
}
error_page 500 502 503 504 /500.html;
client_max_body_size 10M;
keepalive_timeout 10;
}
Thought it might have been a permissions issue so I ran chmod -R 755 on my project folder to no avail.
Any help greatly appreciated!
Whenever I try to access the Rails app, I get the default Nginx 404 page and the following error in /var/log/nginx/error.log:
2015/11/16 21:45:30 [error] 16240#0: *78 open() "/usr/local/apps/careers_api/current/public/application/test_aggregate.json" failed (2: No such file or directory), client: 70.184.87.69, server: careers-api.dynamynd.com, request: "GET /application/test_aggregate.json HTTP/1.1", host: "careers-api.dynamynd.com"
nginx.conf:
upstream api_server {
server unix:/run/unicorn/unicorn-api.sock fail_timeout=0;
}
server {
listen 443 ssl;
server_name abc.xyz.com;
root /usr/local/apps/abc_xyz/current/public;
ssl on;
ssl_certificate /etc/ssl/certs/ssl-bundle.crt;
ssl_certificate_key /etc/ssl/private/STAR_xyz_com.key;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES256-GCM-SHA384:AES128-GCM-SHA256:AES256-SHA256:AES128-SHA256:AES256-SHA:AES128-SHA:DES-CBC3-SHA:HIGH:!aNULL:!eNULL:!EXPORT:!DES:!MD5:!PSK:!RC4;
location #app {
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_redirect off;
proxy_pass http://api_server;
}
}
I have pretty much the same configuration on other apps running on the same machine, and they work just fine.
location #app is a named location. It can only be invoked indirectly from another location block. You have an implicit location / block, but that contains no command to invoke the upstream service.
So, unless that file is a local static file, located at /usr/local/apps/abc_xyz/current/public/application/test_aggregate.json, you will get a 404 error.
Perhaps you are missing something like:
location / {
try_files $uri $uri/ #app;
}
or
try_files $uri #app;
in the server block.
Please help me: there is something wrong in this virtual.conf nginx conf file that means that when viewing the site, I get the error ssl_error_rx_record_too_long rather than being able to view my site. I am using aws, nginx to serve some rails apps - this was working yesterday, but I crashed my entire server and am frantically trying to fix this at 2am, ready for production at 9:30am.
ssl_certificate /etc/ssl/star_my_site.pem;
ssl_certificate_key /etc/ssl/star_my_site.key;
# ------------------
# rails app one
# ------------------
upstream my_app {
server unix:///var/run/puma/my_app.sock;
}
server {
listen 80;
# server_name rails_app_one.my_site.com.au www.rails_app_one.my_site.com.au;
server_name _ localhost;
return 301 https://rails_app_one.my_site.com.au;
}
server {
listen 443;
server_name _ localhost;
location / {
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://my_app;
}
location ~ "^/assets/" {
root /var/app/current/public;
gzip_static on;
expires max;
add_header Cache-Control public;
}
}
# ------------------
# rails app two
# ------------------
upstream rails_app_two_app {
server unix:///var/run/puma/rails_app_two_app.sock;
}
server {
listen 80;
server_name rails_app_two.my_site.com.au www.rails_app_two.my_site.com.au;
return 301 https://rails_app_two.my_site.com.au;
}
server {
listen 443;
server_name rails_app_two.my_site.com.au;
location / {
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://rails_app_two_app;
}
location ~ "^/assets/" {
root /var/app/rails_app_two.my_site.com.au/current/public;
gzip_static on;
expires max;
add_header Cache-Control public;
}
}
ssl_error_rx_record_too_long usually means the server is returning plain HTTP content when the browser is expecting HTTPS content. (You can probably verify this by going to http://your.site:443 and seeing your site.)
You need to enable SSL in nginx - simply declaring ssl_certificate isn't enough.
Change listen 443; to listen 443 ssl;
(Also, I'd suggest putting ssl_certificate in the server block, so you can use different ssl certs with other domains.)
Edit: https://serverfault.com/questions/497430/error-code-ssl-error-rx-record-too-long has almost the exact same issue, hopefully you found it before your 9am production release!