I have an nginx container separate from my rails container and want to be able to serve precompiled assets from rails with the nginx container. This sounds like a job for a volume container but I have got myself confused after having quickly needing to learn docker and reading the documentation endlessly. Has anybody had to deal with a similar situation?
If you are running more than one container, you can let your containers communicate with each other by attaching them to the same network. Docker creates virtual networks which let your containers talk to each other. In a network, a container has an IP address, and optionally a hostname.
Docker containers all run in the same kernel, vs a VM which runs a kernel per guest. So, in terms of which resources in the kernel are shared... really, that would be absolutely everything, except those items which are namespaced away from each other (non-shared mounts, process tree entries, cgroups, etc).
Volumes are easier to back up or migrate than bind mounts. You can manage volumes using Docker CLI commands or the Docker API. Volumes work on both Linux and Windows containers. Volumes can be more safely shared among multiple containers.
I'm having the same issue. Here's what I'm currently working on:
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 rackup docker run --name hello-web -p 80:80 --link hello-app:app hello nginx
Not pretty, but very easy to set up and upgrade.
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:precompile docker run --name hello-app hello rackup docker 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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With