Files
GKNB_MSTM071/Backend_ppt/docker/docker_file.tex
T
2026-02-17 21:17:42 +01:00

978 lines
27 KiB
TeX

\section{Dockerfile}
\begin{frame}{Mi a Dockerfile?}
\begin{block}{Dockerfile -- Image építési utasítások}
\begin{itemize}
\item Szöveges fájl, amely leírja hogyan kell egy image-et építeni
\item Tartalmazza az összes parancsot sorrendben
\item Verziókezelhető (Git-ben tárolva)
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Dockerfile -- Jellemzők}
\begin{block}{Tulajdonságok}
\begin{itemize}
\item Reprodukálható: ugyanaz a Dockerfile = ugyanaz az image
\item Neve: \texttt{Dockerfile} (kiterjesztés nélkül)
\end{itemize}
\end{block}
\begin{exampleblock}{Analógia}
A Dockerfile olyan, mint egy \textbf{sütési recept} -- lépésről lépésre leírja, hogyan készüljön az image.
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Első Dockerfile -- Kód}
\begin{block}{Legegyszerűbb példa}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
FROM ubuntu:22.04
CMD echo "Hello World!"
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Első Dockerfile -- Build és futtatás}
\begin{exampleblock}{Build és futtatás}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Image építése
docker build -t my-hello .
# Konténer futtatása
docker run my-hello
# Kimenet: Hello World!
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Első Dockerfile -- Magyarázat}
\begin{block}{Utasítások}
\begin{itemize}
\item \texttt{FROM}: Alap image megadása
\item \texttt{CMD}: Alapértelmezett parancs futtatáskor
\end{itemize}
\end{block}
\begin{block}{Build paraméterek}
\begin{itemize}
\item \texttt{-t}: Tag (név) adása az image-nek
\item \texttt{.}: Build context (jelenlegi mappa)
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Dockerfile alaputasítások -- 1. rész}
\begin{block}{Alapépítő utasítások}
\begin{enumerate}
\item \texttt{FROM} -- Alap image kiválasztása
\begin{itemize}
\item Minden Dockerfile ezzel kezdődik
\item Meghatározza a kiinduló környezetet
\end{itemize}
\item \texttt{WORKDIR} -- Munkakönyvtár beállítása
\begin{itemize}
\item Létrehozza és beállítja a dolgozó könyvtárat
\item Minden következő utasítás itt fut
\end{itemize}
\end{enumerate}
\end{block}
\end{frame}
\begin{frame}{Dockerfile alaputasítások -- 2. rész}
\begin{block}{Fájl és csomag kezelés}
\begin{enumerate}
\setcounter{enumi}{2}
\item \texttt{COPY} / \texttt{ADD} -- Fájlok másolása
\begin{itemize}
\item Fájlok hozzáadása az image-hez
\item COPY javasolt, ADD extra funkciókkal
\end{itemize}
\item \texttt{RUN} -- Parancs futtatása build közben
\begin{itemize}
\item Csomagok telepítése, fájlok létrehozása
\item Minden RUN új réteget hoz létre
\end{itemize}
\end{enumerate}
\end{block}
\end{frame}
\begin{frame}{Dockerfile alaputasítások -- 3. rész}
\begin{block}{Konfiguráció és indítás}
\begin{enumerate}
\setcounter{enumi}{4}
\item \texttt{ENV} -- Környezeti változó beállítása
\item \texttt{EXPOSE} -- Port deklarálása
\item \texttt{CMD} / \texttt{ENTRYPOINT} -- Indítási parancs
\end{enumerate}
\end{block}
\begin{alertblock}{Sorrend fontos!}
A Dockerfile utasításai felülről lefelé hajtódnak végre
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{FROM -- Alap image kiválasztása}
\begin{block}{Hivatalos image-ek}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Hivatalos Node.js image
FROM node:18
# Specifikus verzió
FROM node:18.16.0
# Alpine Linux alapú (kisebb méret)
FROM node:18-alpine
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{FROM -- További példák}
\begin{block}{Más nyelvek és rendszerek}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Ubuntu
FROM ubuntu:22.04
# Python
FROM python:3.11
\end{lstlisting}
\end{block}
\begin{alertblock}{Ajánlás}
Használj \textbf{specifikus verziót} (pl. \texttt{node:18.16}) a \texttt{latest} helyett!\\
Alpine verzió: kisebb méret, gyorsabb build.
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{WORKDIR -- Kód}
\begin{block}{Beállítja a munkakönyvtárat}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
FROM node:18
# Munkakönyvtár létrehozása és beállítása
WORKDIR /usr/src/app
# Minden utána következő parancs itt fut
COPY package.json ./
RUN npm install
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{WORKDIR -- Magyarázat}
\begin{block}{Funkcionalitás}
\begin{itemize}
\item Létrehozza a könyvtárat, ha nem létezik
\item Minden következő \texttt{RUN}, \texttt{COPY}, \texttt{CMD} itt fut
\item Konténerben \texttt{docker exec} is ide lép be
\end{itemize}
\end{block}
\begin{alertblock}{Jó gyakorlat}
Használj dedikált könyvtárat: \texttt{/app} vagy \texttt{/usr/src/app}
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{COPY -- Fájl másolás}
\begin{block}{Egy és több fájl másolása}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Egy fájl
COPY package.json ./
# Több fájl
COPY file1.txt file2.txt ./
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{COPY -- Mappák és teljes tartalom}
\begin{block}{Mappák másolása}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Mappa teljes tartalma
COPY src/ ./src/
# Minden a build context-ből
COPY . .
\end{lstlisting}
\end{block}
\begin{exampleblock}{Jellemzők}
\begin{itemize}
\item Egyszerű fájl és mappa másolás
\item Látható és érthető
\item \textbf{Ajánlott használni!}
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{ADD -- Speciális másolás}
\begin{block}{ADD utasítás}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Automatikus kicsomagolás
ADD archive.tar.gz /app/
# URL letöltés (nem ajánlott)
ADD http://example.com/file ./
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{ADD vs COPY -- Összehasonlítás}
\begin{block}{ADD vs COPY}
\begin{itemize}
\item ADD: automatikus kicsomagolás, URL támogatás
\item COPY: egyszerű, explicit, ajánlott
\end{itemize}
\end{block}
\begin{alertblock}{Best Practice}
Használj \texttt{COPY}-t, kivéve ha kifejezetten kell az \texttt{ADD} extra funkciója!
\end{alertblock}
\begin{exampleblock}{URL-hez}
URL letöltéshez jobb RUN + curl/wget használata
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{RUN -- Csomagok telepítése}
\begin{block}{Csomag telepítés}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Csomag telepítés
RUN apt-get update && apt-get install -y curl
# NPM függőségek
RUN npm install
# Python csomagok
RUN pip install -r requirements.txt
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{RUN -- Több parancs kombinálása}
\begin{block}{Több parancs egyetlen RUN-ban}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Több parancs (shell form)
RUN apt-get update && \
apt-get install -y git curl && \
apt-get clean
\end{lstlisting}
\end{block}
\begin{alertblock}{Fontos}
Minden \texttt{RUN} egy új \textbf{réteg} (layer) az image-ben.\\
Kombináld parancsokat \texttt{\&\&}-del a rétegek csökkentéséhez!
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{ENV -- Környezeti változók}
\begin{block}{Környezeti változók beállítása}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Egy változó
ENV NODE_ENV=production
# Több változó
ENV NODE_ENV=production \
PORT=3000 \
DB_HOST=localhost
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{ENV -- Használat utasításokban}
\begin{block}{Használat későbbi utasításokban}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
ENV APP_HOME=/usr/src/app
WORKDIR $APP_HOME
\end{lstlisting}
\end{block}
\begin{exampleblock}{Mikor érhető el?}
\begin{itemize}
\item Build időben: későbbi \texttt{RUN} parancsokban
\item Runtime-ban: futó konténerben
\item Felülírható: \texttt{docker run -e NODE\_ENV=dev}
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{EXPOSE -- Port deklaráció}
\begin{block}{Dokumentálja, melyik porton fut az app}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# HTTP port
EXPOSE 3000
# Több port
EXPOSE 3000 5000 8080
# UDP port
EXPOSE 53/udp
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{EXPOSE -- Magyarázat}
\begin{alertblock}{Fontos megértés}
\texttt{EXPOSE} \textbf{NEM} nyitja meg a portot!
\end{alertblock}
\begin{block}{Funkció}
\begin{itemize}
\item Csak \textbf{dokumentáció}, hogy melyik porton fut az alkalmazás
\item Tényleges mapping: \texttt{docker run -p 3000:3000}
\end{itemize}
\end{block}
\begin{exampleblock}{Hasznos}
Docker Compose és orchestration eszközök használják ezt az információt.
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{CMD -- Alapértelmezett parancs}
\begin{block}{CMD utasítás}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Shell form
CMD npm start
# Exec form (ajánlott)
CMD ["npm", "start"]
# Paraméterekkel
CMD ["node", "server.js"]
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{CMD -- Felülírás futtatáskor}
\begin{exampleblock}{Felülírás futtatáskor}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Alapértelmezett CMD fut
docker run my-app
# CMD felülírása
docker run my-app npm test
\end{lstlisting}
\end{exampleblock}
\begin{exampleblock}{Tippek}
\begin{itemize}
\item Exec form ajánlott: \texttt{["cmd", "param"]}
\item Shell form: stringek közvetlenül
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{ENTRYPOINT -- Fő végrehajtható}
\begin{block}{ENTRYPOINT utasítás}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Exec form (ajánlott)
ENTRYPOINT ["node"]
# CMD paramétereket ad hozzá
CMD ["server.js"]
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{ENTRYPOINT -- Paraméter változtatás}
\begin{exampleblock}{Paraméter változtatás}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# server.js fut (CMD alapértelmezett)
docker run my-app
# app.js fut (CMD felülírva, de node marad)
docker run my-app app.js
\end{lstlisting}
\end{exampleblock}
\begin{alertblock}{Best Practice}
Használj \texttt{CMD}-t egyszerű esetekben, \texttt{ENTRYPOINT + CMD}-t összetettebb esetekben.
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Teljes Node.js példa -- Dockerfile}
\begin{exampleblock}{Dockerfile Node.js alkalmazáshoz}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Alap image
FROM node:18-alpine
# Munkakönyvtár
WORKDIR /usr/src/app
# Függőségek másolása és telepítése
COPY package*.json ./
RUN npm ci --only=production
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Teljes Node.js példa -- Kód és indítás}
\begin{exampleblock}{Alkalmazás és futtatás}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Alkalmazás kódjának másolása
COPY . .
# Környezeti változó
ENV NODE_ENV=production
# Port deklarálás
EXPOSE 3000
# Indítási parancs
CMD ["node", "server.js"]
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Layer caching -- Probléma}
\begin{alertblock}{Mi a probléma?}
Minden Dockerfile sor egy \textbf{layer} (réteg).\\
Ha egy layer változik, az összes utána következő újraépül!
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Layer caching -- Nem hatékony megoldás}
\begin{block}{Nem hatékony megközelítés}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
FROM node:18
WORKDIR /app
# Minden változásra újra
COPY . .
RUN npm install
CMD ["npm", "start"]
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{Layer caching -- Következmény}
\begin{alertblock}{Következmény}
Bármilyen kód módosítás után az \texttt{npm install} is újrafut,\\
pedig a \texttt{package.json} nem változott!
\end{alertblock}
\begin{exampleblock}{Példa}
\begin{itemize}
\item 1 sor kód változik a src/app.js-ben
\item \texttt{COPY . .} layer változik
\item \texttt{RUN npm install} újrafut (pár perc!)
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Layer caching -- Optimalizálás}
\begin{exampleblock}{Jó megoldás}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
FROM node:18
WORKDIR /app
# Cache-elhető - csak ha package.json változik
COPY package*.json ./
RUN npm install
# Gyakran változik - de nem érinti a fenti layer-eket
COPY . .
CMD ["npm", "start"]
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Layer caching -- Alapelvek}
\begin{block}{Alapelv}
\textbf{Ritkábban változó dolgok előre, gyakran változók hátra!}
\end{block}
\begin{exampleblock}{Példa szervezet}
\begin{enumerate}
\item FROM -- alap image (soha nem változik)
\item Függőségek (package.json) $\rightarrow$ ritkán változnak
\item Forráskód $\rightarrow$ gyakran változik
\end{enumerate}
\end{exampleblock}
\end{frame}
\begin{frame}{Layer caching -- Eredmény}
\begin{alertblock}{Eredmény}
Kód változtatás $\Rightarrow$ csak COPY és CMD layer újraépül\\
npm install cache-elve marad!
\end{alertblock}
\end{frame}
\begin{frame}{.dockerignore -- Mi ez?}
\begin{block}{Mi ez és miért fontos?}
Megadja, mely fájlokat \textbf{NE} másolja be az image-be.\\
Hasonló a \texttt{.gitignore}-hoz.
\end{block}
\begin{alertblock}{Előnyök}
\begin{itemize}
\item Kisebb image méret
\item Gyorsabb build folyamat
\item Biztonságosabb (nincs .env, .git)
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{.dockerignore -- Node.js példa}
\begin{exampleblock}{Node.js projekt .dockerignore fájlja}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Node.js
node_modules
npm-debug.log
# Git
.git
.gitignore
# Fejlesztői fájlok
*.md
.env
.env.local
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{.dockerignore -- További kizárások}
\begin{exampleblock}{Teszt és IDE fájlok}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Teszt fájlok
*.test.js
# IDE
.vscode
.idea
# Logs
logs
*.log
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Multi-stage build -- Alapok}
\begin{block}{Mi a multi-stage build?}
\begin{itemize}
\item Több \texttt{FROM} utasítás egy Dockerfile-ban
\item Különböző szakaszok különböző célokra
\item Végső image: csak a szükséges fájlok
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Multi-stage build -- Előnyök}
\begin{exampleblock}{Miért jó?}
\begin{itemize}
\item Build eszközök nem kerülnek a végső image-be
\item Fejlesztői függőségek nem kellenek production-ben
\item Kisebb méret = gyorsabb deploy, kevesebb tárhely
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Multi-stage build -- Méretösszehasonlítás}
\begin{exampleblock}{Méretösszehasonlítás}
\begin{itemize}
\item Egy-stage build: \textasciitilde500MB (Node.js + dev deps + TS compiler)
\item Multi-stage build: \textasciitilde150MB (csak Node.js + prod deps + JS)
\item Méretcsökkenés: 70\%!
\end{itemize}
\end{exampleblock}
\begin{alertblock}{Példa}
TypeScript: \texttt{tsc} fordítás és csak a JS megy a végső image-be
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Multi-stage build -- Builder stage}
\begin{exampleblock}{Stage 1: Build}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
FROM node:18 AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Multi-stage build -- Production stage}
\begin{exampleblock}{Stage 2: Production}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/server.js"]
\end{lstlisting}
\end{exampleblock}
\begin{block}{Kulcs elemek}
\begin{itemize}
\item \texttt{AS builder}: Első stage elnevezése
\item \texttt{--from=builder}: Fájl másolás előző stage-ből
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{Multi-stage build -- Go példa}
\begin{exampleblock}{Go alkalmazás -- drasztikus méretcsökkentés}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Stage 1: Build
FROM golang:1.20 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o main .
# Stage 2: Production (scratch = üres image!)
FROM scratch
COPY --from=builder /app/main /main
EXPOSE 8080
ENTRYPOINT ["/main"]
\end{lstlisting}
\end{exampleblock}
\begin{alertblock}{Eredmény}
Golang image: \textasciitilde800MB $\Rightarrow$ Végső image: \textasciitilde10MB
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{ARG -- Build-time változók}
\begin{block}{ARG vs ENV}
\begin{itemize}
\item \texttt{ARG}: Csak build közben érhető el
\item \texttt{ENV}: Build és runtime is
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{ARG -- Használat}
\begin{exampleblock}{ARG használata}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Alapértelmezett érték
ARG NODE_VERSION=18
FROM node:${NODE_VERSION}
ARG VERSION=1.0.0
# Convert to ENV (ha runtime kell)
ENV APP_VERSION=${VERSION}
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{ARG -- Build argument átadása}
\begin{exampleblock}{Parancssorból}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Build argument átadása
docker build --build-arg NODE_VERSION=20 \
--build-arg VERSION=2.0 .
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{USER -- Biztonság}
\begin{alertblock}{Biztonság}
\textbf{Soha ne futtass produkciós konténert root-ként!}
\end{alertblock}
\begin{block}{Miért veszélyes a root?}
\begin{itemize}
\item Ha a konténer kompromittálódik, a támadó teljes hozzáféréssel rendelkezik
\item Biztonsági rések kihasználása könnyebb
\item Host rendszer veszélyeztetett lehet
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{USER -- Implementáció}
\begin{block}{Root user elkerülése}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
# Nem privilegizált user létrehozása
RUN addgroup -S appgroup && \
adduser -S appuser -G appgroup
# Fájlok tulajdonjogának változtatása
RUN chown -R appuser:appgroup /app
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{USER -- Váltás és használat}
\begin{block}{User váltás}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# User váltás
USER appuser
COPY --chown=appuser:appgroup . .
CMD ["node", "server.js"]
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{HEALTHCHECK -- Állapot ellenőrzés}
\begin{block}{Konténer egészség ellenőrzés}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
HEALTHCHECK --interval=30s --timeout=3s \
--start-period=5s --retries=3 \
CMD node healthcheck.js
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{HEALTHCHECK -- HTTP endpoint}
\begin{exampleblock}{HTTP endpoint ellenőrzés}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 \
--spider http://localhost:3000/health || exit 1
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{HEALTHCHECK -- Paraméterek}
\begin{block}{Paraméterek magyarázata}
\begin{itemize}
\item \texttt{--interval=30s}: Ellenőrzések közötti idő
\item \texttt{--timeout=3s}: Max várakozás egy ellenőrzésre
\item \texttt{--start-period=5s}: Kezdeti várakozási idő
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{HEALTHCHECK -- Retries}
\begin{block}{Újrapróbálkozás}
\begin{itemize}
\item \texttt{--retries=3}: Hányszor próbálja újra hiba esetén
\item 3 sikertelen után unhealthy státusz
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{Build parancsok -- Alapok}
\begin{block}{docker build alapok}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Alap build
docker build -t my-app:latest .
# Specifikus Dockerfile
docker build -f Dockerfile.prod -t my-app:prod .
# Build argument
docker build --build-arg NODE_ENV=production \
-t my-app .
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Build parancsok -- Haladó}
\begin{block}{Haladó build opciók}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# No cache (teljes újraépítés)
docker build --no-cache -t my-app .
# Több tag egyszerre
docker build -t my-app:latest -t my-app:1.0.0 .
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{Best Practices -- Verzió és méret}
\begin{exampleblock}{Követendő gyakorlatok}
\begin{itemize}
\item Használj \textbf{specifikus verziókat} (\texttt{node:18.16} nem \texttt{latest})
\item \textbf{Alpine image}: kisebb méret
\item \textbf{.dockerignore}: felesleges fájlok kizárása
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Best Practices -- Cache és struktúra}
\begin{exampleblock}{Követendő gyakorlatok}
\begin{itemize}
\item \textbf{Layer cache}: függőségek előre, kód hátra
\item \textbf{Multi-stage build}: kisebb production image
\item \textbf{Egy konténer = egy folyamat} (ne futtass többet)
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Best Practices -- Biztonság}
\begin{exampleblock}{Követendő gyakorlatok}
\begin{itemize}
\item \textbf{USER}: ne root userként futtass
\item \textbf{HEALTHCHECK}: alkalmazás monitorozás
\item RUN utasítások \textbf{kombinálása} (\&\&)
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Anti-patterns -- Biztonsági hibák}
\begin{alertblock}{Biztonsági problémák}
\begin{itemize}
\item Jelszavak, API kulcsok a Dockerfile-ban
\item Root user production-ben
\item \texttt{sudo} használata Dockerfile-ban
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Anti-patterns -- Alap image hibák}
\begin{alertblock}{Alap image hibák}
\begin{itemize}
\item \texttt{FROM ubuntu} és minden manuális telepítés
\item \texttt{latest} tag production-ben
\end{itemize}
\end{alertblock}
\begin{exampleblock}{Megoldás}
Használj official image-et (pl. \texttt{node:18-alpine})
\end{exampleblock}
\end{frame}
\begin{frame}{Anti-patterns -- Cache hibák}
\begin{alertblock}{Cache és build context hibák}
\begin{itemize}
\item \texttt{COPY . .} a Dockerfile elejére (cache miss)
\item \texttt{RUN apt-get update} külön sorban
\item Nagy fájlok (logs, cache) az image-ben
\end{itemize}
\end{alertblock}
\begin{exampleblock}{Megoldások}
\begin{itemize}
\item Függőségek előbb, kód később
\item RUN parancsok összevonása
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Production Dockerfile -- Builder}
\begin{exampleblock}{Stage 1: Builder}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
FROM node:18-alpine AS builder
WORKDIR /app
# Függőségek telepítése
COPY package*.json ./
RUN npm ci
# Alkalmazás fordítása
COPY . .
RUN npm run build && npm prune --production
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Production Dockerfile -- Builder magyarázat}
\begin{block}{Mit csinál?}
\begin{itemize}
\item Teljes node\_modules telepítés (dev + prod)
\item TypeScript/Build folyamat futtatása
\item Production függőségek megtartása
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{Production Dockerfile -- Alap}
\begin{exampleblock}{Stage 2: Production alap}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
FROM node:18-alpine
WORKDIR /app
# Biztonsági user létrehozása
RUN addgroup -S appgroup && \
adduser -S appuser -G appgroup
# Csak a szükséges fájlok másolása
COPY package*.json ./
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Production Dockerfile -- Indítás}
\begin{exampleblock}{Stage 2: Konfiguráció és indítás}
\begin{lstlisting}[language=Docker,basicstyle=\scriptsize\ttfamily]
# Tulajdonjogok beállítása
RUN chown -R appuser:appgroup /app
USER appuser
# Port és healthcheck
EXPOSE 3000
HEALTHCHECK --interval=30s --timeout=3s \
CMD node healthcheck.js || exit 1
# Indítás
ENV NODE_ENV=production
CMD ["node", "dist/server.js"]
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Összefoglalás -- Főbb utasítások}
\begin{block}{Dockerfile = Image recept}
\begin{itemize}
\item \texttt{FROM} -- Alap image
\item \texttt{WORKDIR} -- Munka könyvtár
\item \texttt{COPY} -- Fájlok másolása
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Összefoglalás -- Futtatás}
\begin{block}{Parancsok és indítás}
\begin{itemize}
\item \texttt{RUN} -- Parancsok futtatása
\item \texttt{ENV} -- Környezeti változók
\item \texttt{EXPOSE} -- Port deklarálás
\end{itemize}
\end{block}
\begin{block}{Indítás}
\begin{itemize}
\item \texttt{CMD} -- Indítási parancs
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Összefoglalás -- Optimalizálás}
\begin{block}{Cache és méret optimalizálás}
\begin{itemize}
\item \textbf{Layer caching:} függőségek előre, kód hátra
\item \textbf{Multi-stage build:} sokkal kisebb production image
\item \textbf{.dockerignore:} tiszta build context
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Összefoglalás -- Biztonság}
\begin{block}{Biztonság és monitorozás}
\begin{itemize}
\item \textbf{Alpine:} kompakt alap image, kisebb méret
\item \textbf{USER:} ne root-ként futtass (biztonság)
\item \textbf{HEALTHCHECK:} alkalmazás állapot monitorozás
\end{itemize}
\end{block}
\begin{alertblock}{Következő lépés}
Docker Image-ek kezelése, majd Docker Compose
\end{alertblock}
\end{frame}