Docker Compose + Rails: best practice to migrate?

*爱你&永不变心* 提交于 2019-12-12 07:29:57

问题


I just followed this article on Running a Rails Development Environment in Docker. Good article, works great. After setting everything up, I decided to go on and set up a production environment.

GOAL:

I want to rake db:create && rake db:migrate every time my docker image is run.

PROBLEM:

If I move the database creation and migrations steps...

docker-compose run app rake db:create
docker-compose run app rake db:migrate

...into the Dockerfile...

RUN rake db:create && rake db:migrate

...that will throw an error...

could not translate host name "postgres" to address: Name or service not known

...because the host in my database.yml...

default: &default
  adapter: postgresql
  encoding: unicode
  pool: 5
  timeout: 5000
  username: postgres
  host: postgres
  port: 5432

development:
  <<: *default
  database: rails_five_development

...is set to the postgres service name specified in my docker-compose.yml...

version: "2"
services:
  postgres:
    image: postgres:9.5
    ports:
      - "5432"
  app:
    build: .
    command: rails server -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - "3000:3000"
    links:
      - postgres

...since that is the recommended practice as pointed by the article.

QUESTION:

How can I automatically rake db:create && rake db:migrate every time my docker image is run?

I am trying to achieve the same thing as in this question


回答1:


From https://docs.docker.com/engine/reference/builder/#cmd:

If you would like your container to run the same executable every time, then you should consider using ENTRYPOINT in combination with CMD. See ENTRYPOINT

https://docs.docker.com/engine/reference/builder/#entrypoint

tl;dr

You could define an entrypoint under app and define a bash file there:

app:
  entrypoint: [bin/entry]
  ..

bin/entry file example:

#!/bin/bash
set -e

rake db:create
rake db:migrate

exec "$@"



回答2:


This approach creates the database if the migration is not able to succeed. It also avoids the issue of being unable to start the server because a pid file was left behind. Create the file as app/lib/docker-entrypoint.sh.

#!/bin/sh
# https://stackoverflow.com/a/38732187/1935918
set -e

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

bundle exec rake db:migrate 2>/dev/null || bundle exec rake db:setup

exec bundle exec "$@"

The docker-compose.yml then includes:

entrypoint: ["/app/lib/docker-entrypoint.sh"]
command: ["rails","server","-b","0.0.0.0","-p","3000"]



回答3:


I use a Makefile:

run:
    docker-compose up -d \
    && docker-compose run web rake db:create

So, now when I wanna docker-compose up I just do make run instead.



来源:https://stackoverflow.com/questions/38089999/docker-compose-rails-best-practice-to-migrate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!