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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With