53

I'm having a discussion with a friend about use cases for Docker. One guy in the team wants to use Docker for everything - like a kind of universal unix process wrapper. The other thinks that Docker should only be used for stateless applications like Microservices and AWS Lambda style apps.

We've engineered proof of concepts for both. On our docker cluster we have a shared drive that gets mounted when the Docker host is mounted, and if a Database in a container is mounted, it simply mounts a volume to the shared drive.

My friend still sticks to his position, despite being shown the contrary evidence. (He also argues that Docker adds unnecessary risk by adding complexity to the stack.)

I'm trying to listen and understand his point of view, both in an act of empathy, but also to better reason with him. (We all get on quite well - so this is a mix of in-jest and serious discussion).

Kind of the question behind the question is: are databases cattle? This comment suggests that a good automated backup and retrieval strategy for your database is indistinguishable from a cattle server.

My question is: What are the reasons Docker should not be used for databases?

EDIT: People have asked me to clarify my terminology. I was assuming that the database application was in the container, and the storage was in the volume. What I meant was, the RDBMS is in the container, and the database storage is in the volume.

Some commentators have suggested that the docker volume drivers aren't going to work with database writes very well. (Or something to that effect). Could you please expand on that?

2

3 Answers 3

42

When people talk about running a database in Docker, they do not mean to store the data in a container; they are talking about having a docker image with the DB software, and mounting the data as a volume (a bind volume, not a container volume).

Volumes are an essential part in Docker, and are not something that is flakey or just tacked on. Docker is not just made for stateless (micro)services.

Wish as I might, I cannot find a technical reason not to run a database in a Docker, so unfortunately I'll pick the other side of the argument and hence maybe not give you the answer you are looking for.

(I'm using Oracle as an example because I'm familiar with it, both bare metal and dockerized, and because it's quite a notorious beast for being just a bit non-trivial to operate if you go past default settings.)

  • Packaging up the DB software itself in a container gives you the usual benefits - having the same version everywhere, avoiding dependency/shared library issues, being able to spin up the exact same DB on developer laptops or wherever you need it.
  • It is a snap getting it to run anywhere; updating is trivial, and so on. All the Docker benefits apply. There is an Oracle image on Dockerhub which allows you to spin up a working DB in a minute or three (and for the others as well, of course).
  • People did do performance tests and found no I/O differences between volumes and bare metal (https://www.percona.com/blog/2016/02/11/measuring-docker-io-overhead/, https://stackoverflow.com/questions/21889053/what-is-the-runtime-performance-cost-of-a-docker-container).
  • Under the hood, it's not like Docker somehow intercepts all I/O, anyway. It just gets creative with standard Linux tools (bind mounts in this case, mangling of the internal kernel tables that make the Docker-fu possible at all).
  • Obviously that does not mean that you can run two instances of the DB and just have them work on the same files, but nobody is implying that. Docker does not give you automatic simultaneous and magically race-free access to volumes, and did never pretend to do so. The rest of the benefits still apply. If your DB itself does not detect conflicts like this, you better supply a CMD script to the image which refuses spinning up a second container when the volume is already in use.
  • You have to be a little more careful spinning up/shutting down the container (just as you would not simply switch off a bare metal DB server), but that should be quite manageable.

Now, depending on circumstances, there may be soft reasons not to do it:

  • Oracle (the company), for example, might not support you if you run their RDBMS in a Docker container on production systems (in 2021, 3 years after writing this answer, it is unclear to me if that is still true). But maybe you are using dockerized Oracle RDBMS images only for your developers and the testing environment, where you would not need their support in any case, reserving it for a bare metal production server. (But don't forget to pay your licenses...).
  • If the ops guys are unfamiliar with Docker, it might just be a bit easier to accidently kill everything, destroy your data files etc..
  • If you have big dedicated metal DB machines already, with large amounts of very fast dedicated SAN storage, and running nothing else anyways, then there would just be no point in using Docker to containerize those as you will never just spin another server up when there are 100s of GB or even TB of data. After all, for production, a RDBMS like Oracle is very, very advanced in all the replication, data integrety, no-downtime failover, etc. aspects. Note that this argument just says "you do not need to containerize your RDBMS". It does not say "you should not do it" - maybe you want to do it because you wish to roll out database software upgrades through containers or for whatever other reason you could imagine.

So there you go. By all means do dockerize your DB, at the very least for your developers (who will be eternally thankful) and your testing environments. On the production, it will come down to taste, and there at least, I would also prefer the solution that sits best with the specialized DBA/Ops - if they have decades of experience working bare metal DB servers, then by all means trust them to continue so. But if you are a startup who has all IT in the cloud anyways, then a Docker container would just be one further piece of onion in the whole picture.

7
  • Another factor is if the alternative is using a managed DB service vs hosting your own.
    – avi
    Commented Mar 16, 2019 at 21:18
  • This answer is a little old, but do you think your point about "Oracle ... will certainly not support you if you run their RDBMS in a Docker container" is still true?
    – Matt
    Commented Jun 29, 2021 at 15:33
  • 1
    @matt: Phew, I don't know actually. Oracle's "official" images on dockerhub seem to end with Oracle RDBMS 12 (quick google, haven't checked if Oracle 19 is there...). Do you know whether Docker is officially supported meanwhile (for production DBs)? I'll gladly change the answer, or remove that sentence if we're not quite sure.
    – AnoE
    Commented Jun 29, 2021 at 15:39
  • 1
    I've updated the answer a little bit, @Matt.
    – AnoE
    Commented Jun 30, 2021 at 6:53
  • 1
    @PirateApp, I am not aware of any changes - my gist would still be "DBs feel well on dedicated hosts, even dedicated hardware, but if you must containerize, then that should be OK, albeit only if the DB vendor allows it; else only for unimportant data". I also see no particular reasons why containers should crash out of the blue moon - if your k8s or other solution kills your containers, you should look at the limit/quota configs or check the overall stability... and any DB worth your productive data should handle hard crashes gracefullym anyway.
    – AnoE
    Commented Jun 2, 2022 at 8:27
7

I wrote about this in depth but here's the summary:

  • Preventing split brain (electing more than one master node) needs to be solved. Failure to do so can be catastrophic

  • There are no production ready shared storage solutions to enable databases to be shutdown on one instance and brought up on another without losing all your data.

4
  • Thanks - that's nearly a reasoned answer. In your blog post however - you add a caveat that validates the assumption I've written up the top. "The issues laid out below don’t relate to just running your database in docker with no shared storage or ability to start it automatically on a different node." Ie - your blog post says that the situation I've written about above is valid.
    – hawkeye
    Commented Jun 6, 2017 at 10:50
  • From your question it seems you're using some kind of orchestration to start the db and mount the volume. But then you have a potential consistency problem with the orchestration, which i talk about. My caveat is explicitly about when you use no orchestration.
    – Robo
    Commented Jun 6, 2017 at 10:58
  • Have you seen flynn.io? They are supposedly production-ready and avoid split-brain scenarios by using a chorum state machine (based on Joyent Manatee).
    – Alix Axel
    Commented Jul 10, 2017 at 16:55
  • 1
    Neither of these points apply to cassandra or other distributed databases but I still don't think running it in a container is a good idea.
    – dres
    Commented Sep 6, 2017 at 1:54
0

When you say that the data is mounted into a docker container, would it not be more correct to say that the "database" is mounted into the docker container? If your are persisting your data outside the container then you are doing the "correct" thing of not putting your database in a container.

Sure, go to town putting a DBMS in a container a letting it manage data that you store outside, personally I think that's just good design because it keeps a clean separation between logic and data. But once you put your data into a container them you're potentially playing with fire.

Although container storage drivers have come a long way, I'm personally not yet willing to dive in and leave my data tangled up in a container.

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.