The Ultimate Docker Cheatsheet For Everyone

Sangam Biradar

Principal Security Advocate , Deepfence

Docker Community Leader

docker run -it --entrypoint EXECUTABLE IMAGE
docker run -it --entrypoint bash nginx
  • 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 cp TARGET CONTAINER:SOURCE
docker cp index.html web:/index.html
  • 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 
  •  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
docker build -t IMAGE DIRECTORY
docker build -t myimage .
  • 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
  •  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 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
  • Show all modified files in container
docker port CONTAINER
docker port web
  • Show mapped ports of a container
docker diff CONTAINER
docker diff web
  • 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
  • Listing Networks 
docker network ls
  • Removing a network
docker network rm MyOverlayNetwork
  • Getting information about network
docker network inspect MyOverlayNetwork
  • Connecting running container to network
docker network connect MyOverlayNetwork nginx
  • Connecting running container to network when its starts 
docker container run -it -d 
--network=MyOverlayNetwork nginx
  • Disconnecting a container from network  
docker container run -it -d 
--network=MyOverlayNetwork nginx
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 services
docker service ls

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


  • listing swarm task
docker service ps


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

The FROM instruction

# Dockerfile
FROM nginx:1.15.2
  • every Dockerfile must have from instruction, and it must be the first instruction in the file 
# 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"
  • you can view all of the labels for an image by using the inspect command :
# 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"
docker inspect --format `' < dockerimage_name : tag > | jq `.Labels'
LABEL org.opencontainers.image.authors="SvenDowideit@home.org.au"
  • Maintainer (deprecated) to set a label corresponding to the maintainer field you could use :

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>"]
  • the ADD instruction just seems similar to COPY Instruction: 
  • 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

# 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"]

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"]
docker inspect --format `' < dockerimage_name : tag > | jq `.Env'
  • you can inspect the image metadata and see the environment variables that have created: 
docker container run -rm --env chnageMe="new value" --env adhoc="run time"  sangam14-env-demo env
  • environment variables can be set(or overridden ) when a container is run using the --env parameter: 

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 .

The difference between ENV and ARG

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

  6. 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>]
# 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 .
  • 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  
    

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
# VOLUME instruction Dockerfile for Docker Quick Start
FROM alpine
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol
CMD ["sh"]
  • 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:
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
# EXPOSE instruction syntax
EXPOSE <port> [<port>/<protocol>...]

The EXPOSE instruction

  • 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"]
# Exec form of RUN instruction using bash
RUN ["/bin/bash", "-c", "echo hello world > /myvol/greeting"]
# 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"]

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 Dockerfile for Docker Quick Start
FROM alpine
RUN apk add curl
ENTRYPOINT ["curl"]
CMD ["--help"]
docker container run sangam14-entrypoint-demo google.com
# ENTRYPOINT instruction syntax
ENTRYPOINT command param1 param2 (shell form)
ENTRYPOINT ["executable", "param1", "param2"] (exec form, best practice)
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 ENTRYPOINTcommand or for executing an ad-hoc command in a container.
  4. 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

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
  • Redeploy just one Service 
docker-compose up $SERVICE_NAME

  • Docker Compose Build 
docker-compose build

  • 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

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

Docker Compose Examples 

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

  # Redis cache container
  redis:
    image: "redis:alpine"
  • sample docker-compose file
  • 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

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

  # expose ports to linked services (not to host)
  expose: ["3000"]
  • Port Binding
  # 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]
  • Command and entrypoint
  volumes:
    - /var/lib/mysql
    - ./_data:/var/lib/mysql 
    # Host_volume: container_volume
  • Volume - Storage Mapping
  # environment vars
  environment:
    DB_HOST: http://localhost:263

  environment:
    - RACK_ENV=development

  # environment vars from file
  env_file: .env
  env_file: [.env, .development.env]
  • Environment Variable
  # 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
  • Dependencies - depend service 
services:
  web:
    labels:
      com.app.description: "My web app"
  • Labels
  • DNS Servers
services:
  web:
    dns: 8.8.8.8
    dns:
      - 8.8.8.8
      - 8.8.4.4

DockerFile

build image

Image

Container

ENV available

ARG ACCOUNT_ID

FROM ubuntu:latest
RUN echo $ACCOUNT_ID
version: '3'
services:
  app:
    build:
       context: .
       args:                                                                     
         - ACCOUNT_ID=abcd
 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.
... and then the argument can be passed in through the docker-compose file like so:
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
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

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

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: {}

Docker Security 

FROM python:3.9-alpine
RUN addgroup -S appgroup \

&& adduser -S appuser -G appgroup


USER appuser
ARG TMP_VAR=”myvar” [REST_OF_YOUR_DOCKERFILE]
Always prefer using a trusted image, preferably from the Docker Official Images If you need to choose a base distro, 

Alpine Linux is recommended.
Wondering if you should use 
 the:latesttagorapinnedversion? 
This is a tradeoff to consider, but pinning to a stable release is what is generally recommended.
ARG is recommended 
 for variables that are not used at runtime 
 but don’t hardcode secrets with it !
docker run -v /var/run/docker.sock:/var/ \
 run/docker.sock
Exposing the Docker socket is equivalent to exposing an unrestricted root access 
 to your host.

Don't use

Create and run your 
 app as an unprivileged user (either explicitly 
 in the Dockerfile, 
or by using an arbitrary userID at runtime).
docker run --name myapp --rm -it \
-u 4000 \

--security-opt no-new-privileges \
--cap-drop=ALL \
 --cap-add=NET_BIND_SERVICE \
 -p 8080:80 \
--cpus=0.5 \
 --restart=on-failure:5 \
 --ulimit nofile=5 \
 --ulimit nproc=5 \
 --memory 128m \
--read-only \

--tmpfs /tmp:rw,noexec,nosuid \
 -v /usr/local/myapp:/app/:ro \
--bridge=none \
 --network=web \
--log-driver=<logging driver> \ myimage:latest
Avoid DoS attacks by 
explicitly constraining the use of resources.
It is recommended 
 to export your logs 
 to an external service
•Limitthemountedfilesystemtobe 
 read-only.
• Provide an in-memory storage for 
 temporary files at /tmp.
•Bindyourlocalpartition/usr/local/myapp 
 using the read-only option too.
You can also create a read-only bind mount
docker run --mount \ source=<volume-name>,destination=/ \
 path/in/container,readonly
Drop all the capabilities and only add those necessary(here we add NET_BIND_SERVICE to bind to a port under 1024 like 80).
Disable the default bridge and use 
 a dedicated network 
 to. expose the host interface.
docker run --privileged
Which is giving your container 
root capabilities on the host
docker run --cgroup-parent
By allowing shared resources with the host, you are putting it at risk.
docker run --network=”host”
But instead create a dedicated network isolate the host's network interface:
docker network create web

Don't use

Thanks You !

Follow on Github :-  https://github.com/sangam14