【问题标题】:Can't run rake db:create in Dockerfile with docker-compose无法使用 docker-compose 在 Dockerfile 中运行 rake db:create
【发布时间】:2015-07-21 10:02:29
【问题描述】:

我有一个 Dockerfiledocker-compose.yml 就像在 tutorial 中一样,除了我从现有应用程序开始。

我的docker-compose.yml 看起来像:

db:
  image: postgres
  ports:
    - "5432"
web:
  build: .
  command: bundle exec rails s -p 3000 -b '0.0.0.0'
  volumes:
    - .:/myapp
  ports:
    - "3030:3030"
  links:
    - db

Dockerfile:

FROM ruby:2.1.4
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
RUN mkdir /myapp
WORKDIR /myapp
ADD Gemfile /myapp/Gemfile
RUN bundle install
ADD . /myapp
# RUN bundle exec rake db:create
# RUN bundle exec rake db:migrate
# RUN bundle exec rake db:seed

database.yml

development:
  adapter: postgresql
  encoding: utf8
  database: myapp_development
  host: db
  pool: 5
  username: postgres
  password:

如你所见,我评论了RUN bundle exec rake db:create,因为我收到了一个错误:

could not translate host name "db" to address: Name or service not known
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/postgresql_adapter.rb:1222:in `initialize'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/postgresql_adapter.rb:1222:in `new'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/postgresql_adapter.rb:1222:in `connect'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/postgresql_adapter.rb:324:in `initialize'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/postgresql_adapter.rb:28:in `new'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/postgresql_adapter.rb:28:in `postgresql_connection'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_pool.rb:315:in `new_connection'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_pool.rb:325:in `checkout_new_connection'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_pool.rb:247:in `block (2 levels) in checkout'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_pool.rb:242:in `loop'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_pool.rb:242:in `block in checkout'
/usr/local/lib/ruby/2.1.0/monitor.rb:211:in `mon_synchronize'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_pool.rb:239:in `checkout'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_pool.rb:102:in `block in connection'
/usr/local/lib/ruby/2.1.0/monitor.rb:211:in `mon_synchronize'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_pool.rb:101:in `connection'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_pool.rb:410:in `retrieve_connection'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_specification.rb:171:in `retrieve_connection'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/connection_adapters/abstract/connection_specification.rb:145:in `connection'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/railties/databases.rake:144:in `rescue in create_database'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/railties/databases.rake:85:in `create_database'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/railties/databases.rake:62:in `block (3 levels) in <top (required)>'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/railties/databases.rake:62:in `each'
/usr/local/bundle/gems/activerecord-3.2.21/lib/active_record/railties/databases.rake:62:in `block (2 levels) in <top (required)>'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/task.rb:240:in `call'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/task.rb:240:in `block in execute'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/task.rb:235:in `each'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/task.rb:235:in `execute'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/task.rb:179:in `block in invoke_with_call_chain'
/usr/local/lib/ruby/2.1.0/monitor.rb:211:in `mon_synchronize'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/task.rb:172:in `invoke_with_call_chain'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/task.rb:165:in `invoke'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/application.rb:150:in `invoke_task'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/application.rb:106:in `block (2 levels) in top_level'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/application.rb:106:in `each'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/application.rb:106:in `block in top_level'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/application.rb:115:in `run_with_threads'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/application.rb:100:in `top_level'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/application.rb:78:in `block in run'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/application.rb:176:in `standard_exception_handling'
/usr/local/bundle/gems/rake-10.4.2/lib/rake/application.rb:75:in `run'
/usr/local/bundle/gems/rake-10.4.2/bin/rake:33:in `<top (required)>'
/usr/local/bundle/bin/rake:16:in `load'
/usr/local/bundle/bin/rake:16:in `<main>'
Couldn't create database for {"adapter"=>"postgresql", "encoding"=>"utf8", "database"=>"myapp_development", "host"=>"db", "pool"=>5, "username"=>"postgres", "password"=>nil}

我不得不docker-compose build 然后 docker-compose run web rake db:create 等等。

为什么我不能在 Dockerfile 中创建 db-creation/migration。会清楚很多。我能做到吗?

【问题讨论】:

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


    【解决方案1】:

    当您的web 映像构建时(按照Dockerfile 的说明),它没有与db 容器的连接。

    网络服务器和数据库图像是独立的并且容器在您启动它们时链接(遵循docker-compose.yml文件的定义)。

    您不能在映像构建过程中链接到容器,因为它会破坏映像构建必须是可重现的原则。同样,您也不能在映像构建期间从主机装载卷。

    您使用的docker-compose run web rake db:create 命令是初始化数据库的正确方法。

    或者,您可以使用docker-compose 正常启动容器,然后使用docker exec 命令在web 容器中执行rake db:create

    【讨论】:

    • 那么解决方案是什么?创建一个run rake db:setup的shell脚本?并启动容器?
    • 我认为没有必要编写脚本来执行这两个操作,因为rake db:setup 应该只执行一次。您无需在每次启动容器时都运行它。
    • 那么为什么他们在官方文档中说我们必须在重启容器时docker-compose run web rake db:createdocs.docker.com/compose/rails/#restart-the-application
    • 他们不会,除非文档在您发表评论后发生了变化。官方 Postgres 图像在 /var/lib/postgresql/data 上附带一卷:github.com/docker-library/postgres/blob/…。所以重启容器时不需要运行迁移。
    • 但是,如果您使用 docker-compose rm 删除容器,则必须运行迁移
    【解决方案2】:

    以下是正确的顺序

    ❯ docker-compose run web rake db:create
    Starting devops-hello-world_db_1 ... done
    Creating devops-hello-world_web_run ... done
    Created database 'myapp_development'
    Created database 'myapp_test'
    
    ❯ docker-compose up
    devops-hello-world_db_1 is up-to-date
    Starting devops-hello-world_web_1 ... done
    ...
    

    【讨论】:

      【解决方案3】:

      您可能希望将 /tmp/db 挂载到您的 postgres 容器的 /var/lib/postgresql/data

      通过该数据库将同步到您的主机,并且在您下次重新启动/重建应用程序时,该数据库将自动初始化。这样做必须运行docker-compose run web rake db:create 只运行一次,当您像本地设置项目时一样,从那时起继续使用docker-compose run web rake db:create 等。

      version: '3'
      services:
        db:
          image: postgres
          volumes:
            - ./tmp/db:/var/lib/postgresql/data # Here you go!
        web:
          build: .
          command: bundle exec rails s -p 3000 -b '0.0.0.0'
          volumes:
            - .:/myapp
          ports:
            - "3000:3000"
          depends_on:
            - db
      

      我真的很想知道为什么他们没有将其写入您链接的文档中。我打开了一个 PR 来添加这个。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-25
        • 1970-01-01
        • 1970-01-01
        • 2022-09-05
        • 1970-01-01
        • 2021-07-26
        • 1970-01-01
        相关资源
        最近更新 更多