Dec 052015
 
Docker! Docker! Docker!

Played a bit with Docker. I read about it (hard to miss, isn’t it?) and wanted to test this out a bit. Setting up a Docker container, deploy in a cloud and see what you can do.

Turns out: this is not only easy, but it’s very quickly understandable why it’s great for dev-ops style work. And why it’s security-wise difficult to use when dev and ops are separate for regulatory reasons.

Important discoveries and notes:

  • You need an underlying OS to run docker containers. Anything will do as long as it’s Linux with support for needed features:
    • kernel 3.10 or newer
    • aufs
    • cgroups
  • A good choice is CoreOS. Tested, and worked. Very small too. Ubuntu is fine too. As is CentOS. Anything modern really. The only thing this OS does is start/stop docker containers. Plus monitoring them if you want to. And store their images.
  • Your app runs all alone in that container. Thus you can use root, but to protect you from yourself, running as a normal user is preferred. In the Dockerfile that will do it:
USER harald
WORKDIR /home/harald
ENTRYPOINT ["/bin/bash"]

 

  • Sharing local filesystems or having local data volumes in containers is easy:
# Create a volume and mountpoint src
docker create -v /src --name src debian:8 /bin/true
# View what you did
docker volume ls
# Use via
docker run -it --volumes-from src --user root hkubota/debian-dev:1

  • If you want to have non-local and persistent modifyable filesystems, you are out of luck. Unsolved problem. NFS is one possibility with known drawbacks.
  • If you build a image, it has layers and the build is automate-able and reproducible. If you cannot, then a commit of a running container creates an image too.
  • https://imagelayers.io/ shows nicely how images are built with all those layers.
  • Development creates a lot of images. Many temporary, but they are kept anyway. Use this to clean them up and run via cron (original found here):
docker rm -v $(docker ps -a -q -f status=exited)
docker rmi $(docker images -f "dangling=true" -q)
docker run -v /var/run/docker.sock:/var/run/docker.sock \
-v /var/lib/docker:/var/lib/docker --rm martin/docker-cleanup-volumes
  • Since your container only runs your stuff, it does not run things like cron out of the box. Or any other daemon for that matter. If you need it, have it be part of the container and make sure crond (in this case) starts as part of your container start.
  • If you use e.g. Debian 8 as the main Docker container OS, have a development system to create binaries with and for it. Using Alpine Linux as OS and using pre-compiled binaries won’t work if glibc is expected and non-existant. A re-compile on Alpine will of course solve this.
    So stick to one container OS.
  • Security is a problem if you usually don’t allow people to be root. If you log in on the container host as, becoming root on it is trivial.

Pending:

  • How to run a DB? It needs persistent storage. How to do replication? How do I do backup?
  • MQTT similar needs persistent storage. A small data volume container will do.
  • Networking. While exposing a port is easy, I did not yet need interconnections between containers.