Reputation: 61
Trying to get a rails app running using docker-compose. I run docker-compose build and it completes with no errors. I then run docker-compose up and both of the containers start. Then I run docker-compose run web rake db:create db:migrate and run into an error:
rake aborted! Mysql2::Error::ConnectionError: Can't connect to MySQL server on '127.0.0.1' (111 "Connection refused")
My 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
New to docker so not even sure if I am issuing the commands correctly. I need to create and seed the database and have the app container connect to it. I think the issue is related to it trying to connect via localhost, but even when I changed the host to db I still got the same results. Any help would be greatly appreciated.
Upvotes: 5
Views: 3264
Reputation: 251
tl;dr:
Try this 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: {}
In detail:
First of all your docker-compose
-file is kinda misconfigured.
Therefore I will do a small instruction on docker-compose.yml
-files before heading over to your question.
The links:
-thing is a legacy feature of docker
which you should strictly avoid:
https://docs.docker.com/compose/compose-file/#links
Moreover, it is not even required when you're working with docker-compose
Also, you're using expose:
and ports:
when defining your database-service.
The ports
-key is opening up a port on your host-machine and forwards it to your docker-service:
https://docs.docker.com/compose/compose-file/#ports
Using ports
-key on database-definitions makes your database accessible to the www - which is not what you want in most cases.
The expose
-key opens the port locally, in the created docker network.
https://docs.docker.com/compose/compose-file/#expose
This is what we want for databases.
Editing your docker-compose.yml
-file results in the following:
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: {}
Getting back to your primary problem:
rake aborted! Mysql2::Error::ConnectionError: Can't connect to MySQL server on '127.0.0.1' (111 "Connection refused")
It looks like rake
expects the database to be available at localhost
- therefore I think that the cause of this issue is a misconfiguration.
Unfortunately I'm not very familiar with rake
but nevertheless your database.yaml
looks correct.
I did some research and came across this post:
Rake tasks seem to ignore database.yml configuration
Maybe you could try to set the environment-variable DATABASE_URL
in your docker-compose
-file: DATABASE_URL=mysql://db
I'd also recommend to set the correct context-environment-variable: RAILS_ENV=development
When you do alle these changes you should come up with the following 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: {}
Hope this helps.
Regards,
Hermsi
Upvotes: 5
Reputation: 21285
your db seems to be configured to listen on localhost only. Unfortunately this will not work since your app is technically another network host (container) within the compose network. Try making your db listen on all network interfaces.
Upvotes: -1