rails docker-compose db:create db:migrate

时间:2017-04-20 10:03:06

标签: ruby-on-rails postgresql docker docker-compose

我有docker-compose.yml文件的简单rails应用程序。 它由两个容器组成 - 带有PostgreSQL的db容器和带有rails app的web容器。

在web部件的dockerfile中,我在CMD

中有这样的行
CMD RAILS_ENV=production rake db:create db:migrate && \
    bundle exec rails s -p 3000 -b '0.0.0.0' --environment=production

所以在线rake db:create db:migrate我创建db,如果它是第一次运行db容器,并运行migrate。

但如果它只是web部分的更新 - 我只需要运行db:migrate,而db:create(因为它应该)给我错误

ERROR:  database "myapp_production" already exists
STATEMENT:  CREATE DATABASE "myapp_production" ENCODING = 'unicode'

一切正常,但我认为还有更好的方法 处理这种情况的最佳方法是什么?

1 个答案:

答案 0 :(得分:1)

我有相同的开发堆栈,这就是我正在做的事情。

这是我扩展的postgres的Dockerfile:

FROM postgres:9.4

ADD db/init.sql /docker-entrypoint-initdb.d/

EXPOSE 5432
CMD ["postgres"]

来自docker postgres文档:

  

如果您想在派生的图像中进行其他初始化   从这一个,添加一个或多个*.sql*.sh脚本   /docker-entrypoint-initdb.d(必要时创建目录)。   入口点调用initdb后创建默认的postgres用户   和数据库,它将运行任何*.sql文件并提供任何*.sh脚本   在该目录中找到在开始之前进行进一步的初始化   服务。

我的init.sql

CREATE USER database_user;
CREATE DATABASE database_production;
GRANT ALL PRIVILEGES ON DATABASE database_production TO database_user;

之后,RUN容器中的web命令指向run.sh脚本:

#!/usr/bin/env bash

echo "Bundling gems"
bundle install --jobs 8 --retry 3

echo "Clearing logs"
bin/rake log:clear

echo "Run migrations"
bundle exec rake db:migrate

echo "Seed database"
bundle exec rake db:seed

echo "Removing contents of tmp dirs"
bin/rake tmp:clear

echo "Starting app server ..."
bundle exec rails s -p 3000 -b '0.0.0.0'

就是这样。我在db容器中创建的数据库和web应用仅执行迁移。