ruby-on-rails - 在 docker 中播种 rails 应用程序以便它可以重复启动的正确方法是什么

标签 ruby-on-rails docker docker-compose

我有一个以 mysql 作为数据库的 rails 应用程序,我正在尝试对其进行 dockerize,因此我最终可以使用 docker-machine 部署它.当我跑 docker-compose up第一次,它正确初始化并为数据库设置种子,就像它应该做的那样。但是,我关闭后,第二次运行docker-compose up ,它失败并出现以下错误,因为种子内容已经存在:

web_1     | ActiveRecord::RecordNotUnique: Mysql2::Error: Duplicate entry 'antun@example.com' 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: "antun@example.com", 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)

我知道我可以跳过!在 u.save!()但正如我所说,我知道在种子文件中使用它是最佳做法,因此它会失败。 我的问题是:仅在首次使用 docker-compose 运行时创建和播种数据库的正确、最佳实践方法是什么? 一旦它上线,我想确保应用程序的后续更新(可能包括新数据类型的迁移/额外种子)运行顺利,而不会删除数据库中的数据。

这是完整的 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: "antun@example.com", 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")

回复您的评论;恐怕存储库已经无人维护,但您可以使用 branch我就是为此而做的。

如果您看到更改,则可以执行以下操作:
SeedDump.dump(ModelName, method: :find_or_create_by)
# "ModelName.find_or_create_by([\n  {name: \"<name>\", status: nil},\n...)\n"

回答您的最后一条评论和您的问题:

What is the correct way to seed a rails app in docker so it can be started repeatedly



我不知道这是否正确,但很简单;当您使用 MySQL 时,只需使用它提供的工具。您可以从任何环境转储和导入数据,这将保持数据的完整性,这可能会更快且不易出错。

关于ruby-on-rails - 在 docker 中播种 rails 应用程序以便它可以重复启动的正确方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62233831/

相关文章:

javascript - 如何使用 CDN 在我的 Rails 应用程序中包含 jQuery/bootstrap/javascript?

ruby-on-rails - 带有索引操作的自定义事件管理页面

docker - 如何停止 docker pull

php - Docker PHP镜像助手和构建依赖项

Docker-compose 在已安装的卷上设置用户和组

mongodb - 如何使用 docker-compose 和 docker-machine 为 mongoDB 挂载外部卷

javascript - 在不使用任何框架的情况下仅使用 ruby​​ 创建 Web 应用程序

ruby-on-rails - 套接字错误 : HiPay Integration in Rails app (Payment API)

docker容器中的Java服务未连接到主机mysql

docker - 在dockerfile和docker-compose文件中使用 “expose”的区别?