Search code examples
ruby-on-railsnginxassetsunicornprecompile

Rails deploying with docker-compose, assets doesn't working


This is an extremely helpful article that I followed:

Docker for an Existing Rails Application

I was stuck on the problem. The application can run with no error, the index page can be see from the web surf. But the index page looks wired, looks like the scss doesn't working and the image doesn't appear.

From the Chrome Console, I got this:

enter image description here

I did a lot search and found it maybe the assets:premcompile. I changed the docker-compose.yml , run docker-compose run app rake db: assets:precompile, even I copied the public/assets/* to the container, but no luck.

Host Computer: CentOS 7

Any idea is great. Thanks in advance.

docker-compose.yml

1 app:
2     build: .
3
4     env_file: .env.production
5
6     environment:
7         RAILS_ENV: $RAILS_ENV
8
9     links:
10         - db
11

14     expose:
15         - "3000"
16
17 db:
18     image: postgres:9.4.5
19
20     volumes:
21         - eshop-postgres:/var/lib/postgresql/data
22
23 web:
24     build: .
25
26     dockerfile: config/containers/Dockerfile-nginx
27
28     volumes:
29         - ./public:/var/www/eshop/public
30
31     links:
32         - app
33     ports:
34         - "80:80"

Dockerfile

      2 FROM ruby:2.3.3-slim
     12 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev postgresql-client libsqlite3-dev nodejs vim
     15 ENV RAILS_ROOT /var/www/myapp
     18 RUN mkdir -p $RAILS_ROOT/tmp/pids
     19
     21 WORKDIR $RAILS_ROOT
     22
     26 COPY Gemfile Gemfile
     27
     28 COPY Gemfile.lock Gemfile.lock
     29
     31 RUN gem install bundler
     32
     34 RUN bundle install
     35
     37 COPY . .
     38

     39 - RUN RAILS_ENV=production bundle exec rake assets:precompile --trace~
     40 - RUN bundle exec rake assets:precompile --trace~

     40 + RUN bundle exec rake RAILS_ENV=$RAILS_ENV DATABASE_URL=postgresql://$POSTGRES_USER:[email protected]/$POSTGRES_PRODUCTION_DB assets:precompile
     41 + VOLUMES ["$RAILS_ROOT/public"]

     46 + CMD [ "config/containers/app_cmd.sh" ]

config/container/Docker-nginx

      2 FROM nginx

     12 RUN apt-get update -qq && apt-get -y install apache2-utils vim

     15 ENV RAILS_ROOT /var/www/myapp

     18 WORKDIR $RAILS_ROOT

     21 RUN mkdir log

     25 COPY public public/

     28 COPY config/containers/nginx.conf /tmp/myapp.nginx

     32 RUN envsubst '$RAILS_ROOT' < /tmp/myappv.nginx > /etc/nginx/conf.d/default.conf

     35 CMD [ "nginx", "-g", "daemon off;" ]

UPDATED:

I made some updates according to @bkunzi01 advices. But no luck.

Dockerfile

 40 RUN bundle exec rake RAILS_ENV=$RAILS_ENV DATABASE_URL=postgresql://$POSTGRES_USER:[email protected]/$POSTGRES_PRODUCTION_DB assets:precompile
 41 VOLUME ["$RAILS_ROOT/public"] 

 46 CMD [ "config/containers/app_cmd.sh" ]

.env.production

# *.env.production*    

RAILS_ENV=production
RAILS_ROOT=/var/www/eshop
SECRET_KEY_BASE=the_long_code
POSTGRES_PRODUCTION_DB=production_db
POSTGRES_USER=postgres
POSTGRES_PASSWORD=keep_secret_ps

There is another [warn] in the log of docker-compose:

web_1  | 2017/03/02 05:45:14 [warn] 1#1: server name "/var/www/eshop/public" has suspicious symbols in /etc/nginx/conf.d/default.conf:16
web_1  | nginx: [warn] server name "/var/www/eshop/public" has suspicious symbols in /etc/nginx/conf.d/default.conf:16

Solution

  • Most people have this error because they're missing node.js however you have that so I think the next likely candidate is to add a volume directive and also consider changing your precompiling command on line 39 of the dockerfile to:

    RUN bundle exec rake RAILS_ENV=production DATABASE_URL=postgresql://user:[email protected]/dbname SECRET_TOKEN=makeupasecret assets:precompile
    
    VOLUME ["$RAILS_ROOT/public"]
    

    Adding this volume directive here will expose your assets to nginx by keeping the precompiled assets in a volume.

    Also, you can makeup anything you want for the secret_token and the database info. The reason is that Rails will freak out when the secret token and user aren't supplied but you can totally make them up because Rails doesn't check them here lol...

    Plus make sure to remove that second precompile:assets command since it's not needed.

    Note: I'd also add at the end of the Dockerfile a line to trigger running unicorn or whatever other appserver you're going to run rails on behind nginx.

    Ex. CMD bundle exec unicorn -c config/unicorn.rb