提问人:antun 提问时间:6/6/2020 最后编辑:antun 更新时间:6/7/2020 访问量:1430
在 docker 中播种 rails 应用程序以便可以重复启动的正确方法是什么
What is the correct way to seed a rails app in docker so it can be started repeatedly
问:
我有一个以 mysql 作为数据库的 rails 应用程序,我正在尝试对其进行 dockerization,因此我最终可以使用 .当我第一次运行时,它会正确初始化并像它应该的那样为数据库设定种子。但是,在我关闭它后,第二次运行时,它失败并出现以下错误,因为种子内容已经存在:docker-machine
docker-compose up
docker-compose up
web_1 | ActiveRecord::RecordNotUnique: Mysql2::Error: Duplicate entry '[email protected]' for key 'index_users_on_email'
在我的docker-compose.yml文件中,我在Web服务下执行以下操作:
command: /bin/sh -c "bin/wait-for db:3306 -- rm -f /home/ubuntu/MY_APP/tmp/pids/server.pid && bundle exec rake db:create db:migrate db:seed && rails server puma -p 80"
我正在使用 !db/seeds.rb 中的方法方法,因为我知道这被认为是最佳实践:
u = User.new(
{email: "[email protected]", encrypted_password: "XXXXX", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, first_name: "Antun", last_name: "LAST_NAME", provider: "facebook", uid: "12345", username: "antun"}
)
u.save!(validate: false)
我知道我可以跳过 !但正如我所说,我知道在种子文件中使用它是一种最佳实践,这样它就会失败。我的问题是:仅在使用 docker-compose 首次运行时创建和播种数据库的正确最佳实践方法是什么?一旦它上线,我想确保应用程序的后续更新(可能包括新数据类型的迁移/附加种子)顺利运行,而不会擦除数据库中的数据。u.save!()
下面是完整的 docker-compose.yml 文件:
docker-compose.yml
version: '3.1'
services:
db:
image: mysql:5.6
command: mysqld --character-set-server=utf8 --collation-server=utf8_unicode_ci --init-connect='SET NAMES UTF8;' --innodb-flush-log-at-trx-commit=0
environment:
MYSQL_ROOT_PASSWORD: XXXXX
MYSQL_DATABASE: XXXXX
MYSQL_USER: XXXXX
MYSQL_PASSWORD: XXXXX
web:
build: .
command: /bin/sh -c "bin/wait-for db:3306 -- rm -f /home/ubuntu/MY_APP/tmp/pids/server.pid && bundle exec rake db:create db:migrate db:seed && rails server puma -p 80"
volumes:
- $PWD:/MY_APP
ports:
- "80:80"
links:
- "db:database"
env_file:
- .env.production
depends_on:
- db
worker:
build: .
command: /bin/sh -c "bundle exec bin/delayed_job -n 1 --log-dir=/home/ubuntu/MY_APP/shared/log/delayed_job.log --pool='notifications-poller:1' --pool='broadcast,default,elasticsearch,firebase:2' restart && bundle exec shoryuken --logfile '/home/ubuntu/MY_APP/shared/log/shoryuken.log' --config '/home/ubuntu/MY_APP/config/shoryuken_staging.yml' -R"
links:
- "db:database"
volumes:
- $PWD:/MY_APP
- '/home/ubuntu/MY_APP/node_modules'
env_file:
- .env.production
depends_on:
- db
答:
请尝试改用 ActiveRecord::Relation#find_or_create_by:
User.find_or_create_by(email: "[email protected]", encrypted_password: "XXXXX", reset_password_token: nil, reset_password_sent_at: nil, remember_created_at: nil, first_name: "Antun", last_name: "LAST_NAME", provider: "facebook", uid: "12345", username: "antun")
回复您的评论;恐怕存储库已经无人维护,但您可以使用我刚刚为此制作的分支。
如果您看到这些更改,则可以执行以下操作:
SeedDump.dump(ModelName, method: :find_or_create_by)
# "ModelName.find_or_create_by([\n {name: \"<name>\", status: nil},\n...)\n"
回答您的最后评论和问题:
在 docker 中播种 rails 应用程序以便可以重复启动的正确方法是什么
我不知道这是否正确,但很简单;当您使用MySQL时,只需使用它提供的工具即可。您可以从任何环境转储和导入数据,这将保持数据的完整性,这可能更快且更不容易出错。
评论
rake db:create db:migrate db:seed
评论
bundle exec rake db:create db:migrate
db:seed
docker-compose run web rake db:create