简体   繁体   中英

Docker-compose : unable to connect to mysql from rails app first time , next run it works

I am creating developer environment for rails app using docker, docker-compose and docker-sync. When I run docker-compose up first time it builds the image of my rails app and downloads mysql image, but not able to connect it, but if I quit this and run docker-compose up again everything works fine. Here are my docker configurations

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"]

Below is my 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 file for volume syncing

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

volumes:
   rails_app_volume_sync:
      external: true   

docker-sync file

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

environment files:

web_env:
DATABASE_HOST=db
RAILS_ENV=development

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

and my database config is as follows:

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

when I run docker-sync-stack start I get the following error after the images are build.

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

if I stop the containers and run it again, its working, why is it failing first time ?

The problem is that you aren't waiting for the database to be ready before running the migrations. depends_on only guarantee that your mysql process in the container is started but it has no way to know when the mysql process has initialized and available to process new connections.

A solution can be to wait for the TCP port to be up, some use wait-for-it for it. Another solution is to simply fail and restart the container until the database is ready (set the Restart Policy of the container to always).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM