Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Serving Rails' precompiled assets using nginx in Docker

Currently I'm setting up my app using docker. I've got a minimal rails app, with 1 controller. You can get my setup by running these:

rails new app --database=sqlite --skip-bundle
cd app
rails generate controller --skip-routes Home index
echo "Rails.application.routes.draw { root 'home#index' }" > config/routes.rb
echo "gem 'foreman'" >> Gemfile
echo "web: rails server -b 0.0.0.0" > Procfile
echo "port: 3000" > .foreman

And I have the following setup:

Dockerfile:

FROM ruby:2.3

# Install dependencies
RUN apt-get update && apt-get install -y \
      nodejs \
      sqlite3 \
      --no-install-recommends \
      && rm -rf /var/lib/apt/lists/*

# Configure bundle
RUN bundle config --global frozen 1
RUN bundle config --global jobs 7

# Expose ports and set entrypoint and command
EXPOSE 3000
CMD ["foreman", "start"]

# Install Gemfile in different folder to allow caching
WORKDIR /tmp
COPY ["Gemfile", "Gemfile.lock", "/tmp/"]
RUN bundle install --deployment

# Set environment
ENV RAILS_ENV production
ENV RACK_ENV production

# Add files
ENV APP_DIR /app
RUN mkdir -p $APP_DIR
COPY . $APP_DIR
WORKDIR $APP_DIR

# Compile assets
RUN rails assets:precompile
VOLUME "$APP_DIR/public"

Where VOLUME "$APP_DIR/public" is creating a volume that's shared with the Nginx container, which has this in the Dockerfile:

FROM nginx

ADD nginx.conf /etc/nginx/nginx.conf

And then docker-compose.yml:

version: '2'

services:
  web:
    build: config/docker/web
    volumes_from:
      - app
    links:
      - app:app
    ports:
      - 80:80
      - 443:443
  app:
    build: .
    environment:
      SECRET_KEY_BASE: 'af3...ef0'
    ports:
      - 3000:3000

This works, but only the first time I build it. If I change any assets, and build the images again, they're not updated. Possibly because volumes are not updated on image build, I think because how Docker handles caching.

I want the assets to be updated every time I run docker-compose built && docker-compose up. Any idea how to accomplish this?

like image 593
jeroenvisser101 Avatar asked Mar 23 '16 13:03

jeroenvisser101


1 Answers

Compose preserves volumes on recreate.

You have a couple options:

  1. don't use volumes for the assets, instead build the assets and ADD or COPY them into the web container during build
  2. docker-compose rm app before running up to remove the old container and volumes.
like image 77
dnephin Avatar answered Nov 05 '22 20:11

dnephin