How to setup Rails, Docker, PostgreSQL (and Heroku) for local development ?
My current side project is an online tool to do remote planning pokers. I followed my previous tutorial to setup Rails, Docker and Heroku.
Naturally, as a BDD proponent, I tried to install cucumber to write my first scenario.
Here is the result of my first cucumber run :
$ docker-compose run shell bundle exec cucumber
rails aborted!
PG::ConnectionBad: could not translate host name "postgres://postgres:@herokuPostgresql:5432/postgres" to address: Name or service not known
...
It turned out that I had taken instructions from a blog article on codeship that mistakenly used host:
instead of url:
in their config/database.yml
After fixing that in my database.yml file, things where only slightly working better :
$ docker-compose run shell bundle exec cucumber
rails aborted!
ActiveRecord::StatementInvalid: PG::ObjectInUse: ERROR: cannot drop the currently open database
: DROP DATABASE IF EXISTS "postgres"
The thing is the config was still using the same database for all environments. That’s not exactly what I wanted. I updated my config/database.yml
:
default: &default
adapter: postgresql
encoding: unicode
pool: 5
timeout: 5000
username: postgres
port: 5432
host: herokuPostgresql
development:
<<: *default
database: planning_poker_development
test: &test
<<: *default
database: planning_poker_test
production:
<<: *default
url: <%= ENV['DATABASE_URL'] %>
Victory ! Cucumber is running
$ docker-compose run shell bundle exec cucumber
Using the default profile...
0 scenarios
0 steps
0m0.000s
Run options: --seed 45959
# Running:
Finished in 0.002395s, 0.0000 runs/s, 0.0000 assertions/s.
0 runs, 0 assertions, 0 failures, 0 errors, 0 skips
Fixing rake db:create
By searching through the web, I found that people were having similar issues with rake db:create. I tried to run it and here is what I got :
$ docker-compose run shell bundle exec rake db:create
Database 'postgres' already exists
Database 'planning_poker_test' already exists
Why is it trying to create the postgres database ? It turns out that the DATABASE_URL takes precedence over what is defined in my config/database.yml
. I need to unset this variable locally. I already have the docker-compose.override.yml
for that :
web:
environment:
DATABASE_URL:
...
shell:
environment:
DATABASE_URL:
...
Rake db:create works just fine now :
$ docker-compose run shell bundle exec rake db:create
Database 'planning_poker_development' already exists
Database 'planning_poker_test' already exists
Starting a psql session
During all my trouble-shootings, I tried to connect to the Postgresql server to make sure that the databases where created and ready. Here is how I managed to do that :
1. Install psql client
On my Ubuntu machine, that was a simple sudo apt-get install postgresql-client-9.4
.
2. Finding the server port
The port can be found through config/database.yml
or through docker ps
. Let’s use the later, as we’ll need it to find the server IP as well.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b58ce42d2b2b postgres "/docker-entrypoint.s" 46 hours ago Up 46 hours 5432/tcp planningpoker_herokuPostgresql_1
Here the port is clearly 5432.
3. Finding the server IP
Using the container id we got on previous docker ps
command, we can use docker inspect
to get further details :
$ docker inspect b58ce42d2b2b | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "172.17.0.2",
"IPAddress": "172.17.0.2",
4. Connecting to the database
Connecting is now just a matter of filling the command line.
$ psql -U postgres -p 5432 -d planning_poker_development -h 172.17.0.2
planning_poker_development=# select * from schema_migrations;
version
---------
(0 rows)
5. Installing psql client directly in the shell
It should be possible to install the psql client in the shell container automatically, but I must admit I did not try this yet. It should just a matter of adding this to the Dockerfile
RUN apt-get install postgresql-client-<version>
Leave a comment