\section{Docker Konténerek} \begin{frame}{Mi a konténer?} \begin{block}{Container -- Futó alkalmazás példány} \begin{itemize} \item Image-ből létrehozott, izolált futtatási környezet \item A konténer \textbf{futó folyamat} a host gépen \item Saját fájlrendszer, hálózat, folyamat tér \end{itemize} \end{block} \end{frame} \begin{frame}{Konténer -- Jellemzők} \begin{block}{Tulajdonságok} \begin{itemize} \item Könnyűsúlyú, gyorsan indul és áll le \item Egy Image-ből több konténer is indítható párhuzamosan \end{itemize} \end{block} \begin{exampleblock}{Analógia} Ha az Image egy \textbf{program} (pl. exe fájl), akkor a Container egy \textbf{futó folyamat} ebből a programból. \end{exampleblock} \end{frame} \begin{frame}{Konténer életciklus állapotok} \begin{center} \begin{tikzpicture}[node distance=2cm] \node[draw, circle, fill=blue!20, minimum size=1.5cm, align=center] (created) {Created}; \node[draw, circle, fill=green!20, minimum size=1.5cm, align=center, right=of created] (running) {Running}; \node[draw, circle, fill=orange!20, minimum size=1.5cm, align=center, below=of running] (paused) {Paused}; \node[draw, circle, fill=red!20, minimum size=1.5cm, align=center, left=of paused] (stopped) {Stopped}; \node[draw, circle, fill=gray!20, minimum size=1.5cm, align=center, below=of created] (exited) {Exited}; \draw[->, thick] (created) -- (running) node[midway, above, font=\tiny] {start}; \draw[->, thick] (running) -- (paused) node[midway, right, font=\tiny] {pause}; \draw[->, thick] (paused) -- (running) node[midway, left, font=\tiny] {unpause}; \draw[->, thick] (running) -- (stopped) node[midway, above, font=\tiny] {stop}; \draw[->, thick] (stopped) -- (running) node[midway, below, font=\tiny] {restart}; \draw[->, thick] (running) -- (exited) node[midway, right, font=\tiny] {exit}; \end{tikzpicture} \end{center} \end{frame} \begin{frame}{Konténer állapotok -- Magyarázat} \begin{itemize} \item \textbf{Running:} Aktívan fut, CPU és memória használ \item \textbf{Stopped/Exited:} Leállítva, de nem törölve \item \textbf{Paused:} Folyamatok befagyasztva \end{itemize} \end{frame} \begin{frame}[fragile]{Konténer indítása -- docker run} \begin{block}{Alap parancs} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] docker run \end{lstlisting} \end{block} \begin{exampleblock}{Egyszerű példa} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Nginx webszerver indítása docker run nginx # Háttérben futtatás (-d = detached) docker run -d nginx # Név adása a konténernek docker run --name my-nginx nginx \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}{Konténer indítása -- Megjegyzés} \begin{alertblock}{Megjegyzés} Ha az image nincs helyben, Docker automatikusan letölti a Docker Hub-ról. \end{alertblock} \end{frame} \begin{frame}{Port mapping -- Miért kell?} \begin{block}{Miért kell?} \begin{itemize} \item Konténer saját hálózati térben fut \item Host gépen elérhetetlenek a portok alapértelmezetten \item Port mapping: host port \textrightarrow{} konténer port \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Port mapping -- Használat} \begin{exampleblock}{-p flag használata} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Szintaxis: -p : docker run -d -p 8080:80 nginx # Most elérhető: http://localhost:8080 \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Port mapping -- Több port} \begin{exampleblock}{Több port mapping} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Több port mapping docker run -d -p 3000:3000 -p 5000:5000 my-app \end{lstlisting} \end{exampleblock} \begin{alertblock}{Példa} \texttt{-p 8080:80} $\Rightarrow$ Host 8080-as port $\Rightarrow$ Konténer 80-as port \end{alertblock} \end{frame} \begin{frame}[fragile]{Környezeti változók -- Alapok} \begin{block}{-e flag használata} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Egy változó docker run -e NODE_ENV=production my-app # Több változó docker run -e DB_HOST=localhost \ -e DB_PORT=5432 \ -e DB_NAME=mydb \ my-app \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Környezeti változók -- Fájlból} \begin{block}{.env fájlból} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # .env fájlból docker run --env-file .env my-app \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Környezeti változók -- PostgreSQL példa} \begin{exampleblock}{PostgreSQL példa} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] docker run -d \ -e POSTGRES_USER=admin \ -e POSTGRES_PASSWORD=secret123 \ -e POSTGRES_DB=myapp \ postgres:15 \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}{Volume mounting -- Miért kell?} \begin{block}{Miért kell volume?} \begin{itemize} \item Konténer törléskor az adatok elvesznek \item Volume: perzisztens tárolás a host gépen \item Megosztható több konténer között \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Volume mounting -- Named volume} \begin{exampleblock}{Named volume} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Named volume docker run -v mydata:/var/lib/postgresql/data \ postgres \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Volume mounting -- Bind mount} \begin{exampleblock}{Bind mount (host útvonal)} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Bind mount docker run -v /host/path:/container/path my-app # Windows példa docker run -v C:\projects\app:/usr/src/app node-app # Csak olvasható docker run -v mydata:/data:ro my-app \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Teljes példa -- Node.js alkalmazás} \begin{exampleblock}{Összes opció együtt} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] docker run -d \ --name my-node-app \ -p 3000:3000 \ -e NODE_ENV=production \ -e DB_HOST=postgres \ -v $(pwd)/src:/usr/src/app/src \ --restart unless-stopped \ node:18-alpine \ npm start \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}{Teljes példa -- Paraméterek} \begin{block}{Opciók részletesen} \begin{itemize} \item \texttt{-d}: Detached módban fut (háttérben) \item \texttt{--name}: Konténer neve (my-node-app) \item \texttt{-p 3000:3000}: Port mapping (host:container) \end{itemize} \end{block} \end{frame} \begin{frame}{Teljes példa -- Paraméterek folyt.} \begin{block}{Opciók részletesen} \begin{itemize} \item \texttt{-e}: Környezeti változók beállítása \item \texttt{-v}: Volume mounting (perzisztens adatok) \item \texttt{--restart}: Automatikus újraindítás \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Konténerek listázása -- docker ps} \begin{block}{Futó konténerek} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Csak futó konténerek docker ps # Összes konténer (leállítottak is) docker ps -a # Csak ID-k megjelenítése docker ps -q \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Konténerek listázása -- Formázás} \begin{block}{Formázott kimenet} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] docker ps --format \ "table {{.Names}}\t{{.Status}}\t{{.Ports}}" \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Konténer kezelő parancsok -- Leállítás} \begin{block}{Leállítás és újraindítás} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Leállítás (graceful) docker stop # Erőszakos leállítás docker kill # Újraindítás docker restart \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Konténer kezelő parancsok -- Szünet és törlés} \begin{block}{Szüneteltetés és törlés} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Szüneteltetés docker pause docker unpause # Törlés (csak leállított konténer) docker rm # Futó konténer törlése docker rm -f \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Interaktív mód -- Flagek} \begin{block}{-it flagek} \begin{itemize} \item \texttt{-i}: Interactive (interaktív) \item \texttt{-t}: TTY (pseudo-terminal) \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Interaktív mód -- Példák} \begin{exampleblock}{Bash shell indítása konténerben} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Ubuntu konténer bash-el docker run -it ubuntu bash # Node.js REPL docker run -it node:18 # Alpine Linux shell docker run -it alpine sh \end{lstlisting} \end{exampleblock} \begin{alertblock}{Kilépés} \texttt{exit} parancs vagy \texttt{Ctrl+D} $\Rightarrow$ konténer leáll\\ \texttt{Ctrl+P, Ctrl+Q} $\Rightarrow$ konténer fut tovább (detach) \end{alertblock} \end{frame} \begin{frame}[fragile]{docker exec -- Parancs futtatása} \begin{block}{docker exec használata} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Shell indítása futó konténerben docker exec -it bash # Parancs futtatása docker exec ls -la /app # Root userként docker exec -u root -it bash \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{docker exec -- Gyakorlati példák} \begin{exampleblock}{Gyakori használat} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # PostgreSQL konzol docker exec -it postgres-container \ psql -U admin -d mydb # NPM parancs futtatása docker exec my-app npm install axios \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Logok -- docker logs} \begin{block}{Alap log parancsok} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Összes log docker logs # Utolsó 50 sor docker logs --tail 50 # Követés (folyamatos, mint tail -f) docker logs -f \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Logok -- Szűrés} \begin{block}{Szűrt logok} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Időbélyegekkel docker logs -t # Utolsó 10 perc docker logs --since 10m \end{lstlisting} \end{block} \begin{alertblock}{Tipp} Fejlesztéskor: \texttt{docker logs -f} $\Rightarrow$ valós idejű log követés \end{alertblock} \end{frame} \begin{frame}[fragile]{docker inspect -- Részletes info} \begin{block}{docker inspect} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Teljes JSON konfiguráció docker inspect # Specifikus mező (pl. IP cím) docker inspect -f \ '{{.NetworkSettings.IPAddress}}' \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{docker stats -- Erőforrás használat} \begin{block}{docker stats} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Valós idejű statisztika (CPU, memória, hálózat) docker stats # Csak egy konténer docker stats \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Erőforrás korlátok -- Memória} \begin{block}{Memória korlátozás} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Memória limit (256MB) docker run -m 256m nginx # Memória swap limit docker run -m 256m --memory-swap 512m my-app \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Erőforrás korlátok -- CPU} \begin{block}{CPU korlátozás} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # CPU limit (50% of 1 CPU) docker run --cpus="0.5" nginx # Kombináció docker run -m 512m --cpus="1.0" my-app \end{lstlisting} \end{block} \begin{alertblock}{Miért fontos?} Megakadályozza, hogy egy konténer minden erőforrást elfogyasszon.\\ Production környezetben kötelező! \end{alertblock} \end{frame} \begin{frame}[fragile]{Restart policies -- Opciók} \begin{block}{--restart flag opciók} \begin{itemize} \item \texttt{no}: Nem indul újra (alapértelmezett) \item \texttt{always}: Mindig újraindul \item \texttt{on-failure}: Csak hiba esetén \end{itemize} \end{block} \end{frame} \begin{frame}[fragile]{Restart policies -- Használat} \begin{exampleblock}{Használat} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Mindig újraindul (host reboot után is) docker run -d --restart always nginx # Csak hiba esetén, max 5 próbálkozás docker run -d --restart on-failure:5 my-app # Production ajánlott docker run -d --restart unless-stopped my-app \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Fájlok másolása -- docker cp} \begin{block}{Host és konténer között} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Host -> Konténer docker cp /host/file.txt container-id:/path/ # Konténer -> Host docker cp container-id:/app/logs/app.log ./logs/ \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Fájlok másolása -- Példák} \begin{exampleblock}{Gyakorlati példa} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Konfigurációs fájl feltöltés docker cp config.json \ nginx:/etc/nginx/config.json # Log fájl letöltés elemzéshez docker cp my-app:/var/log/app.log ./logs/ \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Tisztítás -- Konténer törlés} \begin{block}{Leállított konténerek törlése} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Egy konténer törlése docker rm # Összes leállított konténer docker container prune # Futó konténer törlése docker rm -f \end{lstlisting} \end{block} \end{frame} \begin{frame}[fragile]{Tisztítás -- Tömeges törlés} \begin{block}{Tömeges műveletek} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Minden konténer törlése (VIGYÁZAT!) docker rm -f $(docker ps -aq) \end{lstlisting} \end{block} \begin{alertblock}{Figyelem} A \texttt{prune} parancsok visszavonhatatlanul törölnek!\\ Production környezetben óvatosan használd! \end{alertblock} \end{frame} \begin{frame}[fragile]{Hasznos egy-sorosok -- Alapok} \begin{exampleblock}{Gyakori feladatok} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Összes futó konténer leállítása docker stop $(docker ps -q) # Konténer IP címének lekérése docker inspect -f \ '{{range.NetworkSettings.Networks}} {{.IPAddress}}{{end}}' \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}[fragile]{Hasznos egy-sorosok -- Haladó} \begin{exampleblock}{Haladó parancsok} \begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily] # Legutóbbi konténer logjai docker logs -f $(docker ps -lq) # Konténer shell gyors elérés docker exec -it \ $(docker ps -q --filter name=my-app) bash \end{lstlisting} \end{exampleblock} \end{frame} \begin{frame}{Összefoglalás -- Létrehozás} \begin{block}{Létrehozás és futtatás} \texttt{docker run -d -p 8080:80 --name web nginx} \end{block} \begin{block}{Kezelés} \begin{itemize} \item \texttt{docker ps}: Listázás \item \texttt{docker logs -f}: Logok \item \texttt{docker exec -it bash}: Shell \end{itemize} \end{block} \end{frame} \begin{frame}{Összefoglalás -- Fontos opciók} \begin{block}{Fontos opciók} \begin{itemize} \item \texttt{-p}: Port mapping (hozzáférés) \item \texttt{-v}: Volume (perzisztencia) \item \texttt{-e}: Env változók (konfiguráció) \end{itemize} \end{block} \begin{block}{Megbízhatóság} \begin{itemize} \item \texttt{--restart}: Újraindítás (megbízhatóság) \item \texttt{-m / --cpus}: Erőforrás korlátok \end{itemize} \end{block} \end{frame} \begin{frame}{Best Practices -- Konfiguráció} \begin{exampleblock}{Ajánlott gyakorlatok} \begin{itemize} \item Mindig adj \textbf{nevet} a konténernek (\texttt{--name}) \item Használj \textbf{restart policy}-t production-ben \item Állíts be \textbf{resource limits}-et (CPU, memória) \end{itemize} \end{exampleblock} \end{frame} \begin{frame}{Best Practices -- Adatok és biztonság} \begin{exampleblock}{Ajánlott gyakorlatok} \begin{itemize} \item Használj \textbf{volume}-ot perzisztens adatokhoz \item Ne futtass \textbf{root user}-ként \item \textbf{Logokat} naplózd és monitorozd \end{itemize} \end{exampleblock} \end{frame} \begin{frame}{Best Practices -- Kerülendő} \begin{alertblock}{Kerülendő} \begin{itemize} \item Érzékeny adatok környezeti változóban (használj secrets-et) \item Túl sok folyamat egy konténerben \item Adatok tárolása konténerben (volume nélkül) \end{itemize} \end{alertblock} \end{frame}