Using Docker to provision databases for development and testing
Containers are all the rage now, but is there any reason to put database servers in containers?
I personally don’t really see any reasons to put database servers in docker containers for “normal” production systems (exceptions exist), because I think that if we can avoid unnecessary layer in running software, we should.
When it comes to development and testing tho, utilizing docker containers makes sense:
- We can run multiple database systems (PostgreSQL, MySQL, MariaDB, etc.) for testing our software against different software
- We can run multiple versions of the same database system (PostgreSQL 11, PostgreSQL 10) to test different versions
- We can run all those servers at the same time without much effort
- In doing so, we don’t “pollute” our computers with all those databases and configuration
- We can easily provision a database when running an automated test suite and clean it up after the tests finish
- We can install databases or their versions which are not available for our host operating system, for both development and testing
There are two major ways to use databases in containers, depending on the data storage:
- empheral: when we don’t need any data persistence after we stop the container
- permanent: when we use the container for continuous development and we want to persist the data
One major advantage to using docker for database provisioning is also the fact that it is really easy if there already is a docker image prepared. If it is, we can just search for it on Docker Hub, read the instructions if there is anything special going on and have our database ready with just two or three commands.
How to provision database with docker
As an example, let’s provision PostgreSQL with both empheral and permanent storage. First we need to download the database image:
docker pull postgres:11
This will download the docker image of PostgreSQL 11. If we didn’t specify any tag, it would download the latest stable version.
To run a container from this image with temporary storage, run:
docker run --name postgres -p 5433:5432 -e POSTGRES_PASSWORD=postgres -d postgres
The only thing that makes sense to specify here are the port (we pick 5433 to be our host port, whereas 5432 is the default PostgreSQL port in the container), the database name (-d option) and the password. With this information we can easily connect to the database right away.
To provision database with permanent storage, we need to first create something called volume and assign it to the container:
docker volume create postgres-volume
docker run -v postgres-volume:/var/lib/postgresql/data --name postgres -p 5433:5432 -e POSTGRES_PASSWORD=postgres -d postgres
The only difference here is the volume flag (-v), otherwise it is the same thing.
So this is it – dead simple way to manage and provision database server for development using docker. Happy coding!
Last updated on 12.9.2019.