The Ultimate Docker CheatSheet For Everyone

Photo by Timelab Pro on Unsplash

The Ultimate Docker CheatSheet For Everyone

Table of contents

Start a new Container from an Image

docker run IMAGE
docker run nginx

Start a new Container from an Image and assign it a name

docker run --name CONTAINER IMAGE
docker run --name web nginx

Start a new Container from an Image and map a Port

docker run -p HOSTPORT:CONTAINERPORT IMAGE
docker run -p 8080:80 nginx

Start a new Container from an Image and map All ports

docker run -P IMAGE
docker run -P nginx

Start a new Container from an Image and start container in background

docker run -d IMAGE
docker run -d nginx

Start a new Container from an Image and assign it a hostname

docker run --hostname HOSTNAME IMAGE
docker run --hostname srv nginx

Start a new Container from an Image and add a dns entry

docker run --add-host HOSTNAME:IP IMAGE

Start a new Container from an Image and map a local directory into the container

docker run -v HOSTDIR:TARGETDIR IMAGE
docker run -v ~/:/usr/share/nginx/html nginx

Start a new Container from an Image but change the entry point

docker run -it --entrypoint EXECUTABLE IMAGE
docker run -it --entrypoint bash nginx

showing a list of running container

docker ps

showing list of all container

 docker ps -a

Delete a container

docker rm CONTAINER
docker rm web

Delete a running container

docker rm -f CONTAINER
docker rm -f web

Delete stopped containers

docker container prune

Start a running container

docker stop CONTAINER
docker stop web

Start a stopped container

docker start CONTAINER
docker start web

Copy a file from a container to the host

docker cp CONTAINER:SOURCE TARGET
docker cp web:/index.html index.html

Copy a file from the host to a container

docker cp TARGET CONTAINER:SOURCE
docker cp index.html web:/index.html

Start a shell inside a running container

docker exec -it CONTAINER EXECUTABLE
docker exec -it web bash

Rename a container

docker rename OLD_NAME NEW_NAME
docker rename 096 web

Create an image out of container

docker commit CONTAINER
docker commit web

export the content of container

docker export container

attach to the running container (stdin/stdout/stderr)

docker attached container

Wait until the container terminates and return exit code

docker wait CONTAINER

Create Container without starting

docker create [IMAGE]

show the history of image

docker history [IMAGE]

Kill a container by sending a SIGKILL to a running container

docker kill [CONTAINER]

Pause Processes in a running container

docker pause [CONTAINER]

Unpause processes in a running container

docker unpause [CONTAINER]

Download an image

docker pull IMAGE[:TAG]
docker pull nginx

Upload an image to a repository

docker push IMAGE
docker push myimage:1.0

Delete an image

docker rmi IMAGE

Show a list of all Images

docker images

Delete dangling images

docker image prune

Delete all unused images

docker image prune -a

Build an image from a Dockerfile

docker build DIRECTORY
docker build .

Tag an image

docker tag IMAGE NEWIMAGE
docker tag ubuntu ubuntu:18.04

Build and tag an image form a Dockerfile

docker build -t IMAGE DIRECTORY
docker build -t myimage .

Start an image to .tar file

docker save IMAGE > FILE
docker save nginx > nginx.tar

Load an image from a .tar file

docker load -i TARFILE
docker load -i nginx.tar

Show all modified files in container

docker diff CONTAINER
docker diff web

Show mapped ports of a container

docker port CONTAINER
docker port web

Show the logs of a container

docker logs CONTAINER
docker logs web

Show stats of running container

docker stats

Show Processes of container

docker top CONTAINER
docker top web

Show installed docker version

docker version

Get Detailed info about an object

docker inspect NAME
docker inspect nginx

Create an overlay network

docker network create -d overlay MyOverlayNetwork

Creating Bridge Network

docker network create -d bridge MyBridgeNetwork

Creating Customised overlay network

docker network create -d overlay \
  --subnet=192.168.0.0/16 \
  --subnet=192.170.0.0/16 \
  --gateway=192.168.0.100 \
  --gateway=192.170.0.100 \
  --ip-range=192.168.1.0/24 \
  --aux-address="my-router=192.168.1.5" --aux-address="my-switch=192.168.1.6" \
  --aux-address="my-printer=192.170.1.5" --aux-address="my-nas=192.170.1.6" \
  MyOverlayNetwork

Removing a network

docker network rm MyOverlayNetwork

Listing Networks

docker network ls

Connecting running container to network

docker network connect MyOverlayNetwork nginx

Getting information about network

docker network inspect MyOverlayNetwork

Connecting running container to network when its starts

docker container run -it -d 
--network=MyOverlayNetwork nginx

Disconnecting a container from network

docker network disconnect MyOverlayNetwork nginx

Initialising the swarm

docker swarm init --advertise-addr 192.168.10.1

Getting a worker to join swarm

docker swarm join-token worker

getting manager to join swam

docker swarm join-token manager

listing swarm task

docker service ps

Creating service

docker service create --name vote -p 8080:80 instavote/vote

listing services

docker service ls

scaling service

docker service scale vote=3

Updating Service

docker service update --image instavote/vote:movies vote
docker service update --force --update-parallelism 1 --update-delay 30s nginx
docker service update --update-parallelism 5--update-delay 2s --image instavote/vote:indent vote
docker service update --limit-cpu 2 nginx
docker service update --replicas=5 nginx

DockerFile

A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image. Think of it as a shellscript. It gathered multiple commands into a single document to fulfill a single task

Build command used to create an image from Dockerfile

docker build

you can name your image as well

docker build -t my-image

if your dockerfile is placed in another path

docker build -f /path/to/a/Dockerfile .

every Dockerfile must have from instruction, and it must be the first instruction in the file

# Dockerfile
FROM nginx:1.15.2

The FROM instruction

# hello-world Dockerfile
FROM scratch
COPY hello /
CMD ["/hello"]

The LABEL instruction

# LABEL instruction syntax
# LABEL <key>=<value> <key>=<value> <key>=<value> ...
LABEL maintainer="sangam biradar <sangambiradar@hotmail.com>"
LABEL "description"="My development Ubuntu image"
LABEL version="1.0"
LABEL label1="value1" \
 label2="value2" \
 lable3="value3"
LABEL my-multi-line-label="Labels can span \
more than one line in a Dockerfile."
LABEL support-email="support@something.com" support-phone="123-456-7890"

earlier in the Dockerfile

LABEL version="1.0"

later in the Dockerfile...

LABEL version="2.0"
# The Docker image metadata will show version="2.0"

Maintainer (deprecated) to set a label corresponding to the maintainer field you could use :

LABEL org.opencontainers.image.authors="SvenDowideit@home.org.au"

you can view all of the labels for an image by using the inspect command :

docker inspect --format `' < dockerimage_name : tag > | jq `.Labels'

The COPY instruction

# COPY instruction syntax
COPY [--chown=<user>:<group>] <src>... <dest>
# Use double quotes for paths containing whitespace)
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]
// COPY instruction Dockerfile for Docker Quick Start
FROM alpine:latest
LABEL version=1.0
# copy multiple files, creating the path "/theqsg/files" in the process
COPY file* theqsg/files/
# copy all of the contents of folder "folder1" to "/theqsg/" 
# (but not the folder "folder1" itself)
COPY folder1 theqsg/
# change the current working directory in the image to "/theqsg"
WORKDIR theqsg
# copy the file special1 into "/theqsg/special-files/"
COPY --chown=35:35 special1 special-files/
# return the current working directory to "/"
WORKDIR /
CMD ["sh"]
docker container run --rm cloudnativelabs-demo:1.0  ls -l theqsg

The ADD instruction

# ADD instruction syntax
ADD [--chown=<user>:<group>] <src>... <dest>
# Use double quotes for paths containing whitespace)
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
# ADD instruction Dockerfile for Docker Quick Start
FROM alpine
LABEL version=3.0
ADD https://github.com/docker-library/hello-world/raw/master/amd64/hello-world/hello /
RUN chmod +x /hello
CMD ["/hello"]

Difference between COPY and ADD Instruction

  1. ADD instruction do more then COPY Instruction
  2. Depends upon the value used in source path input
  3. COPY instruction the source can be file or folder
  4. ADD instruction the source can be file or folder , URL or .tar file
  5. ADD instruction , .tar file need to extract into corresponding folder

The ENV instruction

# ENV instruction syntax
# This is the form to create a single environment variable per instruction
# Everything after the space 
# following the <key> becomes the value
ENV <key> <value>
# This is the form to use when you want to create more 
# than one variable per instruction
ENV <key>=<value> ...

ENV instruction Dockerfile for Docker Quick Start

FROM alpine
ENV appDescription This app is a sample of using ENV instructions
ENV appName=env-demo
ENV note1="The First Note First" note2=The\ Second\ Note\ Second \
note3="The Third Note Third"
ENV changeMe="Old Value"
CMD ["sh"]

you can inspect the image metadata and see the environment variables that have created:

docker inspect --format `' < dockerimage_name : tag > | jq `.Env'

environment variables can be set(or overridden ) when a container is run using the --env parameter:

docker container run -rm --env chnageMe="new value" --env adhoc="run time"  sangam14-env-demo env

The ARG instruction

# The ARG instruction syntax
ARG <varname>[=<default value>]

# The build-arg parameter syntax
docker image build --build-arg <varname>[=<value>] ...
# ARG instruction Dockerfile for Docker Quick Start
FROM alpine

ENV key1="ENV is stronger than an ARG"
RUN echo ${key1}
ARG key1="not going to matter"
RUN echo ${key1}

RUN echo ${key2}
ARG key2="defaultValue"
RUN echo ${key2}
ENV key2="ENV value takes over"
RUN echo ${key2}
CMD ["sh"]

Build the image and look at the output from the echo commands

docker image build --rm \
 --build-arg key1="buildTimeValue" \
 --build-arg key2="good till env instruction" \
 --tag arg-demo:2.0 .

ENV vs ARG instruction Dockerfile for Docker Quick Start

FROM alpine
ENV lifecycle="production"
RUN echo ${lifecycle}
ARG username="35"
RUN echo ${username}
ARG appdir
RUN echo ${appdir}
ADD hello /${appdir}/
RUN chown -R ${username}:${username} ${appdir}
WORKDIR ${appdir}
USER ${username}
CMD ["./hello"]

with this Dockerfile, you would want to provide --build-arg parameters for appdirARG instruction & the username ( if you want to override the default) to the build command. you would also provide an --env parameter at runtime to override the lifecycle variable :

# Build the arg3 demo image
docker image build --rm \
   --build-arg appdir="/opt/hello" \
   --tag arg-demo:3.0 .

# Run the arg3 demo container
docker container run --rm --env lifecycle="test" arg-demo:3.0

The difference between ENV and ARG

  1. ENVs persist into running container , ARGs do not
  2. ARGs use corresponding build parameters , ENVs do not
  3. ENV instructions must include bath a ket and a value .
  4. ARG Instruction have a key but the(default) value is optional
  5. ENVs are more significant than ARGS

Note : You should never use either ENV or ARG instructions to provide secret data to the build command or resulting containers because the values are always visible in clear text to any user that runs docker command history

The USER instruction

# User instruction syntax
USER <user>[:<group>] or
USER <UID>[:<GID>]

When the image build start the current user is root or UID=0GID=0 then , the USER instruction is executed to set the current user and group to games:games

# USER instruction Dockerfile for Docker Quick Start 
FROM alpine
RUN id
USER games:games
run id
CMD ["sh"]
docker image build --rm --tag sangam14-user-demo .

The WORKDIR instruction

# WORKDIR instruction syntax
WORKDIR instruction syntax
WORKDIR /path/to/workdir
# WORKDIR instruction Dockerfile for Docker Quick Start
FROM alpine
# Absolute path...
WORKDIR /
# relative path, relative to previous WORKDIR instruction
# creates new folder
WORKDIR sub-folder-level-1
RUN touch file1.txt
# relative path, relative to previous WORKDIR instruction
# creates new folder
WORKDIR sub-folder-level-2
RUN touch file2.txt
# relative path, relative to previous WORKDIR instruction
# creates new folder
WORKDIR sub-folder-level-3
RUN touch file3.txt
# Absolute path, creates three sub folders...
WORKDIR /l1/l2/l3
CMD ["sh"]
docker container run --rm sangam14-workdir-demo  ls -lR /sub-folder-1

The VOLUME instruction

# VOLUME instruction syntax
VOLUME ["/data"]
# or for creating multiple volumes with a single instruction
VOLUME /var/log /var/db /moreData

Other ways to create volumes are to add volume parameters to the docker container run command or to use the docker volume create command .

it create a volume at /myvol that will have a file named greeting:

# VOLUME instruction Dockerfile for Docker Quick Start
FROM alpine
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
CMD ["sh"]
docker image ls
cd volume-demo
ll
cat Dockerfile
docker image build --rm --tag volume-demo:1.0 .
docker image ls
clear
docker container run --rm -it --mount source=myvolsrc,target=/myvol sangam14-volume-demo:1.0
clear
docker volume ls
docker container run --rm -d --name vol-demo volume-demo:1.0 tail -f /dev/null
docker volume ls
docker container stop vol-demo
docker container ls
docker volume ls
clear
docker volume create myvolsrc
docker container run -d --name vol-demo --mount source=myvolsrc,target=/myvol sangam14-volume-demo:1.0 tail -f /dev/null
docker container exec vol-demo ls -l /myvol
docker volume inspect myvolsrc -f ""
echo /var/lib/docker/volumes/myvolsrc/_data/new-file.txt
touch /var/lib/docker/volumes/myvolsrc/_data/new-file.txt\n
sudo touch /var/lib/docker/volumes/myvolsrc/_data/new-file.txt\n
docker container exec vol-demo ls -l /myvol
docker container stop vol-demo
docker container rm vol-demo
docker volume rm myvolsrc
docker volume ls
docker container ls

The EXPOSE instruction

# EXPOSE instruction syntax
EXPOSE <port> [<port>/<protocol>...]

it is important to understand that including the Expose Instruction in the Dockerfile Doesn't actually open network ports in the containers

when containers are run from the images with the EXPOSE instruction in their Dockerfile , it is still necessary to include -p or -P parameters to actually open the network ports to the container

you can include multiple EXPOSE instruction as needed in your Dockerfile as needed . Including the -P parameter at runtime is a shortcut way to automatically open ports for all of EXPOSE instruction included in the Dockerfile. The Corresponding host ports will be randomly assigned when using -P parameter on the run command

Think of the EXPOSE instruction as message from the image developer as a message from the image developer telling you that the application in image is expecting you to open the indicated ports(s) when you run your container . the EXPOSE instruction creates a zero-byte-sized layer in resulting images

The RUN instruction

# RUN instruction syntax
# Shell form to run the command in a shell
# For Linux the default is "/bin/sh -c"
# For Windows the default is "cmd /S /C"
RUN <command>

# Exec form
RUN ["executable", "param1", "param2"]
# RUN instruction Dockerfile for Docker Quick Start
FROM ubuntu
RUN useradd --create-home -m -s /bin/bash dev
RUN mkdir /myvol
RUN echo "hello DQS Guide" > /myvol/greeting
RUN ["chmod", "664", "/myvol/greeting"]
RUN ["chown", "dev:dev", "/myvol/greeting"]
VOLUME /myvol
USER dev
CMD ["/bin/bash"]
# Exec form of RUN instruction using bash
RUN ["/bin/bash", "-c", "echo hello world > /myvol/greeting"]

The CMD instruction

# CMD instruction syntax
CMD command param1 param2 (shell form)
CMD ["executable","param1","param2"] (exec form)
CMD ["param1","param2"] (as default parameters to ENTRYPOINT)
# CMD instruction examples
CMD ["/bin/bash"]
CMD while true; do echo 'DQS Expose Demo' | nc -l -p 80; done
CMD echo "How many words are in this echo command" | wc -
CMD tail -f /dev/null
CMD ["-latr", "/var/opt"]

The ENTRYPOINT instruction

# ENTRYPOINT instruction syntax
ENTRYPOINT command param1 param2 (shell form)
ENTRYPOINT ["executable", "param1", "param2"] (exec form, best practice)
# ENTRYPOINT instruction Dockerfile for Docker Quick Start
FROM alpine
RUN apk add curl
ENTRYPOINT ["curl"]
CMD ["--help"]
docker container run sangam14-entrypoint-demo google.com

both CMD and ENTRYPOINT instructions define what command gets executed when running a container. There are few rules that describe their co-operation.

  1. Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
  2. ENTRYPOINT should be defined when using the container as an executable.
  3. CMD should be used as a way of defining default arguments for an.
  4. ENTRYPOINT command or for executing an ad-hoc command in a container.
  5. CMD will be overridden when running the container with alternative arguments.

The HEALTHCHECK instruction

# HEALTHCHECK instruction syntax
HEALTHCHECK [OPTIONS] CMD command (check container health by running a command inside the container)
HEALTHCHECK NONE (disable any HEALTHCHECK inherited from the base image)

There are four options that can be used when setting the HEALTHCHECK, and these options are as follows:

HEALTHCHECK CMD options


--interval=DURATION (default: 30s)
--timeout=DURATION (default: 30s)
--start-period=DURATION (default: 0s)
--retries=N (default: 3)

HEALTHCHECK instruction Dockerfile for Docker Quick Start


FROM alpine
RUN apk add curl
EXPOSE 80/tcp
HEALTHCHECK --interval=30s --timeout=3s \
CMD curl -f http://localhost/ || exit 1
CMD while true; do echo 'DQS Expose Demo' | nc -l -p 80; done
docker container run --rm -d -p 80:80 --name health sangam14-healthcheck

The ONBUILD instruction

# ONBUILD instruction syntax
ONBUILD [INSTRUCTION]
# my-base Dockerfile
FROM alpine
LABEL maintainer="sangam biradar"
ONBUILD LABEL version="1.0"
ONBUILD LABEL support-email="sangam@something.com" support-phone="123-456-7890"
CMD ["sh"]

Next, let’s build an image named my-app that is built FROM the my-base image, like so:

# my-app Dockerfile
FROM my-base:1.0
CMD ["sh"]
 docker inspect --format "" myapp | jq `.Labels'

The STOPSIGNAL instruction

# STOPSIGNAL instruction syntax
STOPSIGNAL signal
# Sample STOPSIGNAL instruction using a position number in the syscall table
STOPSIGNAL 9
# or using a signal name
STOPSIGNAL SIGQUIT

filippo.io/linux-syscall-table

Heredocs in Dockerfile

FROM nginx

COPY index.html /usr/share/nginx/html
FROM nginx

COPY <<EOF /usr/share/nginx/html/index.html
(your index page goes here)
EOF

You can even copy multiple files at once, in a single layer:

COPY <<robots.txt <<humans.txt /usr/share/nginx/html/
(robots content)
robots.txt
(humans content)
humans.txt
FROM photon:1.0

ARG BASEURL="https://vmware.bintray.com/powershell"

RUN echo $'[powershell]\n\
name=VMware Photon Linux 1.0(x86_64)\n\
baseurl='$BASEURL$'\n\
gpgcheck=0\n\
enabled=1\n\
skip_if_unavailable=True\n '\
>> /etc/yum.repos.d/powershell.repo

CMD ["/bin/bash"]
docker build -t sample .
docker run --rm -it sample cat /etc/yum.repos.d/powershell.repo

Docker Compose

Docker Compose Build

docker-compose build

Redeploy just one Service

docker-compose up $SERVICE_NAME

start all services / container using docker compose

docker-compose up

// Specify a custom filepath for your 
//docker-compose file 
// (it assumes docker-compose.yml in
//your current directory by default)

docker-compose -f custom-docker-compose.yml up

// Apply multiple compose files (changes in latter)

docker-compose -f docker-compose.yml docker-compose-production.yml

sample docker-compose file

#docker-compose.yml file
version: '3'
services:
  # Your web application => Container
  web:
    build: .
    ports:
    - "5000:5000"

  # Redis cache container
  redis:
    image: "redis:alpine"
version: "3"

networks:
  backend:
    driver: bridge

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: app
    image: ${REGISTRY}/my-project-name
    restart: always
    ports:
      - "80:80"
      - "443:443"
    depends_on:
        - db
    networks:
      - backend
    env_file:
      - ./.env

  db:
    image: mariadb:10.5
    container_name: db
    restart: always
    networks:
        backend
    volumes:
      - mysql-data:/var/lib/mysql
    environment:
      - FOO=bar
      - SOME_ENV_VAR=${SUBSTITUTED_VARIABLE}
    env_file:
      - ./.env

volumes:
  mysql-data:
    driver: local

Labels

services:
  web:
    labels:
      com.app.description: "My web app"

Dependencies - depend service

  # makes the `db` service available 
  # as the hostname `database`
  # (implies depends_on)
  links:
    - db:database
    - redis
  # make sure `db` is alive before starting
  depends_on:
    - db

Port Binding

  ports:
    - "3000"
    - "8000:80"  # HOST:CONTAINER

  # expose ports to linked services (not to host)
  expose: ["3000"]

Build from DockerFile or Image

# Service name
web:
  # build from Dockerfile
  build: .

  # build from custom Dockerfile
  build:
    context: ./dir
    dockerfile: Dockerfile.dev

  # build from image
  image: centos:latest
  image: ubuntu:14.04
  image: tutum/influxdb
  image: example-registry:4000/postgresql

Command and entrypoint

  # command to execute
  command: bundle exec thin -p 3000
  command: [bundle, exec, thin, -p, 3000]

  # override the entrypoint
  entrypoint: /app/start.sh
  entrypoint: [php, -d, vendor/bin/phpunit]

Volume - Storage Mapping

  volumes:
    - /var/lib/mysql
    - ./_data:/var/lib/mysql 
    # Host_volume: container_volume

Environment Variable

  # environment vars
  environment:
    DB_HOST: http://localhost:263

  environment:
    - RACK_ENV=development

  # environment vars from file
  env_file: .env
  env_file: [.env, .development.env]

DNS Servers

services:
  web:
    dns: 8.8.8.8
    dns:
      - 8.8.8.8
      - 8.8.4.4

You can specify ARG as part of your Dockerfile at the start (above the FROMstatement). These can then be used later as part of the build. E.g.

ARG ACCOUNT_ID

FROM ubuntu:latest
RUN echo $ACCOUNT_ID

ACCOUNT_ID to be provided, but we could specify a default value that would be overridden, like so:

 ARG ACCOUNT_ID="def"

FROM ubuntu:latest
RUN echo $ACCOUNT_ID

.. and then the argument can be passed in through the docker-compose file like so:

version: '3'
services:
  app:
    build:
       context: .
       args:                                                                     
         - ACCOUNT_ID=abcd

If using docker build instead of docker-compose build, then you can provide the build arguments like so:

#!/bin/sh
docker build \
  --build-arg ACCOUNT_ID=abc \
  --build-arg SECOND_BUILD_ARG=admin \
...

Specifying Build Arguments In Docker-compose Command​

docker-compose build \
  --build-arg ACCOUNT_ID=abc \
  --build-arg SECOND_BUILD_ARG=admin

future :- compose-spec.io

A specification for developer-centric application definition used in Cloud Native Applications

for more details:- github.com/compose-spec/compose-spec/blob/m..

services:
  frontend:
    image: awesome/webapp
    ports:
      - "443:8043"
    networks:
      - front-tier
      - back-tier
    configs:
      - httpd-config
    secrets:
      - server-certificate

  backend:
    image: awesome/database
    volumes:
      - db-data:/etc/data
    networks:
      - back-tier

volumes:
  db-data:
    driver: flocker
    driver_opts:
      size: "10GiB"

configs:
  httpd-config:
    external: true

secrets:
  server-certificate:
    external: true

networks:
  # The presence of these objects 
  # is sufficient to define them
  front-tier: {}
  back-tier: {}

Did you find this article valuable?

Support CloudNativeFolks Community by becoming a sponsor. Any amount is appreciated!