32

I'm having trouble creating an image of a docker redis container with the data in the redis database. At the moment I'm doing this:

docker pull redis
docker run --name my-redis -p 6379:6379 -d redis
redis-cli
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> save
OK
127.0.0.1:6379> exit
docker stop my-redis
docker commit my-redis redis_with_data
docker run --name my-redis2 -p 6379:6379 -d redis_with_data
redis-cli
127.0.0.1:6379> keys *
(empty list or set)

I'm obviously not understanding something pretty basic here. Doesn't docker commit create a new image from an existing container?


okay, i've been doing some digging. The default redis image on hub.docker uses a data-volume which is then mounted at /data in a container. In order to share this volume between containers, you have to start a new container with the following argument:

docker run -d --volumes-from <name-of-container-you-want-the-data-from> \
  --name <new-container-name> -p 6379:6379 redis

Note that the order of the arguments is important, otherwise docker run will fail silently.

docker volume ls

will tell you which data volumes have already been created by docker on your computer. I haven't yet found a way to give these volumes a trivial name, rather than a long random string.

I also haven't yet found a way to mount a data-volume, but rather just use the --volumes-from command.


Okay. I now have it working, but it's cludgey.

With

docker volume ls
docker volume inspect <id of docker volume>

you can find the path of the docker volume on the local file-system. You can then mount this in a new container as follows:

docker run -d -v /var/lib/docker/volumes/<some incredibly long string>/_data:/data \
   --name my-redis2 -p 6379:6379 redis

This is obviously not the way you're meant to do this. I'll carry on digging.


I put all that i've discovered upto now in a blog post: my blog post on medium.com

Maybe that will be useful for somebody

Jakub Kukul
  • 12,032
  • 3
  • 54
  • 53
ehrt1974
  • 1,166
  • 2
  • 11
  • 24

2 Answers2

30

Data in docker is not persistent, when you restart the container your data will be gone. To prevent this you have to share a map on the host machine with your container. When you container restarts it will get the data from the map on the host.

You can read more about it in the Docker docs: https://docs.docker.com/engine/tutorials/dockervolumes/#data-volumes

From the redis container docs:

Run redis-server

docker run -d --name redis -p 6379:6379 dockerfile/redis

Run redis-server with persistent data directory. (creates dump.rdb)

docker run -d -p 6379:6379 -v <data-dir>:/data --name redis dockerfile/redis

Run redis-server with persistent data directory and password.

docker run -d -p 6379:6379 -v <data-dir>:/data --name redis dockerfile/redis redis-server /etc/redis/redis.conf --requirepass <password>

Source: https://github.com/dockerfile/redis

Frenus
  • 780
  • 5
  • 13
  • I can stop and restart the container and the data persists. I'd like to have all the data inside the image, so I can just send somebody the image and they can run it. – ehrt1974 Apr 11 '17 at 09:02
  • You first stop the container(data gone on container) and then you commit it. Maybe you can commit before stopping it? – Frenus Apr 11 '17 at 09:06
  • The data doesn't disappear when a container is stopped. it is (on my system at least) persistant. – ehrt1974 Apr 11 '17 at 09:07
  • Ah I think I understood your question wrong. You want to save the data inside the image. As far as I know that's not possible sorry :-(. – Frenus Apr 11 '17 at 09:10
  • I've been digging a bit. It appears that the default redis image on docker-hub automatically creates a data volume. Looking at http://stackoverflow.com/questions/26331651/how-can-i-backup-a-docker-container-with-its-data-volumes it appears to be quite difficult to actually access that data volume after it's been created. – ehrt1974 Apr 11 '17 at 09:14
  • Have you tried commiting before stopping the container? – Frenus Apr 11 '17 at 09:15
  • Yep. it doesn't help :( – ehrt1974 Apr 11 '17 at 09:15
  • 1
    You're right, it does indeed make a data volume. I can't get it to work either. The ugly solution is to manually share the RDB files I think :-(. – Frenus Apr 11 '17 at 09:54
4

Using data volume and sharing RDB file manually is not ugly, actually that's what data volume is designed for, to separate data from container.

But if you really need/want to save data to image and share it that way, you can just change the redis working directory from volume /data to somewhere else:

  • Option 1 is changing --dir when start the redis container:

    docker run -d redis --dir /tmp
    

    Then you can follow your steps to create new image. Note that only /tmp could be used by this method due to permission issue.

  • Option 2 is creating a new image with changed WORKDIR:

    FROM redis
    
    RUN mkdir /opt/redis && chown redis:redis /opt/redis
    WORKDIR /opt/redis
    

    Then docker build -t redis-new-image and use this image to do your job.

shizhz
  • 11,715
  • 3
  • 39
  • 49