User Tools

Site Tools



Show running containers (process status):

docker ps
docker ps -a
docker ps -a --no-trunc
docker ps -q
docker stop $(docker ps -q)      # run from PowerShell

Show images:

docker images
docker image ls
docker image ls --digests
docker images -f dangling=true

Pull (i.e., download) a docker image from a repository (a registry):

docker pull [OPTIONS] NAME[:TAG|@DIGEST]
    docker pull mongo
    docker pull ubuntu
    docker pull ubuntu:14.04
    docker pull ubuntu:16.04

Run a command in a new container created from an image:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
    docker run -it microsoft/dotnet:latest
    docker run mongo
    docker run hello-world
    docker run -it ubuntu bash
    docker run -it ubuntu:16.04 bash
    docker run -it --name container_name ubuntu:latest /bin/bash
    docker run -d ubuntu

Note that 'docker create' creates a container without running a command.

Run a command in a running container. It's an equivalent to running another copy of the installed software:

    docker exec -it mycontainer bash
    docker exec -it mycontainer mongo
    docker exec -it mycontainer powershell

Start a container:

    docker start -i tmp

Stop a container. Stopping a container does not erase its state data. 'docker stop' is an opposite of 'docker run':

    docker stop ubuntu
    docker stop $(docker ps -aq)
    docker stop $(docker ps -a -q)

Remove containers, images, and other stuff:

    docker rm ubuntu:latest
    docker rm $(docker ps -aq)
    docker rm -f $(docker ps -aq)
    docker rm $(docker ps -a -q)
    docker container rm $(docker container ls -aq) -f
docker rmi [OPTIONS] IMAGE [IMAGE...]
    docker rmi ubuntu:14.04
    docker rmi 2cb0
    docker rmi $(docker images -q)
docker network rm $(docker network ls -q)
docker volume rm $(docker volume ls -qf dangling=true)
docker rmi $(docker images -qf dangling=true)

Show the history of how the image was built:

docker history --no-trunc ubuntu
IMAGE         CREATED BY                                      SIZE                COMMENT
16508e5c265d  /bin/sh -c #(nop)  CMD ["/bin/bash"]            0B                  update manifest
<missing>     /bin/sh -c mkdir -p /run/systemd && echo 'do…   7B                  create layer
<missing>     /bin/sh -c sed -i 's/^#\s*\(deb.*universe\)$…   2.76kB              create layer
<missing>     /bin/sh -c rm -rf /var/lib/apt/lists/*          0B                  update manifest
<missing>     /bin/sh -c set -xe  && echo '#!/bin/sh' > /…    745B                create layer
<missing>     /bin/sh -c #(nop) ADD file:3df374a69ce696c21…   84.1MB              create layer

Show a docker image config (manifest) file including layer data listed by content hash:

docker image inspect ubuntu

Get the IP of the 'web1' container (does not show anything on ubuntu):

docker inspect -f "{{ .NetworkSettings.Networks.nat.IPAddress }}" web1

Save one or more images to a tar archive (streamed to STDOUT by default):

docker save [OPTIONS] IMAGE [IMAGE...]
    docker save ubuntu -o ubuntu.tar

Copy files/folders between a container and the local filesystem:

    docker cp .\App\. mycontainer:/usr/share/app

Run a SQL Server container:

docker run -d -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=p$vd!' -p 1433:1433 --name sqldb microsoft/mssql-server-linux
docker logs sqldb     # check if everything went well
docker rm -fv sqldb   # remove the container forcefully together with all the data

# map the log folder
docker run -d -e 'ACCEPT_EULA=Y' -e 'SA_PASSWORD=p$vd!' -p 1433:1433 --name sqldb 
  -v $(pwd)/log:/var/opt/mssql/log microsoft/mssql-server-linux

Run a MySQL container:

docker run -d -e MYSQL_ROOT_PASSWORD=p$vd! -e MYSQL_DATABASE=mydb --name mysqldb -p 3306:3306 mysql

docker exec -it mysqldb bash
> mysql -u root -p

Volume mapping

There are two types of volumes in Docker:

  • Mapped in the host file system - bind-mount
  • Managed volumes - managed via 'docker volume' subcommand

Volumes are independent from containers and are used to store persitent data. When a container is removed, volumes stay.

Run a command and perform volume mapping:

docker run -it -v "C:\Temp:/console" microsoft/dotnet
docker run --rm -it -v "C:\Temp:/console" microsoft/dotnet:latest
docker run --rm --mount "type=bind,source=C:\Projects,target=/src" -t -i ubuntu:latest /bin/bash
docker run --rm --mount "type=bind,source=C:\Projects,target=/src" -t -i microsoft/dotnet:2.1-sdk /bin/bash

Run a command, create a volume 'myvolume' (if it does not exist), and mount to it:

docker container run -dit --name test --mount source=myvolume,target=/vol ubuntu
Put a file to the volume (just for test purposes):
> docker container exec -it test sh
/# ls -l /vol/
total 0
/# echo "hello" > /vol/myfile
/# cat /vol/myfile

Run a command in PowerShell with volume mapping:

docker run -it --rm -v "${pwd}/bin/Debug:/app" microsoft/dotnet

Map a static website:

docker run --rm -it -p 8080:80 -v C:\Projects\Website:/usr/share/nginx/html nginx

Manage volumes:

docker volume ls
docker volume create myvolume
docker volume inspect myvolume
docker volume rm myvolume
docker volume rm myvolume -f
docker volume ls -q
docker volume rm $(docker volume ls -q)
docker rm -fv <container>     # remove a container and associated *unnamed* volumes (named volumes remain untact)
docker volume ls -f dangling=true  # show volumes not associated with a container

Inspect volumes associated with a container:

docker inspect
"Mounts": [
        "Name": "0c942...",
        "Source": "/var/lib/docker/volumes/0c942...",
        "Destination": "/var/lib/mysql",
        "Driver": "local",
        "Mode": "",
        "RW": true,
        "Propagation": ""

On Linux, volumes are located at /var/lib/docker/volumes/VOLUME_NAME/_data

Interactive Terminal

When you run the following command, docker blocks the current process and waits:

> docker run -p 4000:4000 docs/
Docker docs are viewable at:

Pressing ^C does not stop the container:

> docker ps
CONTAINER ID   IMAGE                   COMMAND                  PORTS
c9e5a66cc0e7   docs/   "/bin/sh -c 'echo -e…"   80/tcp,>4000/tcp

The following command specifies the '-it' paramater which indicates an 'interactive terminal'. It allows you to send commands to the process that runs the application in the container. For example, ^C terminates the process which in effect stops the container:

> docker run -p 4000:4000 -it docs/
Docker docs are viewable at:
> ^C
> docker ps
CONTAINER ID   IMAGE                   COMMAND                  PORTS

Detach from the container but do not stop it:

> docker run -p 4000:4000 -it docs/
Docker docs are viewable at:
> ^PQ
> docker ps
CONTAINER ID   IMAGE                   COMMAND                  PORTS
b0548024da32   docs/   "/bin/sh -c 'echo -e…"   80/tcp,>4000/tcp

Automatically detach from the container i.e., run the container in background:

> docker run -p 4000:4000 -d docs/
> docker ps
CONTAINER ID   IMAGE                   COMMAND                  PORTS
1469be5b5dd5   docs/   "/bin/sh -c 'echo -e…"   80/tcp,>4000/tcp

Port Mapping

docker run -d --name container-name -p 80:8080 docker-image
  • -d - start a container in the detached mode i.e., do not latch it to the terminal
  • container-name - the unique container's name
  • docker-image - an image to use
  • 80:8080 - map port 80 on the Docker host to port 8080 inside the container
    • the container listens on the port 8080
    • we can access the container in a browser on the port 80 (http://localhost:80)


> docker run --rm -it -p 8080:80 nginx
> docker run -d --name web1 -p 8080:80 nginx
> docker port web1
80/tcp ->

Example: Windows container:

> docker run -p 81:80 -d microsoft/iis:nanoserver

the application inside the container runs on port 80
we can access the application from the host on port 81

Client / Server

Download an image:

docker pull mongo

Launch the server in the attached mode i.e., the current command window will be attached to a container. Name the container 'mdb':

docker run --name mdb mongo

From another docker window, launch the client in the interactive mode:

docker exec -it mdb mongo

Issue some commands in the client:

> show dbs
admin   0.000GB
config  0.000GB
local   0.000GB

Tar Utility

Example: Use a docker container to unpack a tar file (C:/Test/myfile.tar):

C:\Test> mkdir extract
C:\Test> docker run --rm -it -v C:/Test:/data alpine tar -xf /data/myfile.tar -C /data/extract

Example: Unpack a tar file and view an extracted json file:

C:\Test> docker run --rm -it -v C:/Test:/data alpine sh
/ # tar -tf /data/myfile.tar
/ # mkdir /data/extract
/ # tar -xf /data/myfile.tar -C /data/extract
/ # apk add --no-cache jq
/ # cd data/extract
/data/extract # cat manifest.json | jq

Version & Info

docker version
 Version:           18.06.1-ce
 API version:       1.38
 Go version:        go1.10.3
 Git commit:        e68fc7a
 Built:             Tue Aug 21 17:21:34 2018
 OS/Arch:           windows/amd64
 Experimental:      false
  Version:          18.06.1-ce
  API version:      1.38 (minimum version 1.12)
  Go version:       go1.10.3
  Git commit:       e68fc7a
  Built:            Tue Aug 21 17:29:02 2018
  OS/Arch:          linux/amd64
  Experimental:     false
docker info
Containers: 5
 Running: 2
 Paused: 0
 Stopped: 3
Images: 6
Server Version: 18.06.1-ce
Storage Driver: overlay2                   # pulls the image's layers
Kernel Version: 4.9.93-linuxkit-aufs
Operating System: Docker for Windows
OSType: linux
Architecture: x86_64

General Info

  • An image is an application packaging format. Image = Manifest + Loosely Coupled Layers
  • A stopped container is an equivalent of installed software.
  • A running container is an equivalent to running software.
  • A host or a container host is the machine that you run containers on.

The building blocks of containers are the Linux kernel primitives: namespaces and control groups. Namespaces are about isolation. Control groups are about grouping objects and setting limits.

Linux namespaces and what they give to each container:

  • Process ID (pid) - a process tree
  • Network (net) - a network stack
  • Filesystem/mount (mnt) - a root file system (C: on Windows, / on Linux)
  • Inter-proc communications (ipc) - lets processes in a single container access the same shared memory
  • UTS (uts) - a host name
  • User (user) - maps accounts inside the container to different users on the host

A container is an organized collection of namespaces.

Control Groups (cgroups) (aka Job Objects on Windows) control the consumption of system resources.

Tha image's Base Layer contains OS files and objects.


There are two types of logs:

  • Daemon logs (= docker engine logs)
    • Linux (systemd): journalctl -u docker.service
    • Linux (non-systemd): /var/log/messages
    • Windows: ~/AppData/Local/Docker -and/or- Event Viewer
  • Container logs (= app logs)
    • run your app as PID1
    • log in messages to stdout/stderr
    • -or- mount a volume and log in to a file
    • -or- logging driver plugins integrate containers with existing logging solutions such as syslog, gelf, splunk, fluentd, etc.
      • set the default logging driver in daemon.json
      • override the default logging driver with a per-container driver using –log-driver, –log-opts

Inspect logs with the docker logs command:

docker logs <container>

Registries & Repos

A default registry is

docker pull <registry>/<repo>:<image(tag)>
docker pull           == docker pull redis
docker pull           == docker pull nginx:1.13.5

Local registries:

  • Linux: /var/lib/docker/<storage-driver>
  • Windows: C:\ProgramData\Docker\WindowsFilter

A registry contains multiple repositories. The repos as well as the entire registries can be public or private.

Containerizing an App

Example: Create an image for a nodejs app:

Create Dockerfile for your app. Dockerfile contains the list of instructions on how to build an image with an app inside.

FROM alpine                             # Layer #1: a base image used as the base layer of your image
LABEL maintainer=""  # metadata: maintainer
RUN apk add --update nodejs nodejs-npm  # Layer #2: execute a command and create a new layer
                                        # we add app-specific files: node and npm (node package manager)
COPY . /src                             # Layer #3: copy files from the current directory into /src in the image
WORKDIR /src                            # metadata: change the working dir to /src
RUN npm install                         # Layer #4: install dependencies; in our example, npm runs against
                                        # whatever is listed in packages.json
EXPOSE 8080                             # metadata: a port the app is listening to
ENTRYPOINT ["node", "./app.js"]         # metadata: run the app; it's relative to the specified WORKDIR

From the location of your app's files and the Dockerfile, call 'docker image build'. The last dot specifies the current directory as the build context:

docker image build -t app_tag .

'docker image' sends the contents of the build context to the Docker Daemon. You could specify the build context explicitly if you were not in the location of your app and the Dockerfile. It means your build context may be a Git repo. In such a case, the Daemon pulls the context from GitHub.

# specify the build context explicitly
docker image build -t app_tag /home/code/myapp/
# specify a Git repo as the build context
docker image build -t app_tag

Example: Create an publish an image for a .NET Core console app:

1. Create FDD (framework-dependent deployment) of your app:

cd C:\Projects\ConsoleApp
dotnet publish -c Release

2. Create a Dockerfile in C:\Projects\ConsoleApp:

FROM microsoft/dotnet:2.0-runtime
COPY bin/Release/netcoreapp2.0/publish .
ENTRYPOINT ["dotnet","ConsoleApp.dll"]

3. Create the docker image 'consoleapp':

docker build -t consoleapp .

4. Run a container from the local image (just to test it):

docker run --rm consoleapp

5. Tag the image and publish it:

docker tag consoleapp ata6502/consoleapp
docker login
docker push ata6502/consoleapp

6. Run a container from the published image:

docker run --rm -it ata6502/consoleapp

You can also override the entry point and list the files in the image:

docker run --rm -it --entrypoint=bash ata6502/consoleapp
root@76f4811ead33:/app# ls

Example: Create a new image from container's changes using 'docker commit':

    docker commit mycontainer repo:tag1


  • Keep only what you need to build your image in the build context.
  • Specify the smallest image as your base layer image.
  • Use multi-stage builds to further reduce the size of your image.
  • Provide metadata to document your app.
  • CMD instruction: Run-time arguments override CMD commands
  • ENTRYPOINT instruction: Run-time arguments are appended to ENTRYPOINT


Use 'where docker' to find out the location of docker on Windows:

  • C:\Program Files\Docker\Docker\Resources\bin\docker.exe

There are also a few other tools in the same location:

  • docker-compose - defines and composes multi-container apps (orchestration)
  • docker-credential-wincred
  • docker-machine - provisions docker hosts/engines
  • kubectl
  • notary
  • Docker Swarm - schedules containers over multiple docker engines

Orchestration of containerized apps:

  • Kubernetes
  • Mesosphere DCOS (Datacenter Operating System)
  • CoreOS fleet
  • OpenStack Magnum

Show repos containing docs:

docker search docs

Show help for the search command:

docker help search

Download and run docker docs. The Docker Docs app listens on the port 4000:

docker run -p 4000:4000 docs/
Browser: http://localhost:4000


ls -al
ls | grep txt
ps -elf
uname -a
rm -rf bin/ obj/
exit      # exit the current process
cp * /var/lib/wbs/data    # copy all files from the current directory to the /var/lib/wbs/data directory
sudo journalctl -u <service_name> --since "1 min ago"


apt-get update
apt-get install vim
  • i - enter the interactive mode
  • Esc :wq
    • w - save changes
    • q - quit vim
  • Esc
    • o - insert a new line below
    • O - insert a new line above
    • dd - delete the line under the cursor
    • i - start the –INSERT– mode


  • <Left> h
  • <Right> l
  • <Up> k
  • <Down> j
notes/tools/docker.txt · Last modified: 2020/08/26 (external edit)