Precompiling assets to deploy dockerized Rails 5 application to Heroku

Viewed 620

My dockerized Rails app (v5.2) works fine locally, but I haven't been able to deploy to Heroku successfully. When I deploy, I get the following error:

2021-02-04T09:57:21.252905+00:00 app[web.1]: F, [2021-02-04T09:57:21.251635 #4] FATAL -- : [793d88e0-6621-4977-87e0-c1c6a2c71420] ActionView::Template::Error (The asset "application.css" is not present in the asset pipeline.

I'm pretty sure this because I didn't precompile assets correctly. My preference is to precompile assets locally, commit the code changes, and then deploy to Heroku rather than adding the RUN bundle exec rake assets:precompile command to my Dockerfile - in order to minimize boot time in production. Although I've tried that approach and it hasn't appeared to work.

Whenever I run RAILS_ENV=production bundle exec rake assets:precompile locally, it appears to work, but it writes the files to /web/public/assets/ in my docker container rather than in my local directory /public/assets/. As a result, I have no new files to commit and push to Heroku. See the results of running rake assets:precompile in docker-compose shell.

To run this command, I first shell into my local docker container:

docker-compose exec web sh

Then I run the rake command:

RAILS_ENV=production bundle exec rake assets:precompile

It makes sense that it would write the files to the path /web/public/assets, but I'm not able to run the assets:precompile step outside of docker-compose because rails isn't installed on my computer. I'd like to avoid installing rails as that kind of defeats the purpose of using Docker for a dev environment.

Here is my Dockerfile:

FROM ruby:2.5.3-alpine3.9

ENV BUNDLER_VERSION=2.0.2

RUN apk add --update --no-cache \
      binutils-gold \
      build-base \
      curl \
      file \
      g++ \
      gcc \
      git \
      less \
      libstdc++ \
      libffi-dev \
      libc-dev \
      linux-headers \
      libxml2-dev \
      libxslt-dev \
      libgcrypt-dev \
      make \
      netcat-openbsd \
      nodejs \
      npm \
      openssl \
      pkgconfig \
      postgresql-dev \
      python \
      tzdata \
      yarn


RUN gem install bundler -v 2.0.2

WORKDIR /web

COPY Gemfile Gemfile.lock ./

RUN bundle config build.nokogiri --use-system-libraries
RUN bundle check || bundle install

ENV RAILS_ENV production
ENV RACK_ENV production

COPY package.json yarn.lock ./
RUN yarn install --check-files


COPY . ./


ENTRYPOINT ["./entrypoints/docker-entrypoint.sh"]

Here is the docker-entrypoint.sh file:

#!/bin/sh

set -e

if [ -f tmp/pids/server.pid ]; then
  rm tmp/pids/server.pid
fi


bundle exec rake assets:precompile
bundle exec rails s -b '0.0.0.0'

Here is docker-compose.yml:

version: '3.4'

services:
  web:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - database
      - redis
    ports:
      - "3000:3000"
    volumes:
      - node_modules:/app/node_modules
    env_file: .env
    environment:
      RAILS_ENV: development

  database:
    image: postgres:12.1
    volumes:
      - db_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql

  redis:
    image: redis:5.0.7

  sidekiq:
    build:
      context: .
      dockerfile: Dockerfile
    depends_on:
      - web
      - database
      - redis
    volumes:
      - .:/app
      - node_modules:/app/node_modules
    env_file: .env
    environment:
      RAILS_ENV: development
    entrypoint: ./entrypoints/sidekiq-entrypoint.sh

volumes:
  gem_cache:
  db_data:
  node_modules:

Thanks so much for your help!

0 Answers
Related