使用docker-compose的Rails应用不会连接到mysql容器

时间:2019-03-30 01:50:35

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

尝试使用docker-compose运行Rails应用程序。我运行docker-compose build,它没有错误完成。然后我运行docker-compose up,两个容器都启动了。然后我运行docker-compose运行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

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: {}

Database.yml

development:
  adapter: mysql2
  encoding: utf8
  database: online_community_development
  pool: 5
  username: root
  password: slumland
  socket: /var/run/mysqld/mysqld.sock
  host: db

Docker的新手,所以甚至不确定我是否正确发出了命令。我需要创建数据库并为其添加种子,并让应用容器连接到该数据库。我认为问题与尝试通过localhost连接有关,但是即使将主机更改为db,我仍然得到相同的结果。任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

您的数据库似乎配置为仅在本地主机上侦听。不幸的是,由于您的应用程序在技术上是组合网络中的另一个网络主机(容器),因此无法使用。尝试让您的数据库在所有网络接口上监听。

答案 1 :(得分:0)

tl; dr:
试试这个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: {}

详细信息:
首先,您的docker-compose文件配置有误。
因此,在讨论您的问题之前,我将对docker-compose.yml文件做一些简短的说明。

links:docker的旧功能,应严格避免:
https://docs.docker.com/compose/compose-file/#links
此外,使用docker-compose

甚至不需要

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

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

编辑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'
    volumes:
    - web-app:/myapp
    ports:
    - "3000:3000"
    depends_on:
    - db
    restart: always

volumes:
  my-db: {}
  web-app: {}

回到您的主要问题:
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 tasks seem to ignore database.yml configuration
也许您可以尝试在DATABASE_URL文件中设置环境变量docker-composeDATABASE_URL=mysql://db
我还建议设置正确的context-environment-variable: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: {}

希望这会有所帮助。

致谢,
赫尔姆西(Hermsi)