The missing Docker Cheatsheet
Tags: docker, devops, javascript, node
Published: 2020-02-18 15:43:37

---
title: The missing Docker Cheatsheet
published: true
description: 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.
tags: docker, devops, javascript, node
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/cd0kz859dbomb0qvnee6.png
series: Development with Docker
---

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](https://github.com/blacksonic/node-docker-workflow).

```docker
# Dockerfile.short
FROM node:12-alpine

WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

EXPOSE 3000

CMD npm start
```

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

```javascript
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}!`));
```

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.

```bash
docker build -f Dockerfile.short -t express .
```

```bash
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
```

#### docker images

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

```bash
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
express             latest              d85b87f880e3        3 minutes ago       87.6MB
node                12-alpine           afd897e3184b        3 days ago          85.2MB
```

#### 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`.

```bash
docker run -p 3000:3000 -v $(pwd):/app express
```

#### docker ps -a

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

```bash
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
```

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.

```bash
docker logs -f -t ec40c8347a43
```

```bash
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!
```

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](https://hub.docker.com/) 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](https://hub.docker.com/signup).

```bash
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
```

#### 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.

```bash
docker tag express:latest blacksonic/express:latest
```

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](https://hub.docker.com/r/blacksonic/express).

```bash
docker push blacksonic/express:latest
```

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

### 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.

```bash
docker stop ec40c8347a43
```

#### docker rm \<container id\>

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

```bash
docker rm ec40c8347a43
```

#### docker rmi \<image id\>

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

```bash
docker rmi d85b87f880e3
```

#### 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.