Ruby on rails 在docker中植入rails应用程序以便重复启动的正确方法是什么

Ruby on rails 在docker中植入rails应用程序以便重复启动的正确方法是什么,ruby-on-rails,docker,docker-compose,Ruby On Rails,Docker,Docker Compose,我有一个rails应用程序,它的数据库是mysql,我正在尝试将其docker化,因此我最终可以使用docker machine部署它。当我第一次运行docker compose up时,它会正确初始化并为数据库种子,就像它应该的那样。但是,在我关闭它之后,第二次运行docker compose up,它失败了,出现以下错误,因为种子内容已经存在: web_1 | ActiveRecord::RecordNotUnique: Mysql2::Error: Duplicate entry

我有一个rails应用程序,它的数据库是mysql,我正在尝试将其docker化,因此我最终可以使用
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中保存!()
但正如我所说,我知道在seeds文件中使用它是一种最佳做法,因此它会失败我的问题是:使用docker compose仅在第一次运行时创建和植入DB的正确最佳实践方法是什么?一旦启动,我希望确保应用程序的后续更新(可能包括新数据类型的迁移/附加种子)顺利进行,而不会擦除数据库中的数据

以下是完整的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
请改为尝试:


回答你的评论;很抱歉,存储库已经没有维护,但是您可以使用我刚才为此制作的

如果看到更改,您可以执行以下操作:

SeedDump.dump(ModelName, method: :find_or_create_by)
# "ModelName.find_or_create_by([\n  {name: \"<name>\", status: nil},\n...)\n"
SeedDump.dump(ModelName,method::find\u或\u create\u by)
#ModelName.find\u或create\u by([\n{name:\“\,status:nil},\n..)\n

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

在docker中植入rails应用程序以便重复启动的正确方法是什么


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

这可能会起作用,但我使用的是seed\u dump gem()生成种子文件,它会根据我在开发过程中手动执行的一些初始设置自动生成种子文件。我当然可以修改它们,但这样会破坏使用种子转储的好处。我非常感谢这里的输入,我认为您的方法会在种子时解决错误。但是,我正在构建的图片Eyeslandic在这个问题上的评论,以及更多的挖掘是:我不应该直接在docker compose.yml`命令中运行
rake db:create db:migrate db:seed
。嗯,这是真的@antun。你通常做的只是在可能产生的更改之后用Rails任务迁移数据库。以及处理来自您的生产数据库您可以通过许多DBMS提供的命令行将数据转储并导入到您的开发环境中。我不认为使用此库有什么意义,当dbs存储许多信息时,它比DBMS可能提供的选项慢。我肯定要维护数据。我是Docker的新手,所以我正在寻找使用Rails种子/创建数据库的正确方法。我遵循的指南是docker-compose.yml文件中有
bundle exec rake db:create db:migrate
。我只是简单地将
db:seed
添加到了该位置。你是在暗示我应该将所有这些文件从docker-compose.yml文件中移到docker文件中?还是有没有办法在docker-compose.yml中放入一些东西,这样它就只能第一次运行?我感觉到你的痛苦,docker很难进入IMO,有时对我来说似乎不值得。无论如何,这可能对你的文档有所帮助,他们建议的方法似乎不是自动创建数据库,而是让用户手动创建数据库通过运行
docker compose run web rake db:create
来使用它。这真的是这么做的吗?对我来说,它似乎非常不适合docker,因为它需要用户知道运行哪些命令才能进行设置和部署。我无论如何都不是docker专家,但我就是这样做的。这里讨论了其他选项
SeedDump.dump(ModelName, method: :find_or_create_by)
# "ModelName.find_or_create_by([\n  {name: \"<name>\", status: nil},\n...)\n"