Skip to content

Latest commit

 

History

History
425 lines (351 loc) · 8.54 KB

docker-ardan.md

File metadata and controls

425 lines (351 loc) · 8.54 KB

Course

Ardan Labs
Jérôme Petazzoni
https://2022-11-live.container.training/docker.yml.html

Day 1

Day 1 - Basic

# run detached
docker run -d jpetazzo/clock
# run read only
docker run -it --read-only jpetazzo/clock
# logs
docker logs CONTAINER_ID
# logs tail
docker logs CONTAINER_ID -f --tail 3
# stop container
docker stop CONTAINER_ID
# kill container
docker kill CONTAINER_ID
# start container
docker start CONTAINER_ID
# attach an shell
docker exec -it CONTAINER_ID /bin/bash
# kill all container
docker kill $(docker ps -q)

Day 1 - Images

# list all images
docker images
# search remote registry
docker search ubuntu
# download image
docker pull ubuntu
# diff comparing to base image
docker diff CONTAINER_ID
# commit change made to image
docker commit CONTAINER_ID
# tagging images
docker tag NEW_IMAGE_ID figlet
# run using tag
docker run -it figlet

Day 1 - Dockerfile

mkdir myimage
cd myimage

Plain Txt

FROM ubuntu
RUN apt-get update
RUN apt-get install figlet
# build the image
docker build -t figlet .
# see history (layers)
docker history figlet

JSON

RUN ["apt-get", "install", "figlet"]

Copy file

FROM ubuntu
RUN apt-get update
RUN apt-get install -y build-essential
COPY hello.c /
RUN make hello
CMD /hello

Day 1 - Go Exercise

Run CMD directly uses shell

FROM golang
COPY . .
RUN go build dispatcher.go
CMD ./dispatcher
docker build . -t web
docker run web
docker exec 90831b3c48b0 ps aux
#USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
#root           1  0.0  0.0   2576   872 ?        Ss   13:29   0:00 /bin/sh -c ./dispatcher
#root           7  0.0  0.2 1600508 5764 ?        Sl   13:29   0:00 ./dispatcher

Correct way to invoke go binary

FROM golang
COPY . .
RUN go build dispatcher.go
CMD ["./dispatcher"]
docker exec 2b4238a071b6 ps aux
#USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
#root           1  0.0  0.3 1600508 7884 ?        Ssl  13:30   0:00 ./dispatcher

Day 2

Day 2 - Network

# publish all ports
docker run -d -P nginx
# docker ps to find mapped port
docker ps
# or by container id
docker port CONTAINER_ID 80
# choose a specif port
docker run -d -p 8000:80 nginx
# find ip address
sudo docker inspect --format '{{ .NetworkSettings.IPAddress }}' CONTAINER_ID

Day 2 - Development Workflow

Testing an example

# clone project
git clone https:/jpetazzo/namer
# build an docker image
docker build -t namer .
# run exposing ports
docker run -dP namer
# check port
docker ps -l

Mapping source code to a local dir

# run cointaner with source code (src) mapped to local current dir
docker run --mount=type=bind,source=$(pwd),target=/src -dP namer
# edit company_name_generator.rb outside the cointaner
# change the color line 13 (color: royalblue;)
vim company_name_generator.rb
# find the port
docker ps
# see new color on the browser
http://localhost:32768/

Day 2 - Network

# list networks
docker network ls
# create network
docker network create dev
docker network create prod
# create container with network
# each network trunk and prod is isolated
docker run --net trunk -ti alpine
docker run --net prod -ti alpine
# alias is a dns name
docker run --net prod --net-alias api -d nginx
ping api

Day 2 - Compose

# install and run containers
docker-compose up
# start containers in the background
docker-compose up -d
# list all containers
docker-compose ps
# show logs
docker-compose logs
# stop all containers
docker-compose stop
# stop and remove
docker-compose down
# get public ib
curl icanhazip.com

Day 3

Day 3 - Compose file

Example word
https:/jpetazzo/wordsmith

docker-compse.yaml:

version: "3"

services:
  web:
    build: web
    ports:
      - 8888:80
    volumes:
      - ./web/static:/go/static
  words:
    build: words
  db:
    build: db
#networks:

Day 3 - Managing containers

# list size of all containers
docker ps --all --size
# prune containers
docker system prune
# detach from a container (exit stop the container)
# ctrl P + ctrl Q
# attach
docker attach CONTAINER_ID
#
# create and run container (withour using run instead)
docker create -ti ubuntu
docker start CONTAINER_ID
docker attach CONTAINER_ID
# or using a name
docker create --name myubuntu -ti ubuntu
docker start myubuntu
docker attach myubuntu
# rename a container
docker rename myubuntu mubuntu
# show diff inside container (changed file)
docker diff mubuntu
# copy a specific file from inside the container
docker cp mubuntu:/readme readme

Day 3 - Optimizing Dockerfiles

# instead of using one by one
# RUN base
# RUN install shell
# RUN install tearraform
# RUN install ffmpeg
# uses Nixery (Nix ecosystem) package manager and NixOS to generate images on the fly
docker run -ti nixery.dev/shell/terraform/ffmpeg

# reduce number of layers: instead
#RUN apt-get install thisthing
#RUN apt-get install andthatthing andthatotherone
#RUN apt-get install somemorestuff
# to
# RUN apt-get install thisthing andthatthing andthatotherone somemorestuff
# or uses backslash
# RUN apt-get install thisthing \
#                     andthatthing \
#                     andthatotherone \
#                     somemorestuff

# bad when you change something in your code will install everything again
FROM python
WORKDIR /src
COPY . .
RUN pip install -qr requirements.txt
EXPOSE 5000
CMD ["python", "app.py"]
# good to avoid reinstalling requirements all the time
FROM python
WORKDIR /src
COPY requirements.txt .
RUN pip install -qr requirements.txt
COPY . .
EXPOSE 5000
CMD ["python", "app.py"]

Day 3 - Advanced Dockerfile Syntax

ARG

FROM ubuntu
ENV DATABASE_PASS=secret
ARG API_KEY=hello
RUN echo curh http://myapi.com -H "X-Auth_Header $API_KEY"
#at build time it change API_KEY and it is not an environment variable
docker build . -t argdemo
#you can override at command line
docker build . -t argdemo --build-arg API_KEY=very.secure

ONBUILD - it sets instruction taht will be executed when another image is builtd from the image being build

FROM ubuntu
ONBUILD RUN apt-get update
FROM firstbuild
RUN apt-get install figlet

ENTRYPOINT

ENTRYPOINT [ "nginx" ]
CMD [ "-g", "daemon off;" ]

The ENTRYPOINT specifies the command to be run and the CMD specifies its options.
On the command line we can then potentially override the options when needed.

docker run -d <dockerhubUsername>/web_image -t

Day 3 - Reducing image size

RUN apt-get install build-essential -y
RUN ... compile the code ...
RUN apt-get remove build-essential
RUN ... make clean

It doesn't work because of layers Solution: Multi-stage builds

At any point in our Dockerfile, we can add a new FROM line. This line starts a new stage of our build. Each stage can access the files of the previous stages with COPY --from=.... When a build is tagged (with docker build -t ...), the last stage is tagged. Previous stages are not discarded: they will be used for caching, and can be referenced

FROM ubuntu AS compiler
RUN apt-get update
RUN apt-get install -y build-essential
COPY hello.c /
RUN make hello
FROM ubuntu
COPY --from=compiler /hello /hello
CMD /hello

It is still a big image but you can try other base image

busybox alpine

Or if you are going to have a lot of container in your server using the same base image
You can use ubuntu that is larger but because of the layers you will have one copy no matter how many different images you have
if it share the same FROM ubuntu

Day 4

Day 4 - Publishing images

# login
docker login
# let's tag our figlet image
docker tag figlet jpetazzo/figlet
# push it to the Hub:
docker push jpetazzo/figlet
# anybody can download
docker run jpetazzo/figlet

Day 4 - Buildkit

New build system

  • copy files only when they are needed; cache them
  • compute dependency graph (dependencies are expressed by COPY)
  • parallel execution
  • doesn't rely on Docker, but on internal runner/snapshotter
  • can run in "normal" containers (including in Kubernetes pods)
# enable
export DOCKER_BUILDKIT=1
# use the same build commands
# multi-arch
docker buildx build … \
       --platform linux/amd64,linux/arm64,linux/arm/v7,linux/386 \
       [--tag jpetazzo/hello --push]

Day 4 - Container network drivers

# no network
docker run ti --net none alpine
# same network as host
docker run ti --net host alpine