Docker Compose + Rails:迁移的最佳实践?

我只是按照这篇关于在Docker中运行Rails开发环境的文章。 好文章,效果很好。 完成所有工作后,我决定继续build立一个生产环境。

目标:

我想rake db:create && rake db:migrate每次我的docker图像运行。

问题:

如果我移动数据库创build和迁移步骤…

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

…到Dockerfile中…

 RUN rake db:create && rake db:migrate 

…会抛出一个错误…

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

…因为我的database.ymlhost

 default: &default adapter: postgresql encoding: unicode pool: 5 timeout: 5000 username: postgres host: postgres port: 5432 development: <<: *default database: rails_five_development 

…设置为在我docker-compose.yml指定的postgres服务名称…

 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 

因为这是该条所指的推荐做法。

题:

我怎么能自动rake db:create && rake db:migrate每次我的docker图像运行?

我正在试图达到与这个问题相同的目的

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

如果您希望您的容器每次都运行相同的可执行文件,则应考虑将入口点与CMD结合使用。 见进入点

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

TL;博士

你可以在app下定义一个entrypoint ,并在那里定义一个bash文件:

 app: entrypoint: [bin/entry] .. 

bin / entry文件示例:

 #!/bin/bash set -e rake db:create rake db:migrate exec "$@" 

如果迁移无法成功,此方法将创build数据库。 它也避免了由于pid文件被遗忘而无法启动服务器的问题 。 创build文件为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 "$@" 

docker-compose.yml包括:

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

我使用一个Makefile:

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

所以,现在当我想要docker-compose up我只是做一个make run而已。