Sharing precompiled assets across docker containers Sharing precompiled assets across docker containers docker docker

Sharing precompiled assets across docker containers


I'm having the same issue. Here's what I'm currently working on:

Option 1: use a single image for both nginx and the app

This way, I can build the image once (with the app, precompiled assets and nginx), then run two instances of it: one running the app server, and another for the nginx frontend:

docker build -t hello .docker run --name hello-app hello rackupdocker run --name hello-web -p 80:80 --link hello-app:app hello nginx

Not pretty, but very easy to set up and upgrade.

Option 2: use a shared volume, and precompile assets as a job

Shared volumes cannot be updated in the build process, but can be updated by a container instance. So we can run our rake task to precompile the assets just before running our app:

docker build -t hello .docker run -v /apps/hello/assets:/app/public/assets hello rake assets:precompiledocker run --name hello-app hello rackupdocker run --name hello-web -p 80:80 --link hello-app:app -v /apps/hello/assets:/usr/share/nginx/html/assets nginx

This looks like a more robust option, but will require a more complex instrumentation. I'm leaning towards this option, however, since we'll need a separate job for database migrations anyway.

Option 3: distribute the assets to a CDN on build-time

Your Dockerfile can upload the resulting assets directly to a CDN. Then you configure your Rails app to use it as the asset_host. Something like:

RUN rake assets:precompile && aws s3 sync public/assets s3://test-assets/

I'm currently experimenting with this option. Since I'm using Amazon CloudFront, looks like I can just sync the resulting assets to S3 using the AWS CLI. There's also a gem for that (asset_sync), but it looks stale.

The downside is that you'll have to send the needed AWS credentials to the build context or the Dockerfile itself – this might need committing them to your source repository, if you're using an automated build.


I recommend to precompile assets inside of Docker container because in this case you can without any problems run it to any environment otherwise before run docker container you should copy shared precompilled assets to new environment, mount them and only after it run docker container.

The other problem related to version of assets. I mean that your code must use assets compatible with it otherwise you will have different problems with CSS and JS. So, this is the second point why you should precompile assets inside of Docker container.


For production, @maxd is right: you should add the compiled assets to your images. However, for development I think you are right. Use a volume container that is used by:

  • the rails container to store the precompiled assets
  • the nginx container to serve the assets

An alternative would be mounting a host directory into the containers.

You can find more help in the Managing Data in Containers User Guide