This week (May 2017) I have been learning about Docker... Here is what I've learned so far.
The shortcut commands in brackets refer to functions/aliases I've set up in my dotfiles.
sudo apt-get install docker docker-compose
sudo usermod -aG docker $USER
Security warning: Any user in the docker
group effectively has full root permissions on the host machine.
Download and install Docker Toolbox. (Note: The newer "Docker for Windows" only works on Windows Professional with Hyper-V – not Windows Home or VirtualBox.)
Initialise a new virtual machine (dinit
; dm
= docker-machine
):
docker-machine create --driver virtualbox default
Set environment variables to allow communication with Docker Machine (denv
):
eval $(docker-machine env)
To support interactive commands under Cygwin, install WinPTY for Cygwin and prefix commands with "winpty
". I have set up Bash functions to do that automatically when required.
Run Bash in a minimal Ubuntu container (dr
= docker run
):
docker run -it ubuntu
# or
docker run -it ubuntu bash
Run the latest version of PHP interactively:
docker run -it php
Run a given command in latest version of PHP (the parameters are just passed to the php
executable):
docker run php -r 'echo PHP_VERSION . "\n";'
Run a specific version of PHP:
docker run -it php:5.6
Any version from 5.3 to 7.1 seems to be available, even though they're not listed on Docker Hub – including some minor versions:
docker run -it php:5.6.1
Some (older?) versions don't automatically pass extra parameters to PHP so require the executable name to be specified:
docker run php:5.3 php -r 'echo PHP_VERSION . "\n";'
List stopped containers:
docker ps -a
Resume a stopped container:
docker start -ai <id>
Resume the last exited container (dresume
):
docker start -ai $(docker ps -qlf status=exited)
Run Bash in any container, overriding the default entry point:
docker run -it --entrypoint bash <image>
Run Bash, including SSH agent forwarding via Docker Machine:
docker-machine ssh default -At docker run -it --volume '$SSH_AUTH_SOCK:/tmp/ssh-agent' \
--env SSH_AUTH_SOCK=/tmp/ssh-agent --entrypoint bash <image>
On Cygwin use this version to avoid layout issues by bypassing docker-machine
and winpty
(dsh
):
ssh -Ati "$HOME/.docker/machine/machines/default/id_rsa" "docker@$(docker-machine ip)" \
docker run -it --volume '$SSH_AUTH_SOCK:/tmp/ssh-agent' --env SSH_AUTH_SOCK=/tmp/ssh-agent \
--entrypoint bash <image>
Start a container in the background and map port 80 to the host port 80:
docker run --name webserver -d -p80:80 nginx
Then open http://localhost/
in a web browser. (On Windows, run docker-machine ip
to get the host IP then open http://<ip>/
instead.)
List running containers:
docker ps
Stop a running container:
docker stop webserver
Resume a stopped container:
docker start webserver
Connect to a container to see it's input/output (e.g. access logs) – resumes it if it's not already running:
docker start -ai webserver
(Note: Press Ctrl-C to disconnect. This doesn't stop the server/container.)
Stop the most recently started container (dstop
):
docker stop $(docker ps -ql)
Stop all containers (dstopall
):
docker stop $(docker ps -q)
Forcibly stop a container / all containers (dkill
, dkillall
):
docker kill webserver
docker kill $(docker ps -ql)
docker kill $(docker ps -q)
Delete a container:
docker rm webserver
Delete all stopped containers (dclean
):
docker container prune
Create a Dockerfile, preferably in a new directory, switch to that directory and run (db
= docker build
):
docker build -t <name> .
(Here are two examples I created: PHP 7.1 CI base image and Dotfiles setup script test image. I also recommend reading the Best Practices guide.)
Then run it as described above:
docker run -it <name>
List local images / tags:
docker images
Publish to Docker Hub:
docker login
docker tag <name> <username>/<repo>:<version>
docker push <username>/<repo>:<version>
Delete all unused and unnamed images (e.g. old versions of a build) (dclean
):
docker image prune