Rit Li ·
Say we have Project X and Project Y that require Postgres 9 and Postgres 10 respectively. These projects aren’t using Docker to manage their Postgres dependency so it is up to each developer to manage this themselves. How do we get different versions of Postgres running simultaneously on our workstation without making any modifications to these projects? One easy way is to use Docker Compose.
Why not Homebrew? With Homebrew, installing multiple versions of Postgres is easy, but running them simultaneously is cumbersome. With Docker Compose, both installing and running are easy. Note that we’re not “dockerizing” the applications themselves; instead, we’re using Docker Compose as an alternative to Homebrew to fetch and run Postgres.
We’ll use Docker Compose to manage two instances of Postgres (i.e. two “services”). The beauty of using Docker is the fact that we can start these services with a clean slate and clean the slate when we’re done.
With this docker-compose.yml
file:
version: '3' services: pg9: image: postgres:9.6.10 ports: - 5961:5432 environment: POSTGRES_DB: project-x pg10: image: postgres:10.5 ports: - 5105:5432 environment: POSTGRES_DB: project-y
We can start Postgres in a pristine state with just one simple command:
docker-compose up -d
And clean the slate with this:
$ docker-compose down
With docker-compose down
, all the records in Postgres are completely wiped out. We should only run this command when we’re done with the project. The Postgres image is by default configured to use a Docker volume so that the data persists between docker-compose start|stop|restart
subcommand. docker-compose down
will remove that volume, hence our Postgres data will be deleted.
Note that we have mapped port 5961
of our workstation to port 5432 (default Postgres’s port) of the container running the pg9
service. Therefore, the connection URI for pg9
should be postgres://localhost:5961/project-x
. Likewise, the connection URI for pg10
should be postgres://localhost:5105/project-y
.
docker-compose up
will start the process in the foreground. It stays alive until we kill it with ctrl-c
. We can start it in the background with the -d
flag. If we reboot our workstation, we have to start the process again. However, we don’t have to “initialize” the environment with docker-compose up
. We can, instead, restart the service with docker-compose start
.
After running docker-compose up
, we can verify pg9
and pg10
services are running with this command:
$ docker-compose ps
The output should resemble this:
Name Command State Ports --------------------------------------------------------------------------------------- postgres-docker_pg10_1 docker-entrypoint.sh postgres Up 0.0.0.0:5105->5432/tcp postgres-docker_pg9_1 docker-entrypoint.sh postgres Up 0.0.0.0:5961->5432/tcp
If we want to start, stop or restart pg9
, we can do so with:
$ docker-compose start|stop|restart pg9
Given pg9
service is running, we can use this command to drop into psql:
$ docker-compose exec -u postgres pg9 bash
Once we’re at the bash
shell prompt, we can use psql
much like we normally would:
postgres@e2d166ef7c37:/$ psql project-x
We can also use createdb
, dropdb
, createuser
, and other Postgres handy utilities.
This is just a taste of Docker as a power tool for development. And while Docker and its ecosystem are vast, we don’t have to navigate them all at once. For example, we don’t have to “dockerize” our apps to get the benefits. We can take it one baby step at a time.
Interested in more software development tips and insights? Visit the development section on our blog!
time-traveling healer