Friday, 8 March 2019

Introduction to Docker

Docker is a platform which allows some application and all its dependencies to be packed in a container, shipped within this monolithic bundle and then deployed on any other machine with no fear that some dependency would be missing or not compatible with the new host.

Here are some terms:

host
  •  may be local or remote

container
  • process which runs on a host

Docker runs processes in isolated containers.

Lifecycle of Docker Container

Image Source and Credits: http://docker-saigon.github.io/post/Docker-Internals/

image

Docker images can consist of multiple layers. Layers can be reused by images. If a layer is downloaded as part of imageA and it is also part of imageB then when we pull/download imageB, this layer will not be downloaded again but will be reused.
  • image ID is a SHA256 digest covering the image’s configuration and layers. 



Dockerfile


What is the difference between CMD and ENTRYPOINT in a Dockerfile?

The ENTRYPOINT specifies a command that will always be executed when the container starts.
The CMD specifies arguments that will be fed to the ENTRYPOINT.

Multi-stage build


This is one of the use cases which shows benefits of multi-staged build:
Docker container running golang http.Client getting error `certificate signed by unknown authority`

---
If we already have app binary built and can simply copy it onto an image but still have to add certificates, Dockerfile can look like:

FROM golang:alpine as build
RUN apk --no-cache add ca-certificates

FROM scratch
COPY --from=build /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
COPY ./bin/my_app /my_app
CMD ["/my_app"]
---

FROM scratch

If we use FROM scratch then we can't use/execute bash/sh terminal if we attach to the container from the outside. The lightest image which provides bash terminal is alpine:

FROM alpine

alpine contains /bin/sh so we can use it via

$ docker exec -it <container_name> sh
---

Linter



Example:

$ docker run --rm -i hadolint/hadolint < Dockerfile
Unable to find image 'hadolint/hadolint:latest' locally
latest: Pulling from hadolint/hadolint
447f1c00f9d8: Pull complete 
Digest: sha256:6e67b08b2f9b3cf57616cfc92adb8864b74b02f079d70eabc944b29f05aff5f9
Status: Downloaded newer image for hadolint/hadolint:latest
/dev/stdin:27 DL3025 Use arguments JSON notation for CMD and ENTRYPOINT arguments


Docker CLI Commands


Builds an image from a Dockerfile.

$ docker build --help
Usage: docker build [OPTIONS] PATH | URL | -
Build an image from a Dockerfile

Options:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--cgroup-parent string Optional parent cgroup for the container
--compress Compress the build context using gzip
--cpu-period int Limit the CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight)
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--force-rm Always remove intermediate containers
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
-m, --memory bytes Memory limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--network string Set the networking mode for the RUN instructions during build (default "default")
--no-cache Do not use cache when building the image
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
--security-opt strings Security options
--shm-size bytes Size of /dev/shm
-t, --tag list Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
--ulimit ulimit Ulimit options (default [])



The PATH specifies where to find the files for the “context” of the build on the Docker daemon.

Example of how to build and run a Docker image:

$ docker build -t jsonschema2db . && docker run jsonschema2db

docker exec


To execute a command inside a running container, use docker exec. For example, we can run a bash terminal as:

$ docker exec -it my-postgres bash
root@a4a7486fea59:/# 

-i // keeps stdin opened
-t // allocates pseudo TTY

In this terminal we can run usual Linux commands as we were inside the container:

root@a4a7486fea59:/# ls
bin  boot  dev docker-entrypoint-initdb.d  docker-entrypoint.sh  etc  home  lib  lib64  media mnt  opt  proc root  run  sbin  srv  sys  tmp usr  var
root@a4a7486fea59:/# pwd
/

not able to use docker exec shell 
Try the alpine tag of image:

$ docker run --name gorush -d appleboy/gorush:alpine
$ docker exec -ti gorush /bin/sh

docker image


To list all images:

$ docker image ls

To remove some image:

$ docker image rm image_id


docker logs

$ docker logs --help

Usage: docker logs [OPTIONS] CONTAINER

Fetch the logs of a container

Options:
      --details        Show extra details provided to logs
  -f, --follow         Follow log output
      --since string   Show logs since timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)
      --tail string    Number of lines to show from the end of the logs (default "all")
  -t, --timestamps     Show timestamps
      --until string   Show logs before a timestamp (e.g. 2013-01-02T13:23:37) or relative (e.g. 42m for 42 minutes)

Example:

$ docker logs my_app >& my_app.log

---

docker network



$ docker network --help

Usage: docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.


List all networks:


$ docker network ls
NETWORK ID          NAME                             DRIVER              SCOPE
110d23a9b23f        bridge                           bridge              local
b32aba0ecc85        my_app1       bridge              local
5a91d6b95b25        my_app2   bridge              local
7422e6165f7a        my_app3                     bridge              local
b2977102daa4        my_app4_test-network                bridge              local
e829cad5a344        host                             host                local
6b0d605ed4a5        none                             null                local


Connect a container to the network (of some other container):


$ docker network connect --help

Usage: docker network connect [OPTIONS] NETWORK CONTAINER

Connect a container to a network

Options:
      --alias strings           Add network-scoped alias for the container
      --ip string               IPv4 address (e.g., 172.30.100.104)
      --ip6 string              IPv6 address (e.g., 2001:db8::33)
      --link list               Add link to another container
      --link-local-ip strings   Add a link-local address for the container


Use case example:

Running Postgres DB in one container (based on postgres image; container runs in its own network) and connecting to it via pgAdmin which runs in another container (based on dpage/pgadmin4 image).

docker container ls shows that my_app_db_1 is up and running with port mapping as 0.0.0.0:5432->5432/tcp. This container runs Postgres DB.

To find the name of the network this container is connected to use docker inspect <container_name> and in the output json look for "NetworkSettings" > "Networks". There should be a network name like "my_app_default".

Let's inspect that network:

$ docker network inspect my_app_default
[
    {
        "Name": "my_app_default",
        "Id": "5a91d6b95b25fdd6d24e921e1ccdb69f24ae4b1c509188ccfc087acd330375ca",
        "Created": "2019-06-05T10:19:11.576495786+01:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.19.0.0/16",
                    "Gateway": "172.19.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": true,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "9ae5dfe822348906d2bdf2b55314a323f7ba03360eb2edf8e5d7d42afca40e34": {
                "Name": "my_app_service",
                "EndpointID": "a5230696caabc7d230df8f589066b8028c3b03493a2f05ed0dc5e224944952fc",
                "MacAddress": "02:42:ac:13:00:03",
                "IPv4Address": "172.19.0.3/16",
                "IPv6Address": ""
            },
            "e52e5d6de6b6a062d2cbfaf921f3365f20db0208511a906cab6143528a14ee6d": {
                "Name": "my_app_db_1",
                "EndpointID": "bbe87692635abe7cd45a3980d0982ca1dbc6c9a5718a267935659cfb036b2da1",
                "MacAddress": "02:42:ac:13:00:02",
                "IPv4Address": "172.19.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {
            "com.docker.compose.network": "default",
            "com.docker.compose.project": "my_app",
            "com.docker.compose.version": "1.23.2"
        }
    }
]

my_app_db_1 is the name of the container which is running db service (Postgres) as I specified in docker-compose.yml.

Now, I want to run pgAdmin DB client (which is also a web server...) from its own container, based on dpage/pgadmin4 image:

$ docker run -p 5051:5051 -d -e "PGADMIN_DEFAULT_EMAIL=bojan.komazec@example.com" -e "PGADMIN_DEFAULT_PASSWORD=postgres" -e "PGADMIN_LISTEN_PORT=5051" --name pgadmin dpage/pgadmin4
baf9343368f9cb20a0dd9ab1a4763eaf08df03f2ee667f979b4e3466bc20d7b1

We can use docker container ls to verify that this container is now up and running, with port mappings as 80/tcp, 443/tcp, 0.0.0.0:5051->5051/tcp. We can now open in browser on the local host the address http://localhost:5051/ which should open pgAdmin login page. If we try to add DB server with IP address 172.19.0.2 (as listed in the postgres container network spec above), connecting to it will fail as pgAdmin runs in its own network. We need to connect pgadmin container to my_app_default network:

$ docker network connect my_app_default pgadmin

We can now use 172.19.0.2 address to connect to DB from pgAdmin web app.

If we again inspect my_app_default network we can verify that there is one more container attached to it: pgadmin.

To avoid issuing two commands, we can specify network container shall connect to in docker run command:

$ docker run -p 5051:5051 -d -e "PGADMIN_DEFAULT_EMAIL=bojan.komazec@example.com" -e "PGADMIN_DEFAULT_PASSWORD=postgres" -e "PGADMIN_LISTEN_PORT=5051" --network=my_app_default --name pgadmin dpage/pgadmin4

---

docker ps


To list all running containers use docker ps:

$ docker ps
CONTAINER ID  IMAGE   COMMAND         CREATED     STATUS      PORTS                      NAMES
b9f263f2b517 postgres "some.command…" 9 hours ago Up 5 hours  0.0.0.0:5432->5432/tcp  my_project_postgres_1

If no containers are running:

$ sudo docker ps
CONTAINER ID    IMAGE           COMMAND         CREATED         STATUS          PORTS               NAMES


To list all containers, use docker ps -a.


docker pull


docker pull pulls an image from the repository.

Use:

$ docker pull <image_name>:<tag_name>

If no tag is provided, Docker Engine uses the :latest tag as a default.

Apart from pulling some image for the first time, this command is used to pull a new version of the existing image. [Update a docker container to the latest version]

In my case, I have been running pgAdmin4 from within a container but after some time I started getting a popup on pgAdmin4 main web page that I am using the old version of it. My course of actions was:

$ docker images | grep pgadmin
dpage/pgadmin4                  latest               c32b95c07a00        5 weeks ago         237MB

$ docker pull dpage/pgadmin4
Using default tag: latest
latest: Pulling from dpage/pgadmin4
e7c96db7181b: Already exists 
...
44bc3cf004be: Already exists 
aa774cf9fd8b: Pull complete 
...
660e231737f7: Pull complete 
Digest: sha256:2c46b3e631f33434246a2a51134e3a43951b00c5639f7fc158b4b973879f9ea3
Status: Downloaded newer image for dpage/pgadmin4:latest

---
How to upgrade docker container after its image changed
---

docker run


docker run = docker create + docker start

A container is an instance of an image and pull only downloads the image, it doesn't create a container.

docker run creates a container from the image you choose.

If you run

$ docker run myImage

...N times, docker ps -a will show N containers based on that image.

Why “Docker run” creates new container every time?

Containers do not modify images. Any changes made to a container you've started via docker run won't affect another container run from the same image

Container process that runs is isolated in that it has its own:
  • file system
  • networking
  • isolated process tree separate from the host

$ docker run --help

Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container


Options:

      --add-host list                  Add a custom host-to-IP mapping (host:ip)
  -a, --attach list                    Attach to STDIN, STDOUT or STDERR
      --blkio-weight uint16            Block IO (relative weight), between 10 and 1000, or 0 to disable (default 0)
      --blkio-weight-device list       Block IO weight (relative device weight) (default [])
      --cap-add list                   Add Linux capabilities
      --cap-drop list                  Drop Linux capabilities
      --cgroup-parent string           Optional parent cgroup for the container
      --cidfile string                 Write the container ID to the file
      --cpu-count int                  CPU count (Windows only)
      --cpu-percent int                CPU percent (Windows only)
      --cpu-period int                 Limit CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int                  Limit CPU CFS (Completely Fair Scheduler) quota
      --cpu-rt-period int              Limit CPU real-time period in microseconds
      --cpu-rt-runtime int             Limit CPU real-time runtime in microseconds
  -c, --cpu-shares int                 CPU shares (relative weight)
      --cpus decimal                   Number of CPUs
      --cpuset-cpus string             CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string             MEMs in which to allow execution (0-3, 0,1)
  
-d, --detach                         
Run container in background and print container ID

      --detach-keys string             Override the key sequence for detaching a container
      --device list                    Add a host device to the container
      --device-cgroup-rule list        Add a rule to the cgroup allowed devices list
      --device-read-bps list           Limit read rate (bytes per second) from a device (default [])
      --device-read-iops list          Limit read rate (IO per second) from a device (default [])
      --device-write-bps list          Limit write rate (bytes per second) to a device (default [])
      --device-write-iops list         Limit write rate (IO per second) to a device (default [])
      --disable-content-trust          Skip image verification (default true)
      --dns list                       Set custom DNS servers
      --dns-option list                Set DNS options
      --dns-search list                Set custom DNS search domains
      --entrypoint string              Overwrite the default ENTRYPOINT of the image

  -e, --env list                       Set environment variables

      --env-file list                  Read in a file of environment variables
      --expose list                    Expose a port or a range of ports
      --group-add list                 Add additional groups to join
      --health-cmd string              Command to run to check health
      --health-interval duration       Time between running the check (ms|s|m|h) (default 0s)
      --health-retries int             Consecutive failures needed to report unhealthy
      --health-start-period duration   Start period for the container to initialize before starting health-retries countdown (ms|s|m|h) (default 0s)
      --health-timeout duration        Maximum time to allow one check to run (ms|s|m|h) (default 0s)
      --help                           Print usage
  -h, --hostname string                Container host name
      --init                           Run an init inside the container that forwards signals and reaps processes

-i, --interactive                    
Keep STDIN open even if not attached

      --io-maxbandwidth bytes          Maximum IO bandwidth limit for the system drive (Windows only)
      --io-maxiops uint                Maximum IOps limit for the system drive (Windows only)
      --ip string                      IPv4 address (e.g., 172.30.100.104)
      --ip6 string                     IPv6 address (e.g., 2001:db8::33)
      --ipc string                     IPC mode to use
      --isolation string               Container isolation technology
      --kernel-memory bytes            Kernel memory limit
  -l, --label list                     Set meta data on a container
      --label-file list                Read in a line delimited file of labels
      --link list                      Add link to another container
      --link-local-ip list             Container IPv4/IPv6 link-local addresses
      --log-driver string              Logging driver for the container
      --log-opt list                   Log driver options
      --mac-address string             Container MAC address (e.g., 92:d0:c6:0a:29:33)
  -m, --memory bytes                   Memory limit
      --memory-reservation bytes       Memory soft limit
      --memory-swap bytes              Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --memory-swappiness int          Tune container memory swappiness (0 to 100) (default -1)
      
--mount mount                    Attach a filesystem mount to the container

--name string                    Assign a name to the container
      
--network string                 Connect a container to a network (default "default")

      --network-alias list             Add network-scoped alias for the container
      --no-healthcheck                 Disable any container-specified HEALTHCHECK
      --oom-kill-disable               Disable OOM Killer
      --oom-score-adj int              Tune host's OOM preferences (-1000 to 1000)
      --pid string                     PID namespace to use
      --pids-limit int                 Tune container pids limit (set -1 for unlimited)
      --platform string                Set platform if server is multi-platform capable
      --privileged                     Give extended privileges to this container

-p, --publish list                   Publish a container's port(s) to the host

  -P, --publish-all                    Publish all exposed ports to random ports
      --read-only                      Mount the container's root filesystem as read only
      --restart string                 Restart policy to apply when a container exits (default "no")

--rm                             
Automatically remove the container when it exits; this means it will not be listed in "docker ps -a" output after it terminates.

      --runtime string                 Runtime to use for this container
      --security-opt list              Security Options
      --shm-size bytes                 Size of /dev/shm
      --sig-proxy                      Proxy received signals to the process (default true)
      --stop-signal string             Signal to stop a container (default "SIGTERM")
      --stop-timeout int               Timeout (in seconds) to stop a container
      --storage-opt list               Storage driver options for the container
      --sysctl map                     Sysctl options (default map[])
      --tmpfs list                     Mount a tmpfs directory

-t, --tty                            
Allocate a pseudo-TTY
(If you wander WTF is TTY read this)

      --ulimit ulimit                  Ulimit options (default [])

  -u, --user string                    Username or UID (format: <name|uid>[:<group|gid>])
      --userns string                  User namespace to use
      --uts string                     UTS namespace to use
  -v, --volume list                    Bind mount a volume
      --volume-driver string           Optional volume driver for the container
      --volumes-from list              Mount volumes from the specified container(s)
  -w, --workdir string                 Working directory inside the container


For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process. -i -t is often written -it. [source]

Confused about Docker -t option to Allocate a pseudo-TTY

Example: 

This example shows how it's easy to fetch, spin and use a specific version of Golang (v1.11) with Docker:

$ docker run --rm -it golang:1.11
Unable to find image 'golang:1.11' locally
1.11: Pulling from library/golang
e79bb959ec00: Already exists 
d4b7902036fe: Already exists 
1b2a72d4e030: Already exists 
d54db43011fd: Already exists 
963c818ebafc: Already exists 
66831bab8cde: Pull complete 
0ac2e04178ce: Pull complete 
Digest: sha256:c096aaab963e25f78d226e841ad258ab3cba8c6a4c345c24166a5755686734f1
Status: Downloaded newer image for golang:1.11
root@bee14b1ffe61:/go# go version
go version go1.11.6 linux/amd64
root@bee14b1ffe61:/go# exit
exit

Example:

docker run -p 443:443 \
        -v "/private/var/lib/pgadmin:/var/lib/pgadmin" \
        -v "/path/to/certificate.cert:/certs/server.cert" \
        -v "/path/to/certificate.key:/certs/server.key" \
        -v "/tmp/servers.json:/servers.json" \
        -e "PGADMIN_DEFAULT_EMAIL=user@domain.com" \
        -e "PGADMIN_DEFAULT_PASSWORD=SuperSecret" \
        -e "PGADMIN_ENABLE_TLS=True" \
        -d dpage/pgadmin4


Pulling the image from Docker Hub


docker run checks if image exists locally and if not it performs docker pull and downloads it from Docker Hub. [1]

Container identification


Container can be identified by:

  • UUID
    • assigned by the daemon
    • can be:
      • long
      • short
  • name
    • set by the developer via --name argument

Container Modes (-d) 


Docker can run processes (containers) in one of these two modes:

  • foreground
    • default mode
    • console is attached to process' stdin, stdout, stderr
  • background (detached)
    • -d has to be passed to docker run
    • container exits when 
      • the root process used to run container exits OR
      • when daemon exits (if this happens first)

Exposing Ports


If some process in the container is listening on some port and we want to allow connections from outside the container, we can open (expose) these incoming ports via -p option which publishes single port or range of ports to the host. Port number that service listens inside the container does not need to be the same as the port exposed to the host (where external clients connect). These mappings are specified like in these examples:

-p <host_port(s)>:<container_port(s)>/protocol

-p 1234:1234 // single port, all protocols
-p 1234:1234/tcp // allow only TCP protocol
-p 1234-1240:1234-1240 // range
-p 1234-1240:1234-1240/tcp // range, TCP protocol only
-p 127.0.0.1:80:8080/tcp // tcp port 8080 is mapped onto host's port 80

Environment variables


Use -e option followed by NAME=VALUE like in this example:

-e POSTGRES_PASSWORD=mysecretpassword


Using volumes

Use volumes

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers.

New users should try --mount syntax which is simpler than --volume syntax.

--mount 'type=volume,src=<VOLUME-NAME>,dst=<CONTAINER-PATH>,volume-driver=local,volume-opt=type=nfs...'


type - type of the mount, which can be bind, volume, or tmpfs
src - For named volumes, this is the name of the volume. May be specified as source or src. It can be either absolute or relative path.
dst - destination takes as its value the path where the file or directory is mounted in the container; May be specified as destination, dst, or target. It has to be absolute path otherwise an error similar to this is issued:

$ docker run --rm -it --mount type=volume,src=./data-vol-src,target=./data-vol-target --name go-demo go-demo
docker: Error response from daemon: invalid mount config for type "volume": invalid mount path: './data-vol-target' mount path must be absolute.
See 'docker run --help'.


Example:

$ docker run  --mount type=volume,source=myvol,target=/app ...


Docker Tip #33: Should You Use the Volume or Mount Flag?

BK: I could not make docker run --mount working when having both type=volume and source=`pwd`/myvol (or $(pwd)/myvol, ${pwd}/myvol, "$(pwd)/myvol", "$(pwd)"/myvol...etc...).

Example:

$ docker run --rm -it --mount type=volume,src="$(pwd)/data-vol",target=/go/src/github.com/BojanKomazec/go-demo/data-vol --name go-demo go-demo
docker: Error response from daemon: create /home/bojan/dev/go/src/github.com/BojanKomazec/go-demo/data-vol: "/home/bojan/dev/go/src/github.com/BojanKomazec/go-demo/data-vol" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path.
See 'docker run --help'.

This is very likely a consequence of Docker's way of handling volumes: When -v (or -- mount type=volume) is specified Docker will create a new volume in the docker host's /var/lib/docker/volumes/new_volume_name/_data and mount to the container. We can't use an arbitrary absolute path for the volume (the one that includes $(pwd)) if volume has to be in a directory predefined by Docker.

Nevertheless, if we switch to binding local host's arbitrary directory to some container's one then $(pwd) works well.

Example:

$ docker run --rm -it --mount type=bind,src="$(pwd)/data-vol",target=/go/src/github.com/BojanKomazec/go-demo/data-vol --name go-demo go-demo

Our application can pick up target directory via environment variable: we need to add e.g. OUTPUT_DIR=./data-vol to .env file or to docker run -e argument.


Troubleshooting


If you use docker run and then see that container is not running (e.g. the output of docker container ls shows its status as Exited(1)) check the log of the container:

$ docker inspect <container_name>

In the output json look for LogPath attribute:

"LogPath":"/var/lib/docker/containers/62fdb19e88ded813969915891f6a2dec6a83cb3a28c1054fbdd1e001f033ccf6/62fdb19e88ded813969915891f6a2dec6a83cb3a28c1054fbdd1e001f033ccf6-json.log"

Then see the content of the log file:

$ sudo cat /var/lib/docker/containers/62fdb19e88ded813969915891f6a2dec6a83cb3a28c1054fbdd1e001f033ccf6/62fdb19e88ded813969915891f6a2dec6a83cb3a28c1054fbdd1e001f033ccf6-json.log

{"log":"You need to specify PGADMIN_DEFAULT_EMAIL and PGADMIN_DEFAULT_PASSWORD environment variables\n","stream":"stdout","time":"2019-06-05T10:14:22.078604896Z"}


docker start


To start a container use docker start. In the following example container name is my-postgres:

$ docker start my-postgres
my-postgres

docker stop


To stop running one or more containers use docker stop:

$ docker stop my_service_postgres_1
my_service_postgres_1


docker container

$ docker container 

Usage:  docker container COMMAND

Manage containers

Commands:
  attach      Attach local standard input, output, and error streams to a running container
  commit      Create a new image from a container's changes
  cp          Copy files/folders between a container and the local filesystem
  create      Create a new container
  diff        Inspect changes to files or directories on a container's filesystem
  exec        Run a command in a running container
  export      Export a container's filesystem as a tar archive
  inspect     Display detailed information on one or more containers
  kill        Kill one or more running containers
  logs        Fetch the logs of a container
  ls          List containers
  pause       Pause all processes within one or more containers
  port        List port mappings or a specific mapping for the container
  prune       Remove all stopped containers
  rename      Rename a container
  restart     Restart one or more containers
  rm          Remove one or more containers
  run         Run a command in a new container
  start       Start one or more stopped containers
  stats       Display a live stream of container(s) resource usage statistics
  stop        Stop one or more running containers
  top         Display the running processes of a container
  unpause     Unpause all processes within one or more containers
  update      Update configuration of one or more containers
  wait        Block until one or more containers stop, then print their exit codes

Run 'docker container COMMAND --help' for more information on a command.

---

If we try to start some container which requires opening some port on the localhost while another running container has already opened it, we might get the following error:

$ docker-compose up --build

Starting my_app_1 ... 

ERROR: for my-app_db_1  Cannot start service db: driver failed programming external connectivity on endpoint my-app_db_1 (a456b10867b734493c831aa99f227147110f61233652c4984415c12ecdf9a9b3): Bind for 0.0.0.0:5432 failed: port is Starting my-app_my-service_1 ... done

ERROR: for db  Cannot start service db: driver failed programming external connectivity on endpoint my-app_db_1 (a456b10867b734493c831aa99f227147110f61233652c4984415c12ecdf9a9b3): Bind for 0.0.0.0:5432 failed: port is already allocated
ERROR: Encountered errors while bringing up the project.

To resolve this, we first need to check which containers are running and then to stop them:

$ docker container ls 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
499c43a9c28b        postgres:latest     "docker-entrypoint.s…"   3 days ago          Up 3 days           0.0.0.0:5432->5432/tcp   my-app-2_db_1

$ docker container stop my-app-2_db_1
my-app-2_db_1

Let's verify that no containers are running:

$ docker container ls
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

---

docker container ls 


$ docker container ls --help

Usage:  docker container ls [OPTIONS]

List containers

Aliases:
  ls, ps, list

Options:
  -a, --all             Show all containers (default shows just running)
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print containers using a Go template
  -n, --last int        Show n last created containers (includes all states) (default -1)
  -l, --latest          Show the latest created container (includes all states)
      --no-trunc        Don't truncate output
  -q, --quiet           Only display numeric IDs
  -s, --size            Display total file sizes



To list all containers:

$ docker container ls -a

To list only numeric IDs of all containers:

$ docker container ls -a -q

or

$ docker container ls -aq

---

docker container rm


$ docker container rm --help

Usage:  docker container rm [OPTIONS] CONTAINER [CONTAINER...]

Remove one or more containers

Options:
  -f, --force     Force the removal of a running container (uses SIGKILL)
  -l, --link      Remove the specified link
  -v, --volumes   Remove the volumes associated with the container


To remove all containers:

$ docker container rm $(docker container ls -aq)


---

docker image

$ docker image --help

Usage:  docker image COMMAND

Manage images

Commands:
  build       Build an image from a Dockerfile
  history     Show the history of an image
  import      Import the contents from a tarball to create a filesystem image
  inspect     Display detailed information on one or more images
  load        Load an image from a tar archive or STDIN
  ls          List images
  prune       Remove unused images
  pull        Pull an image or a repository from a registry
  push        Push an image or a repository to a registry
  rm          Remove one or more images
  save        Save one or more images to a tar archive (streamed to STDOUT by default)
  tag         Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

Run 'docker image COMMAND --help' for more information on a command.

---

docker image ls


$ docker image ls --help

Usage:  docker image ls [OPTIONS] [REPOSITORY[:TAG]]

List images

Aliases:
  ls, images, list

Options:
  -a, --all             Show all images (default hides intermediate images)
      --digests         Show digests
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print images using a Go template
      --no-trunc        Don't truncate output
  -q, --quiet           Only show numeric IDs


To list IDs of all images:

$ docker image ls -aq


docker image rm 


$ docker image rm --help

Usage:  docker image rm [OPTIONS] IMAGE [IMAGE...]

Remove one or more images

Aliases:
  rm, rmi, remove

Options:
  -f, --force      Force removal of the image
      --no-prune   Do not delete untagged parents


To delete all images:

$ docker image rm $(docker image ls -aq)


---

docker images


To see which images are present locally, use docker images:

$ docker images --help

Usage: docker images [OPTIONS] [REPOSITORY[:TAG]]

List images

Options:
  -a, --all             Show all images (default hides intermediate images)
      --digests         Show digests
  -f, --filter filter   Filter output based on conditions provided
      --format string   Pretty-print images using a Go template
      --no-trunc        Don't truncate output
  -q, --quiet           Only show numeric IDs


Example:

$ docker images
REPOSITORY           TAG                  IMAGE ID            CREATED             SIZE
my_app                      latest               477db2641216        12 minutes ago      193MB
<none>                    <none>               7f82c84cc05a        12 minutes ago      193MB




docker volume 


$ docker volume

Usage:  docker volume COMMAND

Manage volumes

Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  prune       Remove all unused local volumes
  rm          Remove one or more volumes

Run 'docker volume COMMAND --help' for more information on a command.


---

docker volume ls 


$ docker volume ls --help

Usage:  docker volume ls [OPTIONS]

List volumes

Aliases:
  ls, list

Options:
  -f, --filter filter   Provide filter values (e.g. 'dangling=true')
      --format string   Pretty-print volumes using a Go template
  -q, --quiet           Only display volume names

---


$ docker volume ls
DRIVER              VOLUME NAME
local               1a2a9d0f43ce94ad1e176f9bb318f46829fcd34354d4d648d70434efa0f43f60
local               1a66b905bcd4be936b8df26cacf018d7f863e758773a11be5faf9d9949311eb0
local               1c6af16b8d8b1041ad3a46e3910bde9121b64cfae65f8299cedd81793d8fce37
...


$ docker volume ls -q
1a2a9d0f43ce94ad1e176f9bb318f46829fcd34354d4d648d70434efa0f43f60
1a66b905bcd4be936b8df26cacf018d7f863e758773a11be5faf9d9949311eb0
1c6af16b8d8b1041ad3a46e3910bde9121b64cfae65f8299cedd81793d8fce37

---

docker volume rm


$ docker volume rm --help

Usage:  docker volume rm [OPTIONS] VOLUME [VOLUME...]

Remove one or more volumes

Aliases:
  rm, remove

Examples:

$ docker volume rm hello
hello


Options:
  -f, --force   Force the removal of one or more volumes
---

To remover all volumes:

$ docker volume rm $(docker volume ls -q)



TBC...

References


Lifecycle of Docker Container
Hey Docker! Why do you hate Windows so much?

No comments: