mysql - Docker-compose : unable to connect to mysql from rails app first time , 下次运行就可以了

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

我正在使用 docker、docker-compose 和 docker-sync 为 Rails 应用创建开发环境。当我第一次运行 docker-compose up 时,它会构建我的 Rails 应用程序的镜像并下载 mysql 镜像,但无法连接它,但如果我退出并再次运行 docker-compose up 一切正常。这是我的 docker 配置

Dockerfile:
FROM ruby:2.5.1

RUN apt-get update && \
      apt-get -y install sudo

RUN apt-get update && apt-get install -y \ 
  build-essential \ 
  nodejs \
  vim \
  mysql-client \
  apt-transport-https \
  build-essential

RUN curl -s -N https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -\
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list \
    && apt-get update \
    && apt-get install -y yarn 

RUN mkdir /rails-app
ENV RAILS_HOME /rails-app


WORKDIR /tmp
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install

WORKDIR /rails-app
ADD . /rails-app

EXPOSE 3000
CMD ["bash"]

下面是我的docker-compose

docker-compose.yml
version: '3'
services:
    web:
      image: "rails_app"
      build: .
      ports:
        - "3000:3000"
      env_file:
        - web_env
        - db_env
      depends_on:
        - db
      command: >
          bash -c "bundle exec rails db:schema:load &&
                   bundle exec rails db:seed &&
                   rm -f tmp/pids/server.pid &&
                   bundle exec rails s -p 3000 -b '0.0.0.0'"
    db:
      image: library/mysql:5.6.42
      env_file:
        - db_env

用于卷同步的 docker-compose dev 文件

docker-compose-dev.yml
version: '3'
services:
      web:
         volumes:
            - rails_app_volume_sync:/rails-app:nocopy

volumes:
   rails_app_volume_sync:
      external: true   

docker同步文件

docker-sync.yml
version: "2"
syncs:
    rails_app_volume_sync:
       src: '.'
       sync_host_ip: 'auto'
       sync_strategy: 'unison'
       notify_terminal: true

环境文件:

web_env:
DATABASE_HOST=db
RAILS_ENV=development

db_env:
MYSQL_DATABASE=development_exp
MYSQL_ROOT_PASSWORD=root
MYSQL_USER=dev
MYSQL_PASSWORD=dev

我的数据库配置如下:

development:
  adapter: mysql2
  encoding: utf8
  database: <%= ENV['MYSQL_DATABASE'] %>
  username: <%= ENV['MYSQL_USER'] %>
  password: <%= ENV['MYSQL_PASSWORD'] %>
  host: <%= ENV['DATABASE_HOST'] %>
  reconnect: true
  pool: 5

当我运行 docker-sync-stack start 时,我在构建图像后收到以下错误。

web_1  | Mysql2::Error::ConnectionError: Can't connect to MySQL server on 'db' (111 "Connection refused")

如果我停止容器并再次运行它,它可以正常工作,为什么第一次失败了?

最佳答案

问题是您在运行迁移之前没有等待数据库准备就绪。 depends_on 仅保证容器中的 mysql 进程已启动,但无法知道 mysql 进程何时已初始化并可用于处理新连接。

一个解决方案是等待 TCP 端口启动,有些使用 wait-for-it为了它。另一种解决方案是简单地失败并重新启动容器,直到数据库准备就绪(将容器的重启策略设置为始终)。

关于mysql - Docker-compose : unable to connect to mysql from rails app first time , 下次运行就可以了,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53091622/

相关文章:

ruby-on-rails - ActiveRecord::Relation#bind 的目的是什么?

ruby-on-rails - 将模块加载到 Rails 中的用户模型中

docker - docker stats不显示流视频容器的ZERO Net I/O

php - Yii2.0完整登录基本模板

mysql - 将较慢的数据插入到 mySQL 中

ruby-on-rails - 我无法使用 View 将 activeRecord 对象保存在旧表中

windows - HttpListener(.NET Core)不适用于 Windows docker 上的 https

wordpress - Docker用户权限说明

mysql - 如何创建 Cron 作业来将 MySQL 和 FTP 备份备份到我的备份服务器?

MYSQL UPDATE 行匹配基于变量的条件