User Tools

Site Tools


notes:tools:docker

Docker

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 [OPTIONS] CONTAINER COMMAND [ARG...]
    docker exec -it mycontainer bash
    docker exec -it mycontainer mongo
    docker exec -it mycontainer powershell

Start a container:

docker start [OPTIONS] CONTAINER [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 [OPTIONS] CONTAINER [CONTAINER...]
    docker stop ubuntu
    docker stop $(docker ps -aq)
    docker stop $(docker ps -a -q)

Remove containers, images, and other stuff:

docker rm [OPTIONS] CONTAINER [CONTAINER...]
    docker rm ubuntu:latest
    docker rm $(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 volume rm $(docker volume ls -qf dangling=true)
docker network rm $(docker network ls -q)

Show running containers (process status):

docker ps
docker ps -a
docker ps -a --no-trunc

Show downloaded images:

docker images
docker image ls
docker image ls --digests

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 [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH
    docker cp .\App\. mycontainer:/usr/share/app

Volume mapping

Volumes are independent from containers 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
hello

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

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.github.io
Docker docs are viewable at:
http://0.0.0.0:4000

Pressing ^C does not stop the container:

> docker ps
CONTAINER ID   IMAGE                   COMMAND                  PORTS
c9e5a66cc0e7   docs/docker.github.io   "/bin/sh -c 'echo -e…"   80/tcp, 0.0.0.0:4000->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.github.io
Docker docs are viewable at:
http://0.0.0.0:4000
> ^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.github.io
Docker docs are viewable at:
http://0.0.0.0:4000
> ^PQ
> docker ps
CONTAINER ID   IMAGE                   COMMAND                  PORTS
b0548024da32   docs/docker.github.io   "/bin/sh -c 'echo -e…"   80/tcp, 0.0.0.0:4000->4000/tcp

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

> docker run -p 4000:4000 -d docs/docker.github.io
1469be5b5dd5480572d184ae3510ad779184acb3e620d905a1ef43a06733399c
> docker ps
CONTAINER ID   IMAGE                   COMMAND                  PORTS
1469be5b5dd5   docs/docker.github.io   "/bin/sh -c 'echo -e…"   80/tcp, 0.0.0.0:4000->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)

Example:

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

Example: Windows container:

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

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
 
Client:
 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
 
Server:
 Engine:
  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.

Logging

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

docker pull <registry>/<repo>:<image(tag)>
docker pull docker.io/redis:latest           == docker pull redis
docker pull docker.io/nginx:1.13.5           == 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="email@something.com"  # 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 https://github.com/wbs/wbs.git

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
 
WORKDIR /app
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 [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
    docker commit mycontainer repo:tag1

Remember:

  • 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

Tools

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/docker.github.io:latest
Browser: http://localhost:4000

Linux

ls
ls -al
ls | grep txt
ps -elf
top
uname -a
rm -rf bin/ obj/
exit      # exit the current process

vim

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
    • i - start the –INSERT– mode
notes/tools/docker.txt · Last modified: 2018/10/17 by leszek