capistrano-plugins / capistrano-unicorn-nginx

Capistrano tasks for automatic and sensible unicorn + nginx configuration
MIT License
175 stars 81 forks source link

Handling assets manifest files with a multi-server setup #28

Open bruno- opened 10 years ago

bruno- commented 10 years ago

On a multi-server setup with separate web and app nodes, assets do not seem to work. The page is served without css and javascript.

I'm working with a minimal scaffolded rails 4 app. Here is how the generated links to css and js files look like:

<link data-turbolinks-track="true" href="/stylesheets/application.css" media="all" rel="stylesheet" />
<script data-turbolinks-track="true" src="/javascripts/application.js"></script>

I investigated this and the reason for this seems to be: assets aren't pre-compilated on the app servers so there's no asset manifest file on those nodes and they generate wrong css & js references.

Fixing this is relatively simple:

<link data-turbolinks-track="true" href="/assets/application-cf0b4d12cded06d61176668723302161.css" media="all" rel="stylesheet" />
<script data-turbolinks-track="true" src="/assets/application-10faafa06109fa14582542ac1852f5c5.js"></script>

@rhomeister how did you handle this in your setup? I wonder why noone handled this in capistrano-rails? Not even an issue was opened related to this so I'm worried I'm missing something.

rhomeister commented 10 years ago

Ah yes, this caused me a little bit of headache too. I'm using asset_sync to upload my assets to S3 (from which they are served). Therefore, my non-release web role doesn't need the assets at all. To generate the manifest, I'm running the assets:compile task only on the app nodes:

set :assets_roles, :app # only compile assets on app roles

In order to do this, I also needed to add the following:

before 'deploy', 'postgresql:database_yml_symlink'
before "deploy:compile_assets", "deploy:symlink:linked_dirs" # we need database.yml because asset_sync connects to DB
before "deploy:compile_assets", "deploy:symlink:linked_files"

This is because the asset_sync gem has to use the Rails environment to compile the assets, and in order to do this, it has to connect to the db. In conclusion: I'm not happy with the amount of extra config I have to do in my deploy.rb, but I managed to get this working.

bruno- commented 10 years ago

Ok, thanks for confirming this wasn't working out of the box for you too. I'll open an issue on capistrano-rails and see what they advise.

rhomeister commented 10 years ago

My setup is not ideal either. It would be nicer if I could have the compilation take place on 1 node (primary app, web, or whatever) and then to copy the manifest file to the app nodes. To be honest, I'm not entirely clear how assets work if they aren't served from a different role than app. Does the app role need the actual assets or is the manifest sufficient?

bruno- commented 10 years ago

Thanks for stepping out about your uncertainness on the topic because I feel fuzzy about all this too.

I'm afraid I don't understand this more than how it's described in the first post. I've opened an issue on capistrano-rails so let's say what those people say.

toobulkeh commented 9 years ago

By default this gem isn't compiling assets on the web nodes for me. Any ideas why this would be happening? Same scenario as you both talked about above (albeit late last year)

toobulkeh commented 9 years ago

I had to remove the no_release option for the assets to compile on the web node. Which required nodesjs (or a JS runtime) and PostgreSQL dependencies. Definitely not ideal, but precompiling locally would work as well (not ideal either).