# Docker Cheat Sheet ## Why [Why Should I Care (For Developers)](https://www.docker.io/the_whole_story/#Why-Should-I-Care-\(For-Developers\)) ## I don't care, I just want a dev environment * [https://github.com/relateiq/docker_public/](https://github.com/relateiq/docker_public/) * [docker-devenv](https://github.com/wsargent/docker-devenv) * [Build your own dev environment](https://gist.github.com/wsargent/7049221#file-your_own_devenv-md) ## Prequisites Use [Homebrew](http://brew.sh/). ``` ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)" ``` ## Installation Install VirtualBox and Vagrant using [Brew Cask](https://github.com/phinze/homebrew-cask). ``` brew tap phinze/homebrew-cask brew install brew-cask brew cask install virtualbox brew cask install vagrant ``` We use the pre-built vagrant box: [http://blog.phusion.nl/2013/11/08/docker-friendly-vagrant-boxes/](http://blog.phusion.nl/2013/11/08/docker-friendly-vagrant-boxes/) ``` mkdir mydockerbox cd mydockerbox vagrant init docker https://oss-binaries.phusionpassenger.com/vagrant/boxes/ubuntu-12.04.3-amd64-vbox.box vagrant up vagrant ssh ``` In the Vagrant: ``` sudo su - sh -c "curl https://get.docker.io/gpg | apt-key add -" sh -c "echo deb http://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list" apt-get update apt-get install -y lxc-docker ``` Verify: ``` docker run -i -t ubuntu /bin/bash ``` That's it, you have a running Docker container. ## Containers [Your basic isolated Docker process](http://docker.readthedocs.org/en/latest/terms/container/#container-def). Containers are to Virtual Machines as threads are to processes. Or you can think of them as chroots on steroids. Some common misconceptions it's worth correcting: * __Containers are not transient__. `docker run` doesn't do what you think. If you * __Containers are not limited to running a single command or process.__ It's just encouraged. ### Lifecycle * [`docker run`](http://docs.docker.io/en/latest/commandline/cli/#run) creates a container. * [`docker stop`](http://docs.docker.io/en/latest/commandline/cli/#stop) stops it. * [`docker start`](http://docs.docker.io/en/latest/commandline/cli/#start) will start it again. * [`docker restart`](http://docs.docker.io/en/latest/commandline/cli/#restart) restarts a container. * [`docker rm`](http://docs.docker.io/en/latest/commandline/cli/#rm) deletes a container. * [`docker attach`](http://docs.docker.io/en/latest/commandline/cli/#attach) will connect to a running container. * [`docker wait`](http://docs.docker.io/en/latest/commandline/cli/#wait) blocks until container stops. If you want to run and then interact with a container, `docker start` then `docker attach` to get in. If you truly want a transient container, `docker run -rm` will remove the container after it stops. If you just want to poke around in an image, `docker run -rm -t -i ` to open a tty. ### Info * [`docker ps`](http://docs.docker.io/en/latest/commandline/cli/#ps) shows running containers. * [`docker inspect`](http://docs.docker.io/en/latest/commandline/cli/#inspect) looks at all the info on a container (including IP address). * [`docker logs`](http://docs.docker.io/en/latest/commandline/cli/#logs) gets logs from container. * [`docker events`](http://docs.docker.io/en/latest/commandline/cli/#events) gets events from container. * [`docker port`](http://docs.docker.io/en/latest/commandline/cli/#port) shows public facing port of container. * [`docker top`](http://docs.docker.io/en/latest/commandline/cli/#top) shows running processes in container. `docker ps -a` shows running and stopped containers. ### Import / Export * [`docker cp`](http://docs.docker.io/en/latest/commandline/cli/#cp) copies into a container. * [`docker export`](http://docs.docker.io/en/latest/commandline/cli/#export) turns container fs into tarball. ## Images Images are just [templates for docker containers](http://docker.readthedocs.org/en/latest/terms/image/). ### Lifecycle * [`docker images`](http://docs.docker.io/en/latest/commandline/cli/#images) shows all images. * [`docker import`](http://docs.docker.io/en/latest/commandline/cli/#import) creates an image from a tarball. * [`docker build`](http://docs.docker.io/en/latest/commandline/cli/#build) creates image from Dockerfile. * [`docker commit`](http://docs.docker.io/en/latest/commandline/cli/#commit) creates image from a container. * [`docker rmi`](http://docs.docker.io/en/latest/commandline/cli/#rmi) removes an image. * [`docker insert`](http://docs.docker.io/en/latest/commandline/cli/#insert) inserts a file from URL into image. `docker import` and `docker commit` only set up the filesystem, not Dockerfile info like CMD or ENTRYPOINT or EXPOSE. See [bug](https://github.com/dotcloud/docker/issues/1141). ### Info * [`docker history`](http://docs.docker.io/en/latest/commandline/cli/#history) shows history of image. * [`docker tag`](http://docs.docker.io/en/latest/commandline/cli/#tag) tags an image to a name (local or registry). ## Registry & Repository A repository is a *hosted* collection of tagged images that together create the file system for a container. A registry is a *host* -- a server that stores repositories and provides an HTTP API for [managing the uploading and downloading of repositories](http://docs.docker.io/en/latest/use/workingwithrepository/). Docker.io hosts its own [index](https://index.docker.io/) to a central registry which contains a large number of repositories. * [`docker search`](http://docs.docker.io/en/latest/commandline/cli/#search) searches registry for image. * [`docker pull`](http://docs.docker.io/en/latest/commandline/cli/#pull) pulls an image from registry to local machine. * [`docker push`](http://docs.docker.io/en/latest/commandline/cli/#push) pushes an image to the registry from local machine. ## Dockerfile The configuration file. Sets up a Docker container when you run `docker build` on it. Vastly preferable to `docker commit`. * [Dockerfile tutorial, level 1](http://www.docker.io/learn/dockerfile/level1/) * [Dockerfile tutorial, level 2](http://www.docker.io/learn/dockerfile/level2/) Best to look at [http://github.com/wsargent/docker-devenv](http://github.com/wsargent/docker-devenv) and the [best practices](http://crosbymichael.com/dockerfile-best-practices.html) for more details. ## Layers The filesystem in Docker is based on layers. They're like [git commits or changesets for filesystems](http://docker.readthedocs.org/en/latest/terms/layer/). ## Links Links are how Docker containers talk to each other. [Linking into Redis](http://docs.docker.io/en/latest/examples/linking_into_redis/) is the only real example. If you have a docker container with the name CONTAINER (specified by `docker run -name CONTAINER`) and in the Dockerfile, it has an exposed port: ``` EXPOSE 1337 ``` Then if we create another container called LINKED like so: ``` docker run -d -link CONTAINER:ALIAS -name LINKED user/wordpress ``` Then the exposed ports and aliases of CONTAINER will show up in LINKED with the following environment variables: ``` $ALIAS_PORT_1337_TCP_PORT $ALIAS_PORT_1337_TCP_ADDR ``` And you can connect to it that way. ## Volumes Docker volumes are free-floating filesystems. They don't have to be connected to a particular container. Volumes are useful in situations where you can't use links (which are TCP/IP only). For instance, if you need to have two docker instances communicate by leaving stuff on the filesystem. If you just want to map a directory on the host to a docker container, use ``` docker run -v /myhost/dir:/docker/dir my_image ``` You can mount them in several docker containers at once, using `docker run -volume-from` See [advanced volumes](http://crosbymichael.com/advanced-docker-volumes.html) for more details.