How do I run Rails in Docker? PG::ConnectionBad could not translate host name "pg" to address: No address associated with hostname
Solution 1
Ok, I'll try to answer this:
Usually when this error appears, it probably means that running the db
container returned some errors and it stopped.
I had the same issue and after some digging found that I had
LANG='en_US.UTF-8'
LANGUAGE='en_US:en'
LC_ALL='en_US.UTF-8'
set in my environment variable and that caused the db
container to stop. Therefore as the container was not running, I had no db
host.
Here is how my docker-compose.yml
file looks like:
version: '3'
services:
db:
image: postgres
volumes:
- ./tmp/db:/var/lib/postgresql/data
env_file: .env
app:
build: .
command: bundle exec puma -p 3000 -C config/puma.rb
env_file: .env
volumes:
- .:/app
ports:
- "3031:3000"
depends_on:
- db
Here is config/database.yml
default: &default
adapter: postgresql
encoding: unicode
host: db
pool: 5
username: <%= ENV['POSTGRES_USER'] %>
password: <%= ENV['POSTGRES_PASSWORD'] %>
development:
<<: *default
database: driggl_dev
test:
<<: *default
database: driggl_test
production:
<<: *default
database: driggl_prod
...and the .env
file for development:
POSTGRES_USER=driggl
POSTGRES_PASSWORD=driggl
As I had shared volumes for db data, I removed the tmp/db
folder from the repository just to be sure.
rm -rf tmp/*
then I removed all containers and images
docker rm $(docker ps -q -a) -f
docker rmi $(docker images -q) -f
Finally I spin up containers again:
docker-compose up --build
and everything finally went right.
Summary
- Make sure there is nothing cached somewhere in the system
- Make sure your db container does not return errors while launching.
I hope that will help anyone who'll encounter that problem.
Solution 2
This setup works for me running rails on docker. Basically need to specify a URL so you'll use a .env file to specify the postgres url and you'll change between _development _test and _production using your config/database file just make you add the env. file to your web service docker-compose file:
/docker-compose.yml:
services:
postgres:
image: postgres:9.6
restart: always
environment:
POSTGRES_USER: kunzig #DockerHub postgres docs state this is optional but must be used when password is set. It will also create a db under the supplied username which you'll use to connect to in rails console such as: $docker-compose exec postgres psql -U YourUserNameHere
POSTGRES_PASSWORD: 'whateverPWYouWant'
ports:
- '5432' #Was originally 5432:5432 with the Left hand side being port on host machine, right hand side is the port on the docker container. However I let docker choose the port it will use by supplying because 5432 is running on my local for other projects.
volumes:
- postgres:/var/lib/postgresql/data
web:
build: . #Runs the docker build command on the current directory
links: #Links the listed services to our application so containers can talk to eachother
- postgres
- redis
restart: always
volumes:
- .:/kunzig #Left hand side is current directory of compose file, right hand side is container folder. This needs to be same as Install_path folder in Dockerfile.
ports:
- '8000:8000' #Left is the local port and the right side is the container port
env_file:
- .YourProjectNameHere.env #This should be in your root project directory along side the Dockerfile and docker-compose file
depends_on:
- 'redis'
- 'postgres'
/.projectname.env
DATABASE_URL=postgresql://PostgresUserNameHere:PasswordFromDockerCompose@postgres:5432/PostgresUsername?encoding=utf8&pool=5&timeout=5000
/config/database.yml
development:
url: <%= ENV['DATABASE_URL'].gsub('?', '_development?' ) %>
test:
url: <%= ENV['DATABASE_URL'].gsub('?', '_test?' ) %>
production:
url: <%= ENV['DATABASE_URL'].gsub('?', '_production?' ) %>
Keep your web service linked with the pg service as you have it and you should be good to go just note I called my service postgres instead.
Solution 3
I had this same issue. For the life of me I could not figure out why it was happening. Debugged for quite a while, but could not figure out how to make the container_name
for the db container resolve within my database.yml
file. Even weirder was the fact that in a different computer the same configuration was working totally fine.
Eventually I found out that if you use host.docker.internal
it is essentially the equivalent of localhost
within Docker.
So I changed my database.yml
file to be:
default: &default
adapter: postgresql
encoding: unicode
host: host.docker.internal
port: 5432
username: <%= ENV['DATABASE_USERNAME'] %>
password: <%= ENV['DATABASE_PASSWORD'] %>
And it all worked out. Mind you I have heard this does not work in Unix systems. I am using OS X and this works fine.
Chloe
Updated on June 20, 2022Comments
-
Chloe almost 2 years
I tried to follow the guide here: https://docs.docker.com/compose/rails/
docker-compose.yml
version: '3' services: pg: ######### LOOK HERE! image: postgres volumes: - ./tmp/db:/var/lib/postgresql/data web: build: . command: bundle exec rails server -p 3000 -b '0.0.0.0' volumes: - .:/app ports: - "3000:3000" depends_on: - pg links: - pg ######### LOOK HERE! cms: image: joomla restart: always links: - mysql:joomladb ports: - 8080:80 environment: JOOMLA_DB_HOST: mysql JOOMLA_DB_PASSWORD: example mysql: image: mysql:5.6 restart: always environment: MYSQL_ROOT_PASSWORD: example
config/database.yml
# SQLite version 3.x # gem install sqlite3 # # Ensure the SQLite 3 gem is defined in your Gemfile # gem 'sqlite3' # default: &default adapter: postgresql encoding: unicode pool: 5 timeout: 5000 host: pg ######### LOOK HERE! username: postgres password: development: <<: *default database: project # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: <<: *default database: project_test production: <<: *default database: project
Console
C:\Users\Chloe\workspace\project\src>docker-compose run web rake db:create Starting src_pg_1 ... done could not translate host name "pg" to address: No address associated with hostname Couldn't create database for {"adapter"=>"postgresql", "encoding"=>"unicode", "pool"=>5, "timeout"=>5000, "host"=>"pg", "username"=>"postgres", "password"=>nil, "database"=>"project"} rake aborted! PG::ConnectionBad: could not translate host name "pg" to address: No address associated with hostname
docker-compose version 1.20.1, build 5d8c71b2, Docker version 18.03.0-ce, build 0520e24302
-
Chloe about 6 yearsBut you still use the hostname
@postgres:5432
so if it can't find the hostname now, how will it by using a URL containing the hostname? -
JosephK almost 5 yearsThere must be a way to do this without combining the containers in one compose file, and building them together. Docker has its own network - how to address to it in the database.yml file?
-
Toshihiro Yokota over 3 yearsThis answer saved my day.