我试图将我的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
答案 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
。
答案 2 :(得分:0)
我也有类似的问题,其原因是多方面的。
TL; DR,请确保:
app
容器已正确关联并依赖于您的postgres
容器DATABASE_URL
引用了postgres
容器RAILS_ENV
ENV变量显式设置在app
容器首先,我必须确保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
这将正确创建两个数据库。