使用 docker-compose 的 Rails 应用程序无法连接到 mysql 容器

Yun*_*zzy 5 mysql ruby-on-rails docker docker-compose

尝试使用 docker-compose 运行 Rails 应用程序。我运行 docker-compose build 并且它没有错误地完成。然后我运行 docker-compose up 并启动​​两个容器。然后我运行 docker-compose run web rake db:create db:migrate 并遇到错误:

耙子中止!Mysql2::Error::ConnectionError: 无法连接到“127.0.0.1”上的 MySQL 服务器(111“连接被拒绝”)

我的 Dockerfile:

FROM ruby:2.5.3
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs mysql-client sqlite3 zlib1g-dev libxslt-dev git  && \
gem install bundler
RUN mkdir /myapp
WORKDIR /myapp
COPY Gemfile /myapp/Gemfile
COPY Gemfile.lock /myapp/Gemfile.lock
RUN bundle install
COPY . /myapp
Run Code Online (Sandbox Code Playgroud)

Docker-compose

version: '3.3'
services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: 'online_community_development'
      MYSQL_ROOT_PASSWORD: '******'
      MYSQL_HOST: 'localhost'
    ports:
      # <Port exposed> : < MySQL Port running inside container>
      - '3306:3306'
    expose:
      # Opens port 3306 on the container
      - '3306'
      # Where our data will be persisted
    volumes:
      - 'my-db:/var/lib/mysql'
    container_name: datab




  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
    - web-app:/myapp
    ports:
    - "3000:3000"
    depends_on:
    - db
    links:
      - db:db
    restart: always

volumes:
  my-db: {}
  web-app: {}
Run Code Online (Sandbox Code Playgroud)

数据库.yml

development:
  adapter: mysql2
  encoding: utf8
  database: online_community_development
  pool: 5
  username: root
  password: slumland
  socket: /var/run/mysqld/mysqld.sock
  host: db
Run Code Online (Sandbox Code Playgroud)

docker 新手,所以甚至不确定我是否正确发出命令。我需要创建和播种数据库,并让应用程序容器连接到它。我认为这个问题与尝试通过本地主机连接有关,但即使我将主机更改为 db,我仍然得到相同的结果。任何帮助将不胜感激。

Her*_*337 5

tl;博士:
试试这个docker-compose.yml

version: '3.3'
services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: 'online_community_development'
      MYSQL_ROOT_PASSWORD: '******'
      MYSQL_HOST: 'localhost'
    expose:
    # Opens port 3306 on the container
      - '3306'
    # Where our data will be persisted
    volumes:
      - 'my-db:/var/lib/mysql'
    container_name: datab

  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    environment:
      DATABASE_URL: 'mysql2://db'
      RAILS_ENV: 'development'
    volumes:
    - web-app:/myapp
    ports:
    - "3000:3000"
    depends_on:
    - db
    restart: always

volumes:
  my-db: {}
  web-app: {}
Run Code Online (Sandbox Code Playgroud)

详细说明:
首先,您的docker-compose-file 配置错误。
因此docker-compose.yml,在转到您的问题之前,我将对-files做一个小说明。

links:-thing是一个传统的功能docker,你应该严格避免:
https://docs.docker.com/compose/compose-file/#links
此外,它甚至不要求当你正在使用docker-compose

此外,您正在使用expose:ports:定义数据库服务时。
ports键后才您的主机计算机上打开一个端口并将其转发给您的搬运工服务:
https://docs.docker.com/compose/compose-file/#ports
使用ports-key对数据库的定义,使您的数据库可访问 www - 在大多数情况下这不是您想要的。

expose-键打开本地端口,创建搬运工网络。
https://docs.docker.com/compose/compose-file/#expose
这就是我们想要的数据库。

编辑您的docker-compose.yml-file 结果如下:

version: '3.3'
services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: 'online_community_development'
      MYSQL_ROOT_PASSWORD: '******'
      MYSQL_HOST: 'localhost'
    expose:
    # Opens port 3306 on the container
      - '3306'
    # Where our data will be persisted
    volumes:
      - 'my-db:/var/lib/mysql'
    container_name: datab

  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
    - web-app:/myapp
    ports:
    - "3000:3000"
    depends_on:
    - db
    restart: always

volumes:
  my-db: {}
  web-app: {}
Run Code Online (Sandbox Code Playgroud)

回到你的主要问题:
rake aborted! Mysql2::Error::ConnectionError: Can't connect to MySQL server on '127.0.0.1' (111 "Connection refused")

看起来rake希望数据库可用localhost- 因此我认为这个问题的原因是配置错误。
不幸的是,我不是很熟悉,rake但你database.yaml看起来是正确的。
我做了一些研究并发现了这篇文章:
Rake 任务似乎忽略了 database.yml 配置
也许您可以尝试DATABASE_URL在您的docker-compose-file 中设置环境变量:DATABASE_URL=mysql://db
我还建议设置正确的上下文环境变量:RAILS_ENV=development

当您进行所有这些更改时,您应该想出以下内容docker-compose.yml

version: '3.3'
services:
  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: 'online_community_development'
      MYSQL_ROOT_PASSWORD: '******'
      MYSQL_HOST: 'localhost'
    expose:
    # Opens port 3306 on the container
      - '3306'
    # Where our data will be persisted
    volumes:
      - 'my-db:/var/lib/mysql'
    container_name: datab

  web:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    environment:
      DATABASE_URL: 'mysql2://db'
      RAILS_ENV: 'development'
    volumes:
    - web-app:/myapp
    ports:
    - "3000:3000"
    depends_on:
    - db
    restart: always

volumes:
  my-db: {}
  web-app: {}
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助。

问候,
赫姆西