When to Persist Data with Docker
With Docker you can create a programmable infrastructure from a single file, allowing you boundless possibilities and immutable environments for your websites and software.
This has revolutionised web development by making it much easier to spin up infrastructure and environments that can be transported straight into production.
One analogy that I use to explain Docker to newbies is:
Imagine you have a fish that needs to live in water to live. If you have two tanks, one for every day feeding and one for show, then you’re not sure the water in them is the same. Will the fish’s health be affected? Enter Docker, a fishbowl that you can put wherever you want, and you know the fish will always be okay as long as you’re in control of the fishbowl and its contents.
Okay it’s not a perfect analogy but it usually gets people’s heads nodding!
These work fantastically well for web servers and applications (you better be separating these out!), but what about databases and data stores?
When I started using Docker, I successfully Dockerised my web server and all the PHP websites I own and host, but the oh so-common Dockerise All the Things syndrome was tempting.
However, I didn’t Dockerise my databases, instead I kept my MariaDB databases where they were. I did this because I like having my databases in a central location. Dockerising it just seemed like a hassle.
Also, I didn’t like the idea of potentially losing all my data with a single command
docker rm <CONTAINER ID> .
It also felt like it would violate one of the main Docker principles — Containers are Ephemeral, i.e. you should be able to destroy and recreate a container without consequences to your application.
While this keeps things safe and simple, it’s possible and increasingly common to Dockerise databases by using Docker volumes.
This means having a shared volume between your host node and your Docker containers, that each can read and write to.
What problem does this solve though, aside from being a bit fun and cool to do?
It can actually make things hella improved when you consider that a single node with the MySQL engine or its sister engines (MariaDB, Oracle) don’t like it when you throw millions of concurrent queries at them.
But, the Docker Compose (ex: Fig)
scale functionality can solve this by cloning out your database service into multiple identical containers — the way that Docker does this is very efficient and utilises threads between than simply installing multiple database engines on one node.
By the way, if you’re not using
docker-compose scale functionality yet then you definitely should. You can horizontally scale out your application in one line, and if you use inter-container links then Docker will automatically load balance across the scaled containers using a round-robin approach. It’s one of my favourite Docker capabilities.
To do this for a MySQL-flavoured database, all you need are the following lines in your
Assuming you have blank folder in the
data directory in the same folder as this file, when you
docker-compose up -d the database container will automatically start writing data to this folder. When you open up the
data folder you’ll see the files being created!
This persists the data to the folder, so that you can shut down the data and bring it back up again with peace of mind.
And with multiple scaled-out containers across your host node, with your application presumably linked to it, you might find the load balanced a bit better instead of all at one server.
However, you still need to get some data redundancy in place. Make sure that you have some kind of central location for your data, regular and multiple backups so that your data is safe and secure.
Have you tried this already yourself? Run into any problems that you’ve solved? Write them down and share them in the comments below.