Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save empireshades/4862bed343d5c10189d4 to your computer and use it in GitHub Desktop.
Save empireshades/4862bed343d5c10189d4 to your computer and use it in GitHub Desktop.

This document contains some notes I have gathered while I was trying to setup a redis service using boot2docker running on OS X. This won't cover what Docker is, see Docker website for details.

Installing boot2docker

First, install Virtualbox and follow the steps at http://docs.docker.com/installation/mac/

Since Docker only runs on Linux, boot2docker runs a virtual machine in Virtualbox (or VMWare etc), however you can run the docker command on OS X command line as if it were running on OS X.

Running redis in docker

Next, run docker run dockerfile/redis

This will download dockerfile's version of redis (for some reason, I wasn't able to access data outside the container for the official redis repo, more details in the next sections) and run it in the foreground. Note that you cannot send an interrupt signal (Ctrl-C) to stop this.

One way to stop this is to open a new shell, run docker ps to verify that it is running. You will see that docker has given the running instance (container) a unique id (1st column) and a unique name (last column). You can use any of these to kill the running container. docker kill 62ec63560d3b where 62ec63560d3b is the ID reported in the first column will kill the container. You can also abbreviate the id so docker kill 62e should work too.

Run the container again, this time with -d switch so that it runs in background. docker run -d dockerfile/redis docker ps should report that it is running again. So far so good, but how do we access the redis instance inside the container?

Running docker ps should show that the port 6379/tcp is not bound to any port on the host of the container (in our case, the VM that boot2docker has started for us.) This means that this port will also not be exposed outside the VM, in the OS X system.

Again stop the docker instance (tip: docker stop $(docker ps -a -q) will stop all containers) and re-run it, this time with -P which will publish all the exposed ports on the host. So running docker run -P -d dockerfile/redis will start the redis server, with its port exposed in the host of the container, that is the VM.

Running docker ps should verify this, as this time, the ports section will show the mapping: 0.0.0.0:49165->6379/tcp instead of just 6379/tcp. The IP 0.0.0.0 means that the host of the container, the VM will be listening on all interfaces.

Now, back in OS X, let's try connecting to this Redis server running in the container. Before continuing, make sure that any natively running servers on OS X has been stopped, just to make sure that we are connecting to the redis inside the container.

Try connecting to the port outputted by docker ps, so issue: redis-cli -p 49165 where 49165 is the random port assigned due to usage of -P. You will see a connection error because boot2docker does not map the port exposed in the virtual machine on the OS X system.

To be able to connect to the redis server, you need to specify the IP of the virtual machine running inside virtualbox. This is a common mistake as boot2docker makes it seem as if docker is running inside OS X.

To get the ip of the virtual machine, issue: boot2docker ip This will report 192.168.59.103 for Virtualbox.

Therefore, to connect to redis instance running inside the container, issue: redis-cli -h 192.168.59.103 -p 49165.

Remember that we have used -P to expose a random port on the outside. You can also use -p to manually expose the port, for example -p 10000:6379 will expose the port 10000 on the virtual machine so that redis-cli -h 192.168.59.103 -p 10000 should work.

Verify this by running:

docker run -p 10000:6379 -d dockerfile/redis redis-cli -h 192.168.59.103 -p 10000

Making redis data durable

After exposing the port for external access, let's look at exposing the data to the outside world. Volumes are used in docker for this, however the container recipe has to be crafted to make use of volumes for the consumers of the container to override the data directories. dockerfile/redis (https://registry.hub.docker.com/u/dockerfile/redis/) exposes the data directory of docker at /data, so running the following should create a folder called /redis_data for storing redis dumps.

docker run -d -p 6379:6379 -v /redis_data:/data --name redis dockerfile/redis

One common mistake is to assume that this data directory will magically appear in OS X. This currently is not the case, there is an ongoing effort to make folder sharing as seamless as possible in the future, however, for now, this folder will be inside the virtual machine, not in OS X. Verify this by ssh'ing into the virtual machine using boot2docker ssh and ls /redis_data. The folder should be there, but empty for now since we have not entered any data to redis.

To verify that redis dump will be available inside the container, do the following:

Since we have exposed redis at port 6379, connect to redis instance just by specifying the ip of the VM:

redis-cli -h 192.168.59.103

Then issue the following:

sadd teams Brazil sadd teams Germany save

The last explicit save is important since redis will normally wait for some time before persisting to disk. save will trigger the dump creation.

Now, ssh into the vm by running boot2docker ssh and issue ls /redis_data. dump.rdb should be available there.

Access stored data in OS X

Now that we have the data inside the virtualbox instance, there are several ways to access it. There is an ongoing work to make this seamless using fuse in the near future, see moby/moby#4023 The changes have been merged 5 days ago as of writing (Jun 1, 2014), so next versions of docker and boot2docker should make these much easier.

One way is to use virtualbox's native sharing capabilities by actually using a different boot2docker iso instead of the stock one. boot2docker project maintainers are currently opposed to this method since boot2docker is not specific to virtualbox and adding such functionality for each backend like vmware would bloat boot2docker.

The other method is to use samba or nfs sharing to expose the folder, which is pretty easy and does not require one to use a different boot2docker iso.

First, redis instance must be run with a name by specifying --name redis, we have already done so in the above examples:

docker run -d -p 6379:6379 -v /redis_data:/data --name redis dockerfile/redis

Next, issue docker run svendowideit/samba redis

This will prompt you to run (erronously)

docker run --rm -v $(which docker):/docker -v $(/var/run/docker.sock):/docker.sock -e DOCKER_HOST svendowideit/samba redis

Instead, issue

docker run --rm -v $(which docker):/docker -v /var/run/docker.sock:/docker.sock -e DOCKER_HOST svendowideit/samba redis

You should see the following output:

stopping and removing existing server
starting samba server container sharing redis:/data

# run 'docker logs samba-server' to view the samba logs

================================================

Your data volume (/data) should now be accessible at \\<docker ip>\ as 'guest' user (no password)

For example, on OSX, using a typical boot2docker vm:
goto Go|Connect to Server in Finder
enter 'cifs://192.168.59.103
hit the 'Connect' button
select the volumes you want to mount
choose the 'Guest' radiobox and connect

Or on Linux:
mount -t cifs //192.168.59.103/data /mnt/data -o username=guest

Or on Windows:
Enter '\\192.168.59.103\data' into Explorer
Log in as Guest - no password`

Follow the instructions there and you will now be able to access the data on OS X side. You can now access (for example backup) the redis dump folder.

What we want to achieve is to be able to access the dump after redis has exited. One interesting pattern in Docker community is to use data containers for that, containers which just wrap some data directories. These usually use busybox repo since they do not need to run anything.

After killing the redis process, issue docker run -v /redis_data:/data --name data_container busybox true. This will make sure that /redis_data folder, where our dump lives will be seen as /data in this container.

Now re-run the samba sharing container with this data container:

docker run --rm -v $(which docker):/docker -v /var/run/docker.sock:/docker.sock -e DOCKER_HOST svendowideit/samba data_container

You should now be able to have access to the dump directory without redis running.

To verify that this is so, on OS X, start the local redis-server with this data directory:

Run redis-server -

Type DIR /Volumes/data followed by Ctrl-d

This will make sure that local redis on OS X will be using the dump we shared from docker.

Running simply redis-cli followed by smembers teams should output 1)Brazil and 2) Germany as expected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment