I’m on Mac OS Big Sur and running the following Docker versions
$ docker -v
Docker version 20.10.12, build e91ed57
$ docker-compose -v
Docker Compose version v2.2.3
I’m running a Rails 6 app, whose database is configured like so
development:
adapter: mysql2
encoding: utf8
host: host.docker.internal
database: cfs
pool: 5
username: myuser
password: bypass
I have to use “host.docker.internal” so that the Rails app can access the Docker db when running inside of Docker, set up in my docker-compose.yml like so
services:
db:
image: mysql:5.7
command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
restart: always
volumes:
- ./docker/provision/mysql/init:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: bypass
ports:
# <Port exposed> : < MySQL Port running inside container>
- '3306:3306'
expose:
# Opens port 3306 on the container
- '3306'
…
web:
#restart: always
build: ./my-project
ports:
- "3000:3000"
expose:
- '3000'
command: foreman start
volumes:
- ./my-project/:/app
depends_on:
- db
However if I run the app locally without Docker, I have to change my config files to remove “host.docker.internal” and use “127.0.0.1” instead (or localhost).
Is there a way I can set things up so that I have a single database config file that works in both Docker and without Docker such that I don’t have to change the host around?
You can use ERB markup in the database.yml
file, which lets you use an environment variable here. In general I'd suggest making default values for things be whatever default will work in a plain non-Docker development environment.
# config/database.yml
development:
host: <%= ENV['DATABASE_HOST'] || 'localhost' %>
If you're running this in a setup where the database hostname isn't localhost
– it's in a sibling container, or you're using a cloud-hosted database like Amazon RDS – you can set that environment variable.
# docker-compose.yml
version: '3.8'
services:
db:
image: 'mysql:5.7'
et: cetera
web:
build: .
ports:
- '3000:3000'
depends_on:
- db
environment:
DATABASE_HOST: db # <-- will be read in database.yml