DEV Community

Cover image for The missing Docker Cheatsheet
Gábor Soós for Emarsys Craftlab

Posted on

The missing Docker Cheatsheet

Docker is becoming increasingly popular among software developers as a container platform. Containers package software in a format that can run isolated on a host operating system. Bundled with only essential libraries and settings, Docker renders lightweight, efficient, self-contained systems that run identically wherever deployed. In this cheat sheet, we'll take a use-case oriented approach: building the image, starting it, and in the end, stopping it and cleaning up after ourselves.

Creating your container

To follow along with the commands, I've borrowed an application with its Dockerfile from my repository representing an ideal Node.js Docker workflow.

# Dockerfile.short FROM node:12-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . EXPOSE 3000 CMD npm start 
Enter fullscreen mode Exit fullscreen mode

The application is an Express web server that responds to incoming HTTP requests.

const express = require('express'); const port = process.env.PORT || 3000; const app = express(); app.get('/', (req, res) => res.send('Hello World!')); app.listen(port, () => console.log(`App listening on port ${port}!`)); 
Enter fullscreen mode Exit fullscreen mode

We'll build and run this file with the upcoming commands.

docker build -f <docker filename> -t <image name> <build context>

Pulls the base image, builds the image inside Dockerfile.short, and names it as express. We can use this name when running the image. The name can contain a tag (express:1): by default, it gets the latest tag. Specifying the name of the Dockerfile is only necessary when it defers from Dockerfile. The dot at the end tells that the build context is the current directory.

docker build -f Dockerfile.short -t express . 
Enter fullscreen mode Exit fullscreen mode
Sending build context to Docker daemon 180.7kB Step 1/7 : FROM node:12-alpine 12-alpine: Pulling from library/node c9b1b535fdd9: Pull complete 750cdd924064: Pull complete 2078ab7cf9df: Pull complete 02f523899354: Pull complete Digest: sha256:e280e51eaa6e626e4df58a5c1f141e453807c30596179330992c55a0bf4114ca Status: Downloaded newer image for node:12-alpine ---> afd897e3184b Step 2/7 : WORKDIR /app ---> Running in c8f379e36c32 Removing intermediate container c8f379e36c32 ---> a11ced1bd480 Step 3/7 : COPY package*.json ./ ---> e811deacf584 Step 4/7 : RUN npm ci --only=production ---> Running in 401bdc088d44 added 50 packages in 1.395s Removing intermediate container 401bdc088d44 ---> 644c8661eff7 Step 5/7 : COPY . . ---> 270057bb701a Step 6/7 : EXPOSE 3000 ---> Running in cd9d70daad58 Removing intermediate container cd9d70daad58 ---> 4c6eb54071d1 Step 7/7 : CMD npm start ---> Running in fc2a7b3e7e11 Removing intermediate container fc2a7b3e7e11 ---> d85b87f880e3 Successfully built d85b87f880e3 Successfully tagged express:latest 
Enter fullscreen mode Exit fullscreen mode

docker images

Shows all the runnable images on the host machine. We'll see our application with the name express.

REPOSITORY TAG IMAGE ID CREATED SIZE express latest d85b87f880e3 3 minutes ago 87.6MB node 12-alpine afd897e3184b 3 days ago 85.2MB 
Enter fullscreen mode Exit fullscreen mode

docker run -p <host port>:<container port> <image name>

Runs the built image and connects the containers port with the host machines port (-p 3000:3000). The result is the application is available on http://localhost:3000. If we don't want to block the terminal, we can run the image in detached mode -d. If we're going to have live-reload on file changes, for example, with Nodemon, we can attach the local folder as a volume -v $(pwd):/app.

docker run -p 3000:3000 -v $(pwd):/app express 
Enter fullscreen mode Exit fullscreen mode

docker ps -a

Lists the running containers. After docker run, we'll see the application here.

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ec40c8347a43 express "docker-entrypoint.s…" 6 seconds ago Up 5 seconds 0.0.0.0:3000->3000/tcp hardcore_vaughan 
Enter fullscreen mode Exit fullscreen mode

The -a flag shows all the containers, not just the running ones.

docker logs -f -t <image id>

Shows the standard output with timestamps from the running container.

docker logs -f -t ec40c8347a43 
Enter fullscreen mode Exit fullscreen mode
2020-02-10T18:22:07.672710300Z 2020-02-10T18:22:07.672788300Z > node-docker-workflow@1.0.0 start /app 2020-02-10T18:22:07.672825700Z > node src/index.js 2020-02-10T18:22:07.672850600Z 2020-02-10T18:22:07.917358100Z App listening on port 3000! 
Enter fullscreen mode Exit fullscreen mode

The -f flag tells the command to listen for new logs. If all the records are too much, you can restrict it to only some lines --tail 100.

Publishing the image

Our application is running fine on our local computer, but we can't deploy it anywhere. For deployment, we have to publish it to a repository. For demonstration purposes, we'll use the default DockerHub repository.

docker login

Logs in to the repository, by default to Dockerhub. We need a Dockerhub account before this to work. You can do the registration here.

Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one. Username: blacksonic Password: Login Succeeded 
Enter fullscreen mode Exit fullscreen mode

docker tag <source image name>:<target tag name> <target image name>:<target tag name>

Names the image with a tag that we will use when uploading the image.

docker tag express:latest blacksonic/express:latest 
Enter fullscreen mode Exit fullscreen mode

We have to prefix the image name before uploading it to Dockerhub (blacksonic is my username).

docker push <image name>:<tag name>

Uploads the image to the repository. You can see the uploaded image now on the site https://hub.docker.com/r/blacksonic/express.

docker push blacksonic/express:latest 
Enter fullscreen mode Exit fullscreen mode
The push refers to repository [docker.io/blacksonic/express] d93ac2ab321f: Pushed 5216338b40a7: Pushed latest: digest: sha256:8b418f814535e24906fcb412f8e564ced393e4976586d710bbff60b5fdb2d11c size: 1993 
Enter fullscreen mode Exit fullscreen mode

Cleaning it up

We've started and pushed our container successfully. It's time to clean up after ourselves.

docker stop <container id>

Stops the running container. The container won't be deleted.

docker stop ec40c8347a43 
Enter fullscreen mode Exit fullscreen mode

docker rm <container id>

Deletes the container, you won't be able to start it again.

docker rm ec40c8347a43 
Enter fullscreen mode Exit fullscreen mode

docker rmi <image id>

Deletes the image: you'll have to build it again to start it as a container.

docker rmi d85b87f880e3 
Enter fullscreen mode Exit fullscreen mode

docker stop $(docker ps -a -q)

Stops all processes from running containers. After this, docker ps -a will return empty results.

docker rm $(docker ps -a -q)

Removes all the containers.

docker rmi $(docker images -q)

Removes all the images. After this, docker images will return empty results.

docker image prune --all

Removes all unused images. Unused means no running containers exist based on the image.

Summary

Encountering containerization can be hard for the first time, but can be simplified by knowing the right commands which can tell what's happening. With an example configuration, you can try them, and you realize that developing with containers can be as easy as doing it on your local machine.

Top comments (2)

Collapse
 
jannikwempe profile image
Jannik Wempe

Awesome, thanks. It's is nice overview for the most used commands.

Just want to mention that some commands are actually the old syntax. Yes, they are shorter but I prefer the newer syntax, since they make more sense to me and are more descriptive. Examples:

docker image build # instead of docker build docker container ls # instead of docker ps docker container stop # instead of docker stop 

Maybe you want to mention that 🆒

Collapse
 
sonicoder profile image
Gábor Soós

Thanks for the feedback, obviously more descriptive than the old ones 👍