mwarren
mwarren

Reputation: 2469

My docker data-only container is empty

The scenario I most feared has happened: my data-only docker container is suddenly empty.

This is not serious: it's a development machine and I have back-up. But I fear this most because I know that I still have holes in my understanding of Docker.

I have read in this answer the following:

Docker containers will persist on disk until they are explicitly deleted with docker rm.

Here are the containers I'm interested in (from a docker ps command):

CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS                         PORTS               NAMES
478e59ecd218        dockerlocal_mongo_instance    "/entrypoint.sh mongo"   About an hour ago   Exited (137) 12 minutes ago                        dockerlocal_mongo_instance_1
0ca49f6629cb        tianon/true                   "/true"                  3 hours ago         Exited (0) About an hour ago                       dockerlocal_mongo_data_1

I have a 1) a mongo container which references the data-only container, and 2) the data-only container itself. I recently ran docker rm a couple of times on the mongo dockerlocal_mongo_instance_1 container which references the data-only container.

I can see from the output of the docker ps command (see above) that it says that the data-only container was created '3 hours ago'. But I created it about 2 weeks ago. Somehow my original one has gone. My question is how could this happen? What other possibilities are there?

I have checked my bash command history and the docker rm command was run only on the mongo container, not on the data-only container - which for obvious reasons I have been extremely careful not to touch.

Can anyone shed any light on this? I must have misunderstood something fundamental here.

I would be grateful for any other possible scenarios that could cause the data-container to be trashed and re-created in this way.

Docker compose .yml file (relevant bits):

mongo_data:
    image: tianon/true
    volumes:
        - /data/db
mongo_instance:
    build: mongodb
    volumes_from:
        - mongo_data
    ports:
        - "27017:27017"
    environment:
        - MONGODB_USER=$S_USER_NAME
        - MONGODB_PASS=$S_USER_PASSWORD
#    command: --auth

Upvotes: 0

Views: 1339

Answers (3)

mwarren
mwarren

Reputation: 2469

The answer for me in the end is to forget using a docker data container and just set a normal volume on the mongo container.

mongo_instance:
    build: mongodb
    volume:
        - /data/db:/data/db
    ports:
        - "27017:27017"
    environment:
        - MONGODB_USER=$S_USER_NAME
        - MONGODB_PASS=$S_USER_PASSWORD

Why?

  1. The main reason to use Docker Compose in my view is because of its portability. You easily run all your docker commands in one place, which means a simple installation. So if using a docker data container means moving the creation of the data container out of the .yml file I am complicating everything - I first have to create the data container and then run docker compose: I would much prefer to just upload my .yml file and run it.
  2. I found problems anyway with the creation of the data container on its own before calling docker-compose. You are advised to reuse your own images when creating data containers rather than using small third-party images like tianon/true. But my images, which I might be able to use, only get created when I run docker-compose and I haven't run it yet - a chicken and egg situation.
  3. I tried creating a data container using tianon/true (and others) and I always ran into permission problems.

So I have removed the data container and used a volume parameter on the mongo_instance. I hope this also solves my original problem ...

Upvotes: 0

Adrian Mouat
Adrian Mouat

Reputation: 46510

There's a couple of things you need to understand.

  • A data container doesn't need to be, and shouldn't be, running. It's really just a namespace for a set of volumes that can the be referred to from other containers. In your case, every time you start up your application, the data container will start, run true, then shut down. It would be better if you just created the container once and never ran it again.
  • Docker Compose defines the running services that make up your application. It has a lot of logic related to deciding when to recreate containers or reuse existing ones, which at some stage has decided to recreate your data container (I'm not sure why in this case). You should only put stuff in Compose that does not need to be persisted. Also note that Compose will attempt to copy volumes from old containers to new ones, which can cause confusion if you're not expecting it.

In your case, the solution is to define the data container outside Compose e.g:

docker run --name mongo_data mongodb echo "Data Container"

This will run the echo command then immediately exit. You can then remove the mongo_data entry from the Compose yaml. Note that I have intentionally used the mongodb image rather than tianon/true; as a data container isn't left running, it won't take up any extra space and using the mongodb image ensures file permissions etc are correct.

Upvotes: 1

jwodder
jwodder

Reputation: 57590

If you ever ran docker-compose rm (or, worse docker-compose rm -f), that would have deleted all extant containers defined in your docker-compose.yml. Note that, even if you only meant to start the mongo_instance container with docker-compose up mongo_instance, the mongo_data container would have been created as well, as mongo_instance depends on mongo_data, and so doing docker-compose rm while mongo_instance was around would delete both containers.

Upvotes: 0

Related Questions