最佳做法轨道docker – 撰写数据库:创build数据库:迁移

我有简单的rails应用程序与docker-compose.yml文件。 它由两个容器组成 – 包含PostgreSQL的db容器和带有rails应用的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数据库:创build数据库:迁移我创build数据库,如果它是第一次运行数据库容器,并运行迁移。

但如果它只是更新Web部分 – 我只需要运行db:migrate和db:create(因为它应该)给我错误

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

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

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

这里是我扩展的postgres的Dockerfile:

 FROM postgres:9.4 ADD db/init.sql /docker-entrypoint-initdb.d/ EXPOSE 5432 CMD ["postgres"] 

docker postgres文件:

如果您想在从此映像派生的映像中进行额外的初始化,请在/docker-entrypoint-initdb.d下添加一个或多个*.sql*.sh脚本(必要时创build该目录)。 在入口点调用initdb创build默认的postgres用户和数据库之后,它将运行任何*.sql文件,并在该目录中find任何*.sh脚本,以在启动服务之前进行进一步的初始化。

我的init.sql

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

之后,我在web容器中的RUN命令指向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容器中创build,而web应用程序只进行迁移。