belgoros
belgoros

Reputation: 3928

docker-compose: run rails db:setup and rake tasks to init data

I can't find the way to execute the following commands from a docker-compose.yml file:

I tried to do that as follows and it failed:

version: '3'

services:
  web:
    build: .
    links:
      - database
      - redis
    ports:
      - "3000:3000"
    volumes:
      - .:/usr/src/app
    env_file:
      - .env/development/database
      - .env/development/web
    command: ["rails", "db:setup"]
    command: ["rails", "db:init_data"]
  redis:
    image: redis
  database:
    image: postgres
    env_file:
      - .env/development/database
    volumes:
      - db-data:/var/lib/postgresql/data
volumes:
  db-data:

Any idea on what's going wrong here ? Thank you. The code source is on the GitHub.

Upvotes: 1

Views: 1988

Answers (2)

belgoros
belgoros

Reputation: 3928

The solution that worked for me was to remove CMD commad from Dockerfile because using command option in docker-compose.yml would have overridden CMD command. So, Docker file will look like that:

FROM ruby:2.5.1

LABEL maintainer="DECATHLON"

RUN apt-get update -yqq
RUN apt-get install -yqq --no-install-recommends nodejs

COPY Gemfile* /usr/src/app/
WORKDIR /usr/src/app
RUN bundle install

COPY . /usr/src/app/

Then add command option to docker-compose file:

version: '3'

services:
  web:
    build: .
    links:
      - database
      - redis
    ports:
      - "3000:3000"
    volumes:
      - .:/usr/src/app
    env_file:
      - .env/development/database
      - .env/development/web
    command:
      - |
        rails db:reset
        rails db:init_data
        rails s -p 3000 -b '0.0.0.0'
  redis:
    image: redis
  database:
    image: postgres
    env_file:
      - .env/development/database
    volumes:
      - db-data:/var/lib/postgresql/data
volumes:
  db-data:

If the above solution does not work for somebody, there is an alternative solution:

Create a shell script in the project route and name it entrypoint.sh, for example:

#!/bin/bash  
set -e  
bundle exec rails db:reset
bundle exec rails db:migrate  
exec "$@"

Declare entrypoint option in dpcker-compose file:

v

version: '3'

services:
  web:
    build: .
    entrypoint:
      - /bin/sh
      - ./entrypoint.sh
    depends_on:
      - database
      - redis
    ports:
      - "3000:3000"
    volumes:
      - .:/usr/src/app
    env_file:
      - .env/development/database
      - .env/development/web
    command: ['./wait-for-it.sh', 'database:5432', '--', 'bundle', 'exec', 'rails', 's', '-p', '3000', '-b', '0.0.0.0']
  database:
    image: postgres:9.6
    env_file:
      - .env/development/database
    volumes:
      - db-data:/var/lib/postgresql/data
volumes:
  db-data:

I also user wait-for-it script to ensure the DB is started.

Hope this helps. I pushed the modifications to the Github repo. Sorry for some extra letters left in the text before code blocks, - for some unknown reasons, the code markdown didn't work, so I left them to get it working.

Upvotes: 0

Alejandro Galera
Alejandro Galera

Reputation: 3691

You can do two things in my opinion:

  1. Change command: to the following line, because two commands are not allowed in compose file:
    command: 
      - /bin/bash
      - -c 
      - |
          rails db:setup
          rails db:init_data

  1. Use supervisord app: supervisord web page

Upvotes: 1

Related Questions