Docker Commands Cheat Sheet
Today, we're presenting our Docker Commands Cheat Sheet — a one-page guide to using Docker that includes a glossary of common terms, useful one-liners, cleanup commands, machine commands, compose syntax and instructions on how to interact with a container. But before we get too far ahead of ourselves, let's get some background information on the Docker platform.
What is Docker?
Docker is an open platform to develop, ship, and run applications, more commonly known as a container manager.
What's a container you ask? A container is an encapsulated environment, which runs on top of a very shallow level of abstractions, providing a virtual machine like isolation for running processes. Now if you are just started with Docker, it’s important we define the vocabulary that you'll need to learn as well as a number of utilities you need to master to become proficient with Docker.
Useful Docker Terms
Let's start with the terms. In a nutshell Docker uses images to specify what the container infrastructure should look like for you to run your apps in it.
- Layer - a set of read-only files to provision the system. Think of a layer as a read only snapshot of the filesystem.
- Image - a read-only layer that is the base of your container. It can have a parent image to abstract away the more basic filesystem snapshot. So a Java image would inherit from a linux image with the preinstalled utilities. A tomcat image will have a Java image as the parent because it depends on Java to run Tomcat.
- Container - a runnable instance of the image, basically it is a process isolated by docker that runs on top of the filesystem that an image provides.
- Registry / Hub is the central place where all publicly published images live. You can search it, upload your images there and when you pull a docker image, it comes the repository/hub.
- Docker machine - a VM within which you can run Docker containers. On Linux you can run docker containers natively, but on OSX and Windows you need a layer of abstraction. A docker machine will spin a very lightweight virtual machine that integrates with the docker command line utilities really well.
- Docker compose - is a utility to run multiple containers as a system of containers. It will take care of making them aware of each other and ensure they’re properly connected to each other. This means you can run your application in one container and your database in a different container, and your analytics application in a different container, and so on. This is the ultimate isolation and it means that your applications are independent and are run in development in a very similar way to how the system might work in production.
What Is a Docker Machine?
A Docker machine is a utility that lets you install Docker on virtual hosts, and then manage those hosts from the command line.
Why should developers be interested in docker machine? It is currently the preferred way to run Docker on OSX and Windows. It also helps you to provision and manage docker containers on a network of machines, but that is less interesting from the developer's point of view. Docker machine will create a tiny virtual machine that is capable or running docker itself.
Running Commands on Docker Machines
After installing the machine you run a command like:
docker-machine start default
And your virtual machine named default is ready. However, what you also want is to make docker on the host system understand that it has to work with that virtual machine. To do that you'll run:
docker-machine env default eval "$(docker-machine env default)"
This command will configure your command line environment variables that will help you use docker with a particular docker-machine, in our case default, without additional complexity. As a developer you'll rarely need anything else from the docker machine, you can list the available machines with the
docker-machine ls command and start or stop any particular of them by calling
docker-machine start|stop machine-name. And now we're finally ready to dive into the heaven of containerized applications.
Building a Container in Docker
A docker container is basically a process or a set of processes running in isolation with a predefined provisioned file system. Think about it this way, a container is a collection of processes that have access to the files in the image.
Images are loaded from the registry, where they are publicly available to anyone. They form a hierarchy, so images can have dependencies on other images. This is really convenient, as your development platform images can depend on the image with common OS utilities.
docker pull image_name:tag
The pull command will download the image and all its parents needed to create the containers with that image. The tag parameter is usually used as the part of the name, but if your container evolves, or includes different versions of the software used, it's nice to tag them without changing the base image name.
docker create --name container_name image_name:tag
The create command is used to instantiate the container from the image. You almost always want to name it by providing the --name parameter. To start and stop the container, naturally, you'll use the
docker start container_name and
docker stop container_name commands respectively. Also, almost always when there's a stop command, there's a
kill command too, to terminate the process less graciously.
Now there's a shorthand for create and start command, which is the run. It will create the container and run it, which is really useful for the various one-liners. We'll look at them in the next section of this post.
Sometimes you will want to create your own images, either to dockerize your project setup or just because you can. There are 2 ways to do that. Create a dockerfile in the directory that describes the image and then run:
docker build image_name .
Modify the container from the inside and then commit the changes to the image:
docker commit -m "commit message" -a "author" container_id username/imagename:tag
How do you change the container? You start it and then execute commands you like. To run a command inside the container namespace you run the following docker command:
docker exec -ti container_name "command.sh"
And while your container is running, you can do that multiple times: install necessary components, copy files around, etc. In general, you don't want to build your project into the container, you just map the filesystem on the host to a directory inside the docker container. Then you don't have to worry about changing the build process for your project and you can run it in the same fashion on your host or in the docker container. But if you build the project in the container, map or commit your local Maven repository, npm modules or that of any dependency management tool you use: if will avoid downloading the internet again and again and make building the project so much faster.
Using Docker Compose
We are now in a position to create and run a container. Let’s stick a full copy of your workstation into a single container. Actually no, instead we'll be smart and isolate various components from each other.
Consider the following typical project: a web application consists of one or more backend services and a database. While it is possible to fit all that into a single container, that is clearly not a best practice. So we'll run these parts of the system independently and manage a couple of containers.
Luckily, there's the a utility that helps us with just that, docker-compose. Docker compose allows you to specify a relationship between several containers in a yml file, and then run all of these containers at once.
Docker Compose Example
The syntax for the docker-compose.yml is pretty straightforward. You specify the container name, the image it should use and the starting command for the container. Additionally you can specify the mapping of the ports to your host machine ports and the mapping of the filesystem, so your docker container can see the files from your host system.
version: "2" services: web: container_name: "web" image: java:8 # image name command: java -jar /app/app.jar # command to run ports: # map ports to the host - "4567:4567" volumes: # map filesystem to the host - ./myapp.jar:/app/app.jar mongo: # container name image: mongo # image name
The best part of all this is that you can link the containers together. In the example above, we link the web container to the mongo container, so our web application will be able to find the database. And docker-compose takes care of providing the port mappings between the linked containers.
Let’s chat more about port mappings. You most likely won't be able to access your web application on your host machine using localhost as the hostname. This is because your container is running in the docker-machine, instead of your host machine.
One way to overcome that is to use the following command to figure out the IP of your docker-machine:
docker-machine ip default
Alternatively you can use the forward2docker utility, that our colleague Sergei created, to monitor your docker-machine usage and automatically forward the ports to the localhost. This way, you can use your running application in a docker container as if it were available on localhost.
Useful Docker Commands
This list of Docker commands includes the most useful commands you will use day to day while working with Docker containers.
|Download an image, and all its parents, from the registry.||docker pull image_name|
|Run a shell command inside a freshly created and started container.||docker run -ti --name container_name image_name /command|
|Start a container||docker start container_name|
|Stop a container||docker stop container_name|
|Run a command inside a container from the image and remove the container when command is done.||docker run --rm -ti image_name /command|
|Run a shell command in the container.||docker exec -ti container_name "cmd"|
|Show/follow log output of the container.||docker logs -ft container_name|
|Kill all runnning docker containers.||docker kill $(docker ps -q)|
|Delete dangling Docker images.||docker rmi $(docker images -q -f dangling=true)|
|Remove all stopped containers.||docker rm $(docker ps -a -q)|
Run Tomcat on Java 8 with a custom javaagent attached. This command illustrates mapping the volumes on your host system into the docker container filesystem, see the
-v flag part.
docker run -it --rm -p 8080:8080 -v /host/path/to/your/agent/agent.jar:/agent.jar -e JAVA_OPTS="-javaagent:/agent.jar" tomcat:8.0.29-jre8
Docker containers ensure applications run quickly and accurately across environments. It’s just one of many tools designed to increase developer productivity. JRebel cancels out the slow redeploys associated with Java development for instant code updates, while maintaining application state. Evaluate JRebel for free today and quantify your time savings.
This is just one of our many cheat sheets designed to help you with Java projects. Here are just a few of others: