ID: I202604231704
Status: idea
Tags: Promptus Imperii, Docker, Docker Compose
Docker workshop PI
Workshop van Frido
de volledige readme van de workshop.
Shit man, nu heb ik honger tijdens de workshopā¦
Waar gebruik je het?
Docker kom je overal tegen in de SDLC.
- Requirements: om te prototypen
- Design: hoe kan je je process inrichten
- Implementatie: bij de CI/CD
- Testing: je kan alle testcases makkelijk in docker gooien
- Evaluation: in productie zie je het ook terugkomen
PhotoManager example
Github repository van de leraar.
alle dingen zijn terug te lezen in de readme in de repo.
Rundown
Op hub.docker.com staan allemaal images die je al kan importeren. Bij projecten zie je ook de CVEās waar ze in voor komen.
docker run hello-world is een command.
docker run -p 8000:8000 hello-world is om de port 8000 te exposen.
docker build . is om een dockerfile met de naam dockerfile te builden.
docker build -t cool . is om een dockerfile met de naam dockerfile te builden als een image met de naam cool.
docker system df haal je op hoeveel images je hebt etc.
met docker container ls -a kan je al je containers bekijken (door -a ook degenes die niet actief zijn)
docker containers zijn niet persistent wanner je hem update.
touch dockerfile_new is een mooi linux command om een nieuwe dockerfile te maken.
het verschil tussen RUN en CMD is dat RUN gebeurt tijdens het bouwen van een image. CMD kan je overwriten.
je dockerfile kan elke naam hebben, je kan een dockerfile dus ook gwn henk.md noemen en het zal nogsteeds werken.
Dockerfile aanmaken
In principe is het volgende genoeg om een docker container te maken als je docker build -f dockerfile . uitvoert, onthoudt dat je in de goede directory moet zitten:
FROM debian:12-slimdocker run -it 02-building-image:latest /bin/bash kan je dan met de shell in de container praten.
als je een dockerfile wilt met linux packages, stop dit in je dockerfile:
FROM debian:12-slim
RUN apt update
RUN apt install -y nano python3Met de volgende dockerfile gaat hij automatisch naar de Linux terminal. Nu kan je ook gwn docker run -it 02-building-image:latest gebruiken om hem te runnen.
FROM debian:12-slim
RUN apt update
RUN apt install -y nano python3
CMD [ "/bin/bash" ]En met de volgende kan je direct een python file runnen:
FROM debian:12-slim
RUN apt update
RUN apt install -y nano python3
CMD [ "/bin/python3", "main.py" ]Maar ja, hoe geef je dan je main.py mee? Nou door het volgende te doen (onthoudt dat je relatieve paden hebt en main.py dus in de zelfde root moet zitten als je dockerfile):
FROM debian:12-slim
RUN apt update
RUN apt install -y nano python3
COPY main.py
CMD [ "/bin/python3", "main.py" ]Een entrypoint kan je nooit overschrijven (whatever that means).
FROM debian:12-slim
RUN apt update
RUN apt install -y nano python3
COPY main.py
ENTRYPOINT [ "executable"]
# CMD [ "/bin/python3", "main.py" ] # is overwritable when you run:
# docker run -it 02-building-image:latest /bin/bashNu geef je een argument mee aan je build die je kan overwriten. om te zorgen dat je bijv een username en passw mee kan geven. docker run -it 02-building-image:latest --build-arg MAIN=main_new.py
FROM debian:12-slim
RUN apt update
RUN apt install -y nano python3
ARG MAIN=main.py
COPY ${MAIN}
RUN cp ${MAIN} main.py
CMD [ "/bin/python3", "main.py" ]Een entrypoint kan je niet met arguments aanpassen, daarvoor heb je env variables. Dit heeft ook voordelen tegenover variables in andere scenarios, zoals dat je hebt op runtime nog kan aanpassen.
FROM debian:12-slim
RUN apt update
RUN apt install -y nano python3
ENV MAIN=main.py
COPY ${MAIN}
ENTRYPOINT [ "/bin/bash", "-c", "/bin/python3 ${MAIN}"]of hieronder is een ander voorbeeld van een entrypoint. docker run -it -e TARGET=intel 02-building-image:latest. En ofc kan je de env en arg combinen.
FROM debian:12-slim
RUN apt update
RUN apt install -y nano python3
COPY main_new.py
ENV TARGET=esp32
ENTRYPOINT [ "/bin/bash", "/bin/python3 main_new.py --target ${TARGET}"]03-webserver
met de volgende dockerfile navigeer je naar de app folder en maak je daar 2 folders aan. als je dus docker build -t websiteee . en dan docker run -p 8000:8000 websiteee dan run je deze mooie website op localhost:8000
FROM python:3.9-slim
WORKDIR /app
RUN mkdir webfolder01
RUN mkdir webfolder02
ENTRYPOINT [ "python", "-m", "http.server", "8000"]04-volumes
hier was ik blijkbaar niet bij??
05-compilation
met SHELL kies je welke shell je gebruikt. In de volgende dockerfile builden we rust. We gebruiken CMD zodat we die kunnen overwriten en het kunnen gaan runnen instead. docker build -t 05-compilation . en dan docker run -ti -v ./hello-world:/workdir 05-compilation:latest
FROM debian:12-slim
WORKDIR /workdir
SHELL ["/bin/bash", "-c"]
RUN apt update
RUN apt install -y curl build-essential
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
ENV PATH=${PATH}:/root/.cargo/bin
CMD [ "cargo", "build"]
06-multistage
hier hebben we 3 dockerfileās
docker build -t 06-multistage-large -f dockerfile-large .docker build -t 06-multistage-multi -f dockerfile-multi .docker build -t 06-multistage-rust-multi -f dockerfile-rust-multi .docker image ls -a
en dan zie je dat de image sizes heel erg verschillen:
IMAGE ID DISK USAGE CONTENT SIZE EXTRA
05-compilation:latest cca7e29ef467 1.77GB 0B U
06-multistage-large:latest aec6f6465708 394MB 0B
06-multistage-multi:latest c62f9a0c2ca4 10.7MB 0B
06-multistage-rust-multi:latest 53925fb7063b 79.2MB 0B
07-compose
Docker Compose WHOOOOOP.
services:
web:
image: 04-webserver-demo:latest
container_name: python-webserver
restart: unless-stopped
ports:
- 8001:8000
volumes:
- ./webserver/web_root:/app # <--- This is a relative path. So it depends where you start the image
- time_file:/app/time
depends_on:
- time-fetcher
time-fetcher:
build: python-timefetcher
volumes:
- time_file:/time/time_file
volumes:
time_file:maar dit gaat wss niet werken omdat je die image niet hebt (tenzij je stap 4 ff build). maar je kan dit starten met docker compose up en dan weer afsluiten met docker compose down. Wanneer je dit runt zie je dit op localhost:8001
08-networking
services:
web:
image: 04-webserver-demo:latest
restart: unless-stopped
volumes:
- ./webserver/web_root:/app # <--- This is a relative path. So it depends where you start the image
networks:
- between_containers # Only on internal network, NOT reachable from host
proxy:
image: nginx:alpine
ports:
- "8080:80" # Host port -> Proxy
networks:
- between_containers
- to_host # <- Add this so the host can reach it
volumes:
- ./proxy/nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- web
networks:
between_containers:
driver: bridge
internal: true # Blocks external traffic ā no internet access
to_host:
driver: bridge
external_between_host_and_proxy:
# <-- Not used at the moment
external: true
driver_opts:
# pass options to driver for network creation
com.docker.network.bridge.host_binding_ipv4: 127.0.0.1
We hebben nu een mooie proxy. ik weet niet hoe ik dit moet uitleggen, maar ik weet wel dat het werkt ;)
Je wilt netwerken om meerdere containers met elkaar te laten praten. Denk bijvoorbeeld aan een MariaDB container die je API kan berijken, maar het internet niet. Dit is wat ik dus doe met File - mongo-stack.