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.
Initialize and Reset the Postgres Services
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.
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
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
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
Starting and Stopping the Server
docker-compose up, we can verify
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
Using psql for debugging
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
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!