【问题标题】:I want to delete "Mysql2 :: Error :: ConnectionError (Unknown MySQL server host 'db' (0)):"我想删除“Mysql2 :: Error :: ConnectionError (Unknown MySQL server host 'db' (0)):”
【发布时间】:2020-02-05 16:43:24
【问题描述】:

环境

- MacOS Mojave 10.14.6
- Ruby 2.6.4
- Rails 5.2.2
- mysql  Ver 8.0.17 for osx10.14 on x86_64 (Homebrew)
- Docker 2.1.0.3

我想实现什么

我想清除以下错误。

Mysql2::Error::ConnectionError (Unknown MySQL server host 'db' (0)):

终端

$ rails s
=> Booting Puma
=> Rails 5.2.2 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.1 (ruby 2.6.4-p104), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://localhost:3000
Use Ctrl-C to stop
Started GET "/" for ::1 at 2019-10-07 22:11:28 +0900

Mysql2::Error::ConnectionError (Unknown MySQL server host 'db' (0)):
...
$ docker-compose ps
      Name                    Command               State           Ports
--------------------------------------------------------------------------------
rails_test_db_1    docker-entrypoint.sh mysqld      Up       3306/tcp, 33060/tcp
rails_test_web_1   bundle exec rails s -p 300 ...   Exit 1

docker-compose.yml

version: '3'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
volumes:
  db-volume:

数据库.yml

# MySQL. Versions 5.0 and up are supported.
#
# Install the MySQL driver
#   gem install mysql2
#
# Ensure the MySQL gem is defined in your Gemfile
#   gem 'mysql2'
#
# And be sure to use new-style password hashing:
#   http://dev.mysql.com/doc/refman/5.7/en/old-client.html
#
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: password
  host: db

development:
  <<: *default
  database: app_development

# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
  <<: *default
  database: app_test

# As with config/secrets.yml, you never want to store sensitive information,
# like your database password, in your source code. If your source code is
# ever seen by anyone, they now have access to your database.
#
# Instead, provide the password as a unix environment variable when you boot
# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database
# for a full rundown on how to provide these environment variables in a
# production deployment.
#
# On Heroku and other platform providers, you may have a full connection URL
# available as an environment variable. For example:
#
#   DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase"
#
# You can use this database configuration with:
#
#   production:
#     url: <%= ENV['DATABASE_URL'] %>
#
production:
  <<: *default
  database: app_production
  username: app
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>

【问题讨论】:

  • db 容器是否正在运行。能否将docker-compose ps 的输出添加到问题中?
  • 对不起。 docker-compose 构建需要时间。
  • 我在终端中添加了 docker-compose ps 结果。
  • 我没有看到名称为 db 的服务未运行(来自 docker-compose ps 输出)。这就是为什么您的 Rails 应用程序无法连接到主机 db 上的 mysql 服务器的原因 通过运行 docker-compose up -d db 运行服务 db
  • 我发现如果你想可靠地使用 docker 容器名称,你需要一个中间人 dns 服务器来将主机名解析为 docker IP。有一些脚本和解决方案可供选择。

标签: mysql ruby-on-rails ruby docker rubygems


【解决方案1】:

该错误告诉您主机 db 未知。

您正在终端上运行rails s。那是在 docker outside 启动您的 Rails 服务器,因此无法解析主机 db。 (对于在同一个 docker 网络中运行的容器,您只有这种 DNS 解析)

您应该只运行 docker-compose up 以便在您的 docker-compose.yml 中定义的 两个 服务(webdb)在同一个网络中启动(docker-compose 负责那个,你不需要为它做任何额外的设置)

【讨论】:

  • 非常感谢!我不需要做任何额外的设置...好的
【解决方案2】:

您可以创建一个网络,该网络将在您的 docker 内的图像之间共享

networks:
  my_network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.25.0.1/16
          gateway: 172.25.0.1

然后为您的数据库容器分配特定的 IP:

networks:
  my_network:
    ipv4_address: 172.25.0.3

之后,您需要确保 db 主机名与数据库容器 IP 链接。 下面的代码会将新行 172.25.0.3 db 添加到您的 /etc/hosts 文件中。

extra_hosts:
  - 'db:172.25.0.3'

docker-compose 的最终版本如下所示:

version: '3'
services:
  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - 3000:3000
    depends_on:
      - db
    tty: true
    stdin_open: true
  extra_hosts:
    - 'db:172.25.0.3'

  db:
    image: mysql:5.7
    volumes:
      - db-volume:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: password
    networks:
      my_network:
        ipv4_address: 172.25.0.3

volumes:
  db-volume:

networks:
  my_network:
    driver: bridge
    ipam:
      driver: default
      config:
        - subnet: 172.25.0.1/16
          gateway: 172.25.0.1

如果您这样做,您可以确定db 主机将始终可用。希望对你有帮助。

【讨论】:

  • 为容器提供静态 IP 是一种非常非常糟糕的方法
猜你喜欢
  • 2019-02-01
  • 2019-02-13
  • 1970-01-01
  • 2020-10-24
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多