Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
Tips and Tricks
from Docker Captain
Łukasz Lach
v2018.10-TSR/11+5/ v2019.03+3/ v2019.05+2
Łukasz Lach
Docker Captain
Docker Certified Associate
Docker Community Leader - Warsaw, Poland
Speaker at DockerCon 2018 and 2019
Lecturer at the University of Warsaw
llach@llach.pl
Install Docker on Linux
$ curl -fsSL get.docker.com 
| VERSION=18.03 CHANNEL=edge sh
Easiest way to install Docker on Linux allowing to choose
the CHANNEL (edge, test or experimental)
and VERSION as well.
Install Docker rootless
$ curl -fsSL get.docker.com/rootless | sh
Rootless Docker refers to running the Docker daemon
(and containers) as a non-root user.
Local Docker Hub mirror
version: '3.7'
services:
registry:
image: registry:2
ports:
- 5000:5000
environment:
REGISTRY_STORAGE_DELETE_ENABLED: 'true'
REGISTRY_PROXY_REMOTEURL: 'https://registry-1.docker.io'
Setup local, caching and revalidating Docker Hub mirror.
No build context
$ docker build -t my-image .
Sending build context to Docker daemon 589.14kB
$ docker build -t my-image - < Dockerfile
Sending build context to Docker daemon 4.096kB
When no build context is needed there is no point of
waiting for it to be compressed and passed along.
ADD a remote file
ADD http://example.com/ /index.html
ADD http://example.com/archive.tar.xz /archive
ADD on a remote file does not utilize the build cache.
RUN curl -fsSL http://example.com/ -o /index.html
RUN curl -fsSL http://example.com/archive.tar.xz | 
tar -xJC /archive
no cache for these and subsequent commands
uses cache
Build FROM scratch
$ go build -v 
-a 
-installsuffix cgo 
-o ./bin/binary 
main.go
Many compilers allow output binaries to be statically linked,
including GoLang. Docker image size can be almost equal
to the binary size.
FROM scratch
ADD ./bin/binary /binary
CMD ["/binary"]
6.9MB 7.2MB
Set a HEALTHCHECK
HEALTHCHECK --interval=1m --timeout=10s 
CMD ( 
# check if HTTPS port is opened
lsof -i :443 && 
# send HTTP request
curl -sSf localhost:80/status 
) || exit 1
Setup a health check for your container so that
the orchestrator knows it’s state, also for debugging.
CI in a Dockerfile FROM scratch AS base
ADD . /build
FROM jakzal/phpqa:php7.2 AS base-qa
COPY --from=base /build /build
WORKDIR /build
RUN phplint . && 
phpa . && 
phpcpd .
FROM composer AS base-build
COPY --from=base /build /build
WORKDIR /build
RUN composer install
FROM phpunit/phpunit AS base-test
COPY --from=base-build /build /build
WORKDIR /build
RUN phpunit
FROM php:7.2-fpm-alpine AS final
COPY --from=base-build /build /var/www
One Dockerfile is
needed to lint, analyze,
install dependencies, test
and containerize your
project using a single
docker build
command.
Perfect Dockerfile
$ docker run --rm -i hadolint/hadolint < Dockerfile
/dev/stdin:1 DL3006 Always tag the version of an image explicitly
/dev/stdin:3 DL4000 MAINTAINER is deprecated
/dev/stdin:5 DL3020 Use COPY instead of ADD for files and folders
/dev/stdin:7 DL4001 Either use Wget or Curl but not both
/dev/stdin:8 DL4006 Set the SHELL option -o pipefail before RUN...
/dev/stdin:9 DL3003 Use WORKDIR to switch to a directory
Build best practice Docker images with a help
of Dockerfile linter.
Restart or respawn the container
# Bring back the development environment
$ docker restart gitlab
$ docker restart gitlab-runner
docker restart command allows to restart a running
container or reincarnate a stopped one.
Container disk usage
$ docker ps -s
CONTAINER ID IMAGE COMMAND
CREATED STATUS PORTS
NAMES SIZE
09b43a71eb95 nginx "nginx -g 'daemon of…"
3 seconds ago Up 2 seconds 80/tcp
vigilant_beaver 2B (virtual 109MB)
Size reports amount of disk used by the writable layer of a
container. Virtual shows disk space used for the read-only
image data and the writable layer.
Detach from a container
If you have started an interactive container (using -it parameters),
you can detach from it (and later attach back).
The default "detach" keyboard sequence is
^P^Q
Detach and attach anytime
$ docker run -it debian:stretch
root@e093566d8aff:/#
root@e093566d8aff:/# ^P^Q
$ docker attach $(docker ps -lq)
root@e093566d8aff:/#
Detaching and attaching back allows you to “jump in” to
different containers without rerunning them:
Ungraceful stop
# stop the container with 3s timeout
$ docker stop -t 3 container-name
# stop the whole stack with 3s timeout
$ docker-compose stop -t 3
When one of the containers is not handling signals
properly and blocks the stop command.
# set the grace period for a single container in YAML
services:
misbehaving:
stop_grace_period: 3s
Inspect a group of containers
# Find the names of all containers that exited with a non-zero code
$ docker inspect --format 
'{{if ne 0 .State.ExitCode}}{{.Name}} {{.State.ExitCode}}{{end}}' 
$(docker ps -aq)
# Show commands for all running containers
$ docker inspect 
--format '{{ print .Path }} {{ join .Args " " }}' 
$(docker ps -aq)
docker inspect can take more than one
container name or ID in the parameters.
Shared network stack
$ docker run -d --name nginx nginx
a0e43a69a087d4362d994ea2db1c76e3d8f055cffaf1105ec1279
$ docker run --net container:nginx busybox 
wget -q -O - localhost
<title>Welcome to nginx!</title>
$ docker run --rm --net container:nginx 
itsthenetwork/alpine-tcpdump
listening on eth0, link-type EN10MB (Ethernet), capture size ...
Containers can communicate over their loopback (lo) interface.
docker-compose and systemd
[Unit]
Description=My Docker Project
After=docker.service
BindsTo=docker.service
[Service]
WorkingDirectory=/srv/project
ExecStartPre=/usr/local/bin/docker-compose down
ExecStart=/usr/local/bin/docker-compose up --force-recreate
ExecStop=/usr/local/bin/docker-compose stop
[Install]
WantedBy=multi-user.target
Expose your Docker application as a systemd service.
Services well organized
x-project-vars:
- &project-name "my-docker-project"
- &project-version "${VERSION:-dev}"
- &syslog-host "tcp://127.0.0.1:1514"
- &web-replicas 4
x-project-base: &base
networks:
- project-network
x-logger-syslog: &syslog
logging:
driver: "syslog"
options:
syslog-address: *syslog-host
tag: *project-name
version: "3.4"
services:
web:
<<: *base
image: project/web
environment:
project_name: *project-name
project_version: *project-version
deploy:
replicas: *web-replicas
db:
<<: *base
<<: *syslog
image: mysql:5.7
Organize docker-compose.yml with extensions, environment variables,
YAML anchors and aliases.
.env for configuration
.env file allows you to expose a configuration file
for your project.
version: "3.5"
services:
web:
image: nginx:${VERSION:-1.15}
ports:
- ${PORT:-80}:80
VERSION=1.15.4
PORT=8080
/srv/project/docker-compose.yml /etc/project/project.conf
-> /srv/project/.env
envsubst for templating
# NGINX_PORT=80 NGINX_HOST=host.com NGINX_ROOT=/var/www
envsubst < nginx.conf.tpl > nginx.conf
Use envsubst to customize your configuration files with
environment variables.
server {
listen ${NGINX_PORT};
server_name ${NGINX_HOST};
root ${NGINX_ROOT};
}
server {
listen 80;
server_name host.com;
root /var/www;
}
nginx.conf.tpl nginx.conf
docker-entrypoint.sh
Recipe for a container
$ alias runlike='docker run --rm
-v /var/run/docker.sock:/var/run/docker.sock
assaflavie/runlike -p'
Get the exact docker run command for the container.
$ runlike gitlab
docker run 
--name=gitlab 
--hostname=gitlab.local 
--volume="/Users/dev/gitlab/data:/var/opt/gitlab" 
-p 80:80 
...
gitlab/gitlab-ce:latest
Clean environment
# Remove images older than one month
$ docker image prune --filter "until=720h"
# Remove build cache entries unused for one day
$ docker builder prune --filter "unused-for=24h"
Keep your Docker environment clean by purging
what is not needed.
Kali Linux in a web browser
$ docker run -d 
-p 6080:6080 
lukaszlach/kali-desktop:xfce
$ open http://127.0.0.1:6080/
Access Kali Linux desktop
environment when needed,
in your browser.
Thank you!

More Related Content

JDO 2019: Tips and Tricks from Docker Captain - Łukasz Lach

  • 1. Tips and Tricks from Docker Captain Łukasz Lach v2018.10-TSR/11+5/ v2019.03+3/ v2019.05+2
  • 2. Łukasz Lach Docker Captain Docker Certified Associate Docker Community Leader - Warsaw, Poland Speaker at DockerCon 2018 and 2019 Lecturer at the University of Warsaw llach@llach.pl
  • 3. Install Docker on Linux $ curl -fsSL get.docker.com | VERSION=18.03 CHANNEL=edge sh Easiest way to install Docker on Linux allowing to choose the CHANNEL (edge, test or experimental) and VERSION as well.
  • 4. Install Docker rootless $ curl -fsSL get.docker.com/rootless | sh Rootless Docker refers to running the Docker daemon (and containers) as a non-root user.
  • 5. Local Docker Hub mirror version: '3.7' services: registry: image: registry:2 ports: - 5000:5000 environment: REGISTRY_STORAGE_DELETE_ENABLED: 'true' REGISTRY_PROXY_REMOTEURL: 'https://registry-1.docker.io' Setup local, caching and revalidating Docker Hub mirror.
  • 6. No build context $ docker build -t my-image . Sending build context to Docker daemon 589.14kB $ docker build -t my-image - < Dockerfile Sending build context to Docker daemon 4.096kB When no build context is needed there is no point of waiting for it to be compressed and passed along.
  • 7. ADD a remote file ADD http://example.com/ /index.html ADD http://example.com/archive.tar.xz /archive ADD on a remote file does not utilize the build cache. RUN curl -fsSL http://example.com/ -o /index.html RUN curl -fsSL http://example.com/archive.tar.xz | tar -xJC /archive no cache for these and subsequent commands uses cache
  • 8. Build FROM scratch $ go build -v -a -installsuffix cgo -o ./bin/binary main.go Many compilers allow output binaries to be statically linked, including GoLang. Docker image size can be almost equal to the binary size. FROM scratch ADD ./bin/binary /binary CMD ["/binary"] 6.9MB 7.2MB
  • 9. Set a HEALTHCHECK HEALTHCHECK --interval=1m --timeout=10s CMD ( # check if HTTPS port is opened lsof -i :443 && # send HTTP request curl -sSf localhost:80/status ) || exit 1 Setup a health check for your container so that the orchestrator knows it’s state, also for debugging.
  • 10. CI in a Dockerfile FROM scratch AS base ADD . /build FROM jakzal/phpqa:php7.2 AS base-qa COPY --from=base /build /build WORKDIR /build RUN phplint . && phpa . && phpcpd . FROM composer AS base-build COPY --from=base /build /build WORKDIR /build RUN composer install FROM phpunit/phpunit AS base-test COPY --from=base-build /build /build WORKDIR /build RUN phpunit FROM php:7.2-fpm-alpine AS final COPY --from=base-build /build /var/www One Dockerfile is needed to lint, analyze, install dependencies, test and containerize your project using a single docker build command.
  • 11. Perfect Dockerfile $ docker run --rm -i hadolint/hadolint < Dockerfile /dev/stdin:1 DL3006 Always tag the version of an image explicitly /dev/stdin:3 DL4000 MAINTAINER is deprecated /dev/stdin:5 DL3020 Use COPY instead of ADD for files and folders /dev/stdin:7 DL4001 Either use Wget or Curl but not both /dev/stdin:8 DL4006 Set the SHELL option -o pipefail before RUN... /dev/stdin:9 DL3003 Use WORKDIR to switch to a directory Build best practice Docker images with a help of Dockerfile linter.
  • 12. Restart or respawn the container # Bring back the development environment $ docker restart gitlab $ docker restart gitlab-runner docker restart command allows to restart a running container or reincarnate a stopped one.
  • 13. Container disk usage $ docker ps -s CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES SIZE 09b43a71eb95 nginx "nginx -g 'daemon of…" 3 seconds ago Up 2 seconds 80/tcp vigilant_beaver 2B (virtual 109MB) Size reports amount of disk used by the writable layer of a container. Virtual shows disk space used for the read-only image data and the writable layer.
  • 14. Detach from a container If you have started an interactive container (using -it parameters), you can detach from it (and later attach back). The default "detach" keyboard sequence is ^P^Q
  • 15. Detach and attach anytime $ docker run -it debian:stretch root@e093566d8aff:/# root@e093566d8aff:/# ^P^Q $ docker attach $(docker ps -lq) root@e093566d8aff:/# Detaching and attaching back allows you to “jump in” to different containers without rerunning them:
  • 16. Ungraceful stop # stop the container with 3s timeout $ docker stop -t 3 container-name # stop the whole stack with 3s timeout $ docker-compose stop -t 3 When one of the containers is not handling signals properly and blocks the stop command. # set the grace period for a single container in YAML services: misbehaving: stop_grace_period: 3s
  • 17. Inspect a group of containers # Find the names of all containers that exited with a non-zero code $ docker inspect --format '{{if ne 0 .State.ExitCode}}{{.Name}} {{.State.ExitCode}}{{end}}' $(docker ps -aq) # Show commands for all running containers $ docker inspect --format '{{ print .Path }} {{ join .Args " " }}' $(docker ps -aq) docker inspect can take more than one container name or ID in the parameters.
  • 18. Shared network stack $ docker run -d --name nginx nginx a0e43a69a087d4362d994ea2db1c76e3d8f055cffaf1105ec1279 $ docker run --net container:nginx busybox wget -q -O - localhost <title>Welcome to nginx!</title> $ docker run --rm --net container:nginx itsthenetwork/alpine-tcpdump listening on eth0, link-type EN10MB (Ethernet), capture size ... Containers can communicate over their loopback (lo) interface.
  • 19. docker-compose and systemd [Unit] Description=My Docker Project After=docker.service BindsTo=docker.service [Service] WorkingDirectory=/srv/project ExecStartPre=/usr/local/bin/docker-compose down ExecStart=/usr/local/bin/docker-compose up --force-recreate ExecStop=/usr/local/bin/docker-compose stop [Install] WantedBy=multi-user.target Expose your Docker application as a systemd service.
  • 20. Services well organized x-project-vars: - &project-name "my-docker-project" - &project-version "${VERSION:-dev}" - &syslog-host "tcp://127.0.0.1:1514" - &web-replicas 4 x-project-base: &base networks: - project-network x-logger-syslog: &syslog logging: driver: "syslog" options: syslog-address: *syslog-host tag: *project-name version: "3.4" services: web: <<: *base image: project/web environment: project_name: *project-name project_version: *project-version deploy: replicas: *web-replicas db: <<: *base <<: *syslog image: mysql:5.7 Organize docker-compose.yml with extensions, environment variables, YAML anchors and aliases.
  • 21. .env for configuration .env file allows you to expose a configuration file for your project. version: "3.5" services: web: image: nginx:${VERSION:-1.15} ports: - ${PORT:-80}:80 VERSION=1.15.4 PORT=8080 /srv/project/docker-compose.yml /etc/project/project.conf -> /srv/project/.env
  • 22. envsubst for templating # NGINX_PORT=80 NGINX_HOST=host.com NGINX_ROOT=/var/www envsubst < nginx.conf.tpl > nginx.conf Use envsubst to customize your configuration files with environment variables. server { listen ${NGINX_PORT}; server_name ${NGINX_HOST}; root ${NGINX_ROOT}; } server { listen 80; server_name host.com; root /var/www; } nginx.conf.tpl nginx.conf docker-entrypoint.sh
  • 23. Recipe for a container $ alias runlike='docker run --rm -v /var/run/docker.sock:/var/run/docker.sock assaflavie/runlike -p' Get the exact docker run command for the container. $ runlike gitlab docker run --name=gitlab --hostname=gitlab.local --volume="/Users/dev/gitlab/data:/var/opt/gitlab" -p 80:80 ... gitlab/gitlab-ce:latest
  • 24. Clean environment # Remove images older than one month $ docker image prune --filter "until=720h" # Remove build cache entries unused for one day $ docker builder prune --filter "unused-for=24h" Keep your Docker environment clean by purging what is not needed.
  • 25. Kali Linux in a web browser $ docker run -d -p 6080:6080 lukaszlach/kali-desktop:xfce $ open http://127.0.0.1:6080/ Access Kali Linux desktop environment when needed, in your browser.