Run Docker Rails Application Which Can Access Mysql Running at same Host in Mac OS and Linux

By | 2018 年 3 月 11 日

Docker Mac Native has been released for a long time. It improves the performance of docker runtime in Mac OSX. But --net=host won’t work as expected as on Linux OS.

This article introduced a setup/configuration for rails application/web application running in docker but connect to mysql hosted on the same host of docker container (Mac OSx specifically).

The structure looks like:

Host
-- mysql server running here
-- docker run --net=host rails_app

There lays 2 problems:

  1. How can we visit the web service running in a docker in this case?

  2. How can the application in docker access the mysql service hosted outside the docker container?

How can we visit the web service running in a docker in this case?

In linux, this is as simple as docker run --net=host rails_app (by default it use port 3000), then we can visit the app as http://$host_ip:3000.

Because with --net-host we can consider the docker instance’s network interface running at the same level of the host. When rails application opened port 3000 in docker, it actually opened a port 3000 on the Linux server.

However, the --net=host won’t work as expected in Mac OSX compare to Linux system. Because the docker container is still running in a VM as:

Mac OS
-- VM host docker container
-- -- the rails application docker instance

The --net=host just opened the network interface to that VM which docker container is running but not Mac OS directly. Thus in order to have it accessible, we need specify -p 3000:3000 instead of --net=host. The cmd becomes as:

docker run -p 3000:3000 rails_app

With this setup, we can visit the rails application by http://$host_ip:3000, if you develop on the Mac OS it self, just http://localhost:3000 will work.

How can the application in docker access the mysql service hosted outside the docker container?

In Linux

In Linux, we can let mysql server listening the 127.0.0.1 address as (in my.cnf):

# localhost which is more compatible and is not less secure.
bind-address        = 127.0.0.1

And open proper permission for the mysql user as (in mysql prompt):

CREATE USER 'root'@'127.0.0.1' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'127.0.0.1' WITH GRANT OPTION;

In rails application, config the mysql host as:

development:
  adapter: mysql2
  encoding: utf8
  pool: 5
  database: some_database
  username: root
  password: password
  host: 127.0.0.1

In Mac OS

However, this won’t work in Mac OS due to the VM in the middle. Instead, we need the Mysql server to listen specific ip of the docker instance or just bind to 0.0.0.0:

In my.cnf:

# localhost which is more compatible and is not less secure.
bind-address        = 0.0.0.0

And open proper permission for the mysql user as (in mysql prompt):

CREATE USER 'username'@'%' IDENTIFIED BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' WITH GRANT OPTION;

In rails application, config the mysql host as:

development:
  adapter: mysql2
  encoding: utf8
  pool: 5
  database: some_database
  username: username
  password: password
  host: <%= MAC_IP_ADDRESS %>

发表评论

电子邮件地址不会被公开。 必填项已用*标注