Nginx serving static files via Unicorn upstream (tcp)

nginxstatic-filesunicorn

I'm trying to create a rails app with load balancer. App is running but I don't know how to serve static files. All examples assume that nginx and unicorn running on the same machine.

Here is the minimal configs:

Machine A: Nginx
Machine B: Unicorn process with app

Machine A:

user www-data;
worker_processes 4;
pid /run/nginx.pid;
events {
        worker_connections 768;
}

http {

        upstream unicorn_servers {
                server 192.168.14.224:8080 fail_timeout=0;
        }

        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_proxied any;
        gzip_http_version 1.1;
        gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
        include /etc/nginx/sites-enabled/*;
}

server {
        listen 80;
        location / {
                proxy_set_header        Host $host;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

                proxy_pass http://unicorn_servers;
        }
}

Machine B:

dir = '/home/user/apps/test_app'
working_directory dir
pid "#{dir}/pids/unicorn.pid"

# logs
stderr_path "#{dir}/log/unicorn.log"
stdout_path "#{dir}/log/unicorn.log"

worker_processes 2

timeout 30

I always see 404 on static assets.

  <link rel="stylesheet" media="all" href="/assets/application-0723cb9a2dd5a514d954f70e0fe0b89f6f9f1ae3a375c182f43b5f2b57e9c869.css" data-turbolinks-track="true" />
  <script src="/assets/application-08a19ba96489d7fc7864bb409a6841003509fe519cbd091b7a11a1acc7e53fbb.js" data-turbolinks-track="true"></script>

How to set up nginx to serve static files from other computer?

Best Answer

In your server block, you need to set the root directive to the top-level directory containing your assets (for a Rails app this is the public directory) and then use try_files to either load a static asset or pass on to your Rails app.

Of course, the static files must be accessible to the web server (e.g. via NFS). If you can't do this for some reason, then proxy from machine A to another nginx instance on machine B (which can access the static files) which in turn proxies to unicorn.

A quick example:

server {
        listen 80;

        root /home/user/apps/test_app/public;

        location / {
            try_files $uri $uri/ @rails;
        }

        location @rails {
                proxy_set_header        Host $host;
                proxy_set_header        X-Real-IP $remote_addr;
                proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;

                proxy_pass http://unicorn_servers;
        }
}