Docker Installation

To get the most recent stable docker version on a Debian, system, add the docker repository as explained in Docker community edition for Debian.

sudo apt-get update

sudo apt-get install \
   ca-certificates \
   curl \
   gnupg \
   lsb-release

Add Docker’s official GPG key:

curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

Use the following command to set up the stable repository. To add the nightly or test repository, add the word nightly or test (or both) after the word stable in the commands below. Learn about nightly and test channels.

 echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Display the updated source.list

cat /etc/apt/sources.list.d/docker.list

Then run :

sudo apt update
sudo apt install docker-ce

Install docker compose

sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

Update permissions

sudo chmod +x /usr/local/bin/docker-compose

Add your user to the docker group

To prevent docker from requesting permission each time you use it. Add your user to the docker group. As explained here

sudo usermod -aG docker $USER

Login to the new group (so that you don’t need to restart the shell)

newgrp docker

Login

Login to docker

docker login

My repository https://hub.docker.com/u/paulrougieux

Build

Instructions to create a container are stored in a Dockerfile. Docker hub is a collection of Dockerfiles. Containers stored on docker hub can be pulled and started directly from the docker run command. The section below explain how to write your own Docker file.

Docker file

docs.docker.com best practices for writing Dockerfiles

Build a container based on the Dockerfile in the present working directory

docker build -t friendlyhello .

Dockerfile from R packages:

I used R CMD build inside the docker file to build a package.

# Set the working directory to /R
WORKDIR /R

# Copy the current directory contents into the container at /R/packagename
ADD . /R/packagename

RUN R CMD build packagename

# R CMD build generates the file name from the description file
# Remember to update file name here below after a version update
RUN R -e 'install.packages("packagename_0.1.0.tar.gz")'

Compose file

docs.docker.com how services work

Compose several containers in a service Networking in compose from version 2, links are not required, for example with

db: image: postgres ports: - “8001:5432”

“Within the web container [in the same compose file], your connection string to db would look like postgres://db:5432, and from the host machine, the connection string would look like postgres://{DOCKER_IP}:8001.”

Restart policy

deploy:
  restart_policy:
    condition: on-failure

Volumes

docs.docker https://docs.docker.com/engine/admin/volumes/volumes/#create-and-manage-volumes List volumes:

docker volume ls

Inspect a volume:

docker volume inspect my-vol

Create a volume

docker volume create my-vol

Remove volumes:

docker volume rm <volume name>
docker volume rm $(docker volume ls -q) # all volumes

Start

Start containers

Start a container

sudo docker run hello-world

Restart a container

sudo docker restart hello-world

Stop a container

sudo docker stop [OPTIONS] CONTAINER [CONTAINER...]

Docker run options

  • -i, --interactive Keep STDIN open even if not attached
  • rm=true|false “Automatically remove the container when it exits (incompatible with -d). The default is false.”
  • -t, --tty Allocate a pseudo-TTY
  • -v, –volume=[] Bind mount a volume (e.g., from the host: -v /host:/container, from Docker: -v /container) The -v option can be used one or more times to add one or more mounts to a container. These mounts can then be used in other containers using the –volumes-from option.

Start services

You can start the service with:

sudo docker-compose up -d

Create a compose file then start the service with:

docker stack deploy -c docker-compose.yml servicename 

Stop the service with:

docker stack rm servicename 

swarm init error:

I specified the IP address Stackoverflow could not choose and IP address Error

Monitor

Start a bash shell

Start a bash shell inside a container, -it stands for interactive

docker ps # find the ID of the running container
docker exec -it <container-id> bash 

Start a script within a container, non interactively

docker exec <container-id> /path/to/test.sh

Stats and inspect running containers

run metrics

docker stats <container-id>

Find the IP of a container:

docker ps # look for the process id
docker inspect <container id>

The IP is at the end. it can also be extracted with a template:

 docker inspect -f '{{range .NetworkSettings.Networks}} IP {{.IPAddress}}{{end}}' <container id> 

Inspect options

Inspect the run restart policies Get the number of times a container was restarted:

docker inspect -f "{{ .RestartCount }}" my-container

Get the last time the container was (re)started;

docker inspect -f "{{ .State.StartedAt }}" my-container

Container logs

docker logs [OPTIONS] <container id>

Monitor stopped containers

See stopped containers

docker ps --filter "status=exited"

Inspect a stopped container

docker inspect <container-id>

Monitor running services

see which stacks are running

sudo docker stack ls
sudo docker stack services <stackname>

see which services are running

docker service ls

see which containers are running inside a service

docker service ps <service_name> 

You can also run docker ps to see all running processes.

Manage container images

Show available images on the system:

sudo docker images

Update a container image

How to upgrade docker container after its image changed Has information on the difference between volumes and bind mounts for data backup.

docker pull <image-name> 
docker stop <container-id> 
docker rm <image-name> 
docker run <image-name> [options]

If the container is part of a stack, you only need docker pull, then docker stack deploy.

Cleanup

A container should be stopped before it can be removed. Stop a container

docker ps
docker stop <container-id>

Remove a stopped container

docker rm <container-id>

Remove all stopped containers

docker container prune

Remove images

docker images # list available images
docker image rm  <image-id>

Programming with Docker

Docker for R

Docker hub R-base

Set the directory with -w and run an R script

docker exec -it -w /src/path_to_project backend Rscript  "script.R"

Or start a bash session in docker and use R from there

docker exec -it backend bash
cd /src/wood_prices/notebooks && Rscript render_notebooks.R
docker exec -it backend bash -c "cd /src/wood_prices/notebooks && Rscript render_notebooks.R"

Compile an R markdown notebook with docker

The r-rmd container was made specifically to compile R markdown notebooks.

Set the directory to the notebook location and render the notebook

docker exec -it -w /path/to/project container_name Rscript -e "rmarkdown::render('notebook_name.Rmd')"

Docker within docker

Docker blog Docker can now run within Docker.

Security

docs.docker.com Manage sensitive data with Docker secrets * Example use secrets with a Wordpress service * Use secrets in compose * Declare the location of secrets :

 secrets:
   db_password:
     file: db_password.txt
   db_root_password:
     file: db_root_password.txt
  • give access to secrets to a service :

    db: image: mysql:latest volumes: - db_data:/var/lib/mysql environment: MYSQL_ROOT_PASSWORD_FILE: /run/secrets/db_root_password MYSQL_DATABASE: wordpress MYSQL_USER: wordpress MYSQL_PASSWORD_FILE: /run/secrets/db_password secrets: - db_root_password - db_password

Stackoverflow Docker and securing passwords previous solution recommended passing passwords as environement variables. Docker now has a native solution to deal with secrets.