我刚刚在Running a Rails Development Environment in Docker上关注了这篇文章。好文章,效果很好。设置好后,我决定继续设置生产环境。
目标:
我希望每次运行泊坞窗图像时rake db:create && rake db:migrate
。
问题:
如果我移动数据库创建和迁移步骤......
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
...因为host
中的database.yml
...
default: &default
adapter: postgresql
encoding: unicode
pool: 5
timeout: 5000
username: postgres
host: postgres
port: 5432
development:
<<: *default
database: rails_five_development
...设置为postgres
...
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
...因为这是本文指出的推荐做法。
问题:
每次运行泊坞窗图像时,如何自动rake db:create && rake db:migrate
?
答案 0 :(得分:19)
来自https://docs.docker.com/engine/reference/builder/#cmd:
如果您希望容器每次都运行相同的可执行文件,那么您应该考虑将ENTRYPOINT与CMD结合使用。参见ENTRYPOINT
https://docs.docker.com/engine/reference/builder/#entrypoint
TL;博士
您可以在应用下定义entrypoint
并在其中定义bash文件:
app:
entrypoint: [bin/entry]
..
bin / entry file example:
#!/bin/bash
set -e
rake db:create
rake db:migrate
exec "$@"
答案 1 :(得分:12)
如果迁移无法成功,此方法将创建数据库。它还避免issue无法启动服务器,因为pid文件被遗忘。将文件创建为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"]
答案 2 :(得分:2)
我使用Makefile:
run:
docker-compose up -d \
&& docker-compose run web rake db:create
所以,现在当我想docker-compose up
时,我只是做make run
而已。