Docker Compose:Rails不会尊重DATABASE_URL以连接到Postgres

时间:2017-05-19 12:19:02

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

我试图将我的Ruby on Rails 5.1.0应用程序容器化,但我遇到了一些麻烦,因为它没有从环境中获取DATABASE_URL。在docker-compose.yml中,我有以下服务:

app:
  build: .
  command: bundle exec rails s -p 3000 -b '0.0.0.0'
  volumes:
    - .:/myapp
  environment:
    DATABASE_URL: postgres://postgres:pw@db:5432/myapp_development

如果我运行docker-compose run app rails c

,环境就会好起来
$ docker-compose run app rails c
Running via Spring preloader in process 25
Loading development environment (Rails 5.1.0)
irb(main):001:0> ENV['DATABASE_URL']
=> "postgres://postgres:pw@db:5432/myapp_development"

但是如果我运行docker-compose run app rake db:create,则会收到有关无法连接到localhost的错误消息:

$ docker-compose run app rake db:create
Database 'myapp_development' already exists
could not connect to server: Connection refused
    Is the server running on host "localhost" (::1) and accepting
    TCP/IP connections on port 5432?
could not connect to server: Connection refused
    Is the server running on host "localhost" (127.0.0.1) and accepting
    TCP/IP connections on port 5432?
Couldn't create database for {"adapter"=>"postgresql", "host"=>"localhost", "pool"=>10, "timeout"=>5000, "database"=>"myapp_test"}
rake aborted!

知道我在这里做错了吗?

编辑:这是database.yml的样子:

common: &common
  adapter: postgresql
  pool: 10
  timeout: 5000

development:
  <<: *common
  database: myapp_development

test:
  <<: *common
  database: myapp_test

production:
  <<: *common
  database: myapp_production

4 个答案:

答案 0 :(得分:1)

我遇到了同样的问题,似乎在Rails 5.1.x上以某种方式打破了配置合并

您可以在DATABASE_URL区块中添加url: <%= ENV['DATABASE_URL'] %>来强制使用default

答案 1 :(得分:0)

问题在于rake任务,它正在尝试创建测试数据库,我假设您的database.yml具有localhost主机的测试环境。

来自rake db:create

的说明
  

从DATABASE_URL或 config / database.yml 创建数据库   当前RAILS_ENV(使用db:create:all创建所有数据库   配置)。 没有RAILS_ENV,它默认创建开发和   测试数据库

你应该明确地传递env,否则它可以默认创建一个测试数据库。

我建议您更改database.yml

中的测试数据库凭据

Connection Preference

答案 2 :(得分:0)

我也有类似的问题,其原因是多方面的。

TL; DR,请确保:

  1. 您的app容器已正确关联并依赖于您的postgres容器
  2. 您的DATABASE_URL引用了postgres容器
  3. 的正确主机名
  4. RAILS_ENV ENV变量显式设置在app容器
  5. 首先,我必须确保app中的docker_compose.yml容器已链接到postgres容器并依赖它:

    version: '3'
        services:
          app:
            container_name: 'app'
            depends_on:
              - postgres
            links:
              - postgres
    

    其次,我提供的DATABASE_URL ENV变量database.yml没有引用postgres容器的正确主机名。最初,我看起来像:

    'postgres://postgres:@localhost:5432/my_app_development'

    我把它改为:

    'postgres://postgres:@postgres:5432/my_app_development'

    在您的案例中不是一个明显的问题,但值得注意其他人。

    第三,我没有明确指定RAILS_ENV环境。我在development中将ENV变量设置为docker_compose.yml,以便使用正确的database.yml配置。

    我的database.yml文件的最终结果:

    development: &default
      adapter: postgresql
      encoding: unicode
      database: my_app_development
      username: postgres
      pool: 5
      timeout: 5000
      url: <%= ENV['DATABASE_URL'] %>
    
    test:
      <<: *default
      database: my_app_test
      pool: 5
      url: <%= ENV['DATABASE_URL'] %>
    
    production:
      <<: *default
      url: <%= ENV['DATABASE_URL'] %>
    

    我的docker_compose.yml文件的最终结果:

    version: '3'
    services:
      app:
        container_name: 'app'
        environment:
          DATABASE_URL: 'postgres://postgres:@postgres:5432/my_app_development'
          RAILS_ENV: 'development'
        build: .
        ports:
          - '3000:3000'
        volumes:
          - ./:/dev
        depends_on:
          - postgres
        links:
          - postgres
        tty: true
    
      postgres:
        container_name: 'postgres'
        image: postgres:9.5
        ports:
          - '5432:5432'
        environment:
          POSTGRES_USER: postgres
          POSTGRES_PASSWORD:
    

    之后,所有bundle exec rake db:命令都运行正常。

    希望有所帮助!

答案 3 :(得分:0)

我认为@Зелёныйenter's answer基本上是正确的,问题在于rake任务正在尝试创建用于开发和测试的数据库。

Database 'myapp_development' already exists

可能在这里,是因为该数据库是在同一命令的先前执行中创建的,该命令创建了该数据库,但也未能尝试创建测试数据库。

人们会认为,通过在URL中指定数据库名称,在本例中为myapp_development

DATABASE_URL: postgres://postgres:pw@db:5432/myapp_development

那将是唯一要创建的数据库,但不是。我使用DATABASE_URL时未指定数据库名称,例如:

DATABASE_URL: postgres://postgres:pw@db:5432

结果相同,其中一个创建,一个失败。

但是,据我了解,这不是RAILS_ENV定义的问题。根据{{​​3}},关于这个主题的问题,这是预期的行为,顺便说一下,这个问题还在讨论中。

到目前为止,有this comment:两个是gems,另一个是对database.yml的修改或删除。

一种可行的database.yml是:

default: &default
  adapter: postgresql
  encoding: unicode
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  url: <%= ENV['DATABASE_URL'] %>

development:
  <<: *default
  database: app_development

test:
  <<: *default
  database: app_test

这将正确创建两个数据库。