Search code examples
ruby-on-railsdockerdocker-composerails-migrations

docker compose rails app is asking for migration to be ran when it was already ran in build


So I have pre built a docker image of a rails app. When the image is built the migration is ran. When I run the image with docker run everything works fine. But when I try and run a docker-compose file, when I visit the app, it is telling me I need to run the migration, but the migration was ran in the build step.

Folder structure:

root/
  my_app/
  Dockerfile
  docker-compose

Here are the steps I took:

I run docker build -t my_app . on the Dockerfile:

FROM ruby:2.4-jessie

WORKDIR /usr/src/app
COPY ./my_app/Gemfile* ./
RUN bundle install
COPY ./my_app .
EXPOSE 3000

RUN rails db:migrate

CMD ["rails", "server", "-b", "0.0.0.0"]

It buids fine and I can see that the migration is successfully ran.

Next I run it with docker run -p 3000:3000 my_app

I visit it in the browser and everything is fine.

Next I run docker-compose up on the docker-compose file:

version: '3'

services:
  my-app-container:
    image: my_app
    volumes:
      - ./my_app:/usr/src/app
    ports:
      - 3000:3000

The image starts fine but when I visit it in the browse is get:

Migrations are pending. To resolve this issue, run: bin/rails db:migrate RAILS_ENV=development 

# Raises <tt>ActiveRecord::PendingMigrationError</tt> error if any migrations are pending.
def check_pending!(connection = Base.connection)
  raise ActiveRecord::PendingMigrationError if ActiveRecord::Migrator.needs_migration?(connection)
end

Solution

  • Ok, so the solution was to have commands in the docker-compose file to handle the migration and the starting of the rails app:

    version: '3'
    
    services:
      my-app-run-container:
        image: my_app_run_container
        volumes:
          - ./my_app:/usr/src/app
        ports:
          - 3000:3000
        command: rails db:migrate
        command: rails server -b 0.0.0.0
    

    I guess if I was going to use docker-compose for everything I could remove the migration and server start commands from the Dockerfile