This commit is contained in:
magdo
2026-02-17 21:17:42 +01:00
parent d90a6ed735
commit af57733506
17 changed files with 4194 additions and 59 deletions
Binary file not shown.
+21 -5
View File
@@ -18,7 +18,7 @@
\end{frame} \end{frame}
\begin{frame}[fragile]{Példa séma} \begin{frame}[fragile]{Példa séma}
\begin{block}{schema.prisma} \begin{block}{schema.prisma - Product}
\begin{lstlisting}[language=JavaScript] \begin{lstlisting}[language=JavaScript]
model Product { model Product {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
@@ -30,6 +30,13 @@ model Product {
references: [id]) references: [id])
createdAt DateTime @default(now()) createdAt DateTime @default(now())
} }
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Példa séma (folyt.)}
\begin{block}{schema.prisma - Category}
\begin{lstlisting}[language=JavaScript]
model Category { model Category {
id Int @id @default(autoincrement()) id Int @id @default(autoincrement())
name String name String
@@ -47,7 +54,13 @@ async function countProducts() {
const count = await prisma.product.count(); const count = await prisma.product.count();
console.log(`Összes termék: ${count}`); console.log(`Összes termék: ${count}`);
} }
// Szűrt számlálás \end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Count - Számlálás (szűréssel)}
\begin{block}{Szűrt számlálás}
\begin{lstlisting}[language=JavaScript]
async function countExpensiveProducts() { async function countExpensiveProducts() {
const count = await prisma.product.count({ const count = await prisma.product.count({
where: { where: {
@@ -69,14 +82,17 @@ async function getProductStats() {
const stats = await prisma.product.aggregate({ const stats = await prisma.product.aggregate({
_count: true, _count: true,
_avg: {price: true}, _avg: {price: true},
_sum: {stock: true}, _sum: {stock: true},
_min: {price: true}, _min: {price: true},
_max: {price: true} _max: {price: true}
}); });
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Aggregate - Alapok (folyt.)}
\begin{block}{Egyszerű aggregáció}
\begin{lstlisting}[language=JavaScript]
console.log(stats); console.log(stats);
} }
\end{lstlisting} \end{lstlisting}
Binary file not shown.
+3 -2
View File
@@ -4,8 +4,8 @@
% Automatikus frame törés engedélyezése túl hosszú tartalomnál % Automatikus frame törés engedélyezése túl hosszú tartalomnál
\setbeamertemplate{frametitle continuation}[from second][\insertcontinuationcountroman] \setbeamertemplate{frametitle continuation}[from second][\insertcontinuationcountroman]
\title[Webtechnológia és webalkalmazás-fejlesztés - Rest API]{Webtechnológia és webalkalmazás-fejlesztés - Rest API} \title[Webtechnológia és webalkalmazás-fejlesztés - Databse]{Webtechnológia és webalkalmazás-fejlesztés - Adatbázis}
\subtitle{Rest API} \subtitle{Adatbázis}
\begin{document} \begin{document}
@@ -18,6 +18,7 @@
\input{orm.tex} \input{orm.tex}
\input{prisma.tex} \input{prisma.tex}
\input{database_connection.tex} \input{database_connection.tex}
\input{replication.tex}
\input{aggregates.tex} \input{aggregates.tex}
\input{repository.tex} \input{repository.tex}
\input{dto.tex} \input{dto.tex}
+53 -39
View File
@@ -11,56 +11,70 @@
\end{frame} \end{frame}
\begin{frame}{Kapcsolati paraméterek} \begin{frame}{Kapcsolati paraméterek}
\begin{block}{Alapvető beállítások}
\begin{itemize} \begin{itemize}
\item Host, port, adatbázis név \item \textbf{Host:} Szerver címe (localhost, IP, domain)
\item Felhasználónév, jelszó \item \textbf{Port:} Adatbázis portja\\
\item SSL/TLS beállítások (PostgreSQL: 5432, MySQL: 3306, MongoDB: 27017)
\item Timeout és pool méretek \item \textbf{Database:} Adatbázis neve
\item \textbf{User/Password:} Hitelesítési adatok
\item \textbf{SSL/TLS:} Titkosított kapcsolat (production kötelező!)
\end{itemize} \end{itemize}
\end{block}
\end{frame}
\begin{exampleblock}{Connection string példa} \begin{frame}[fragile]{Connection String formátumok}
\texttt{postgres://user:pass@localhost:5432/appdb} \begin{exampleblock}{PostgreSQL}
\begin{lstlisting}[language=bash]
postgresql://user:password@localhost:5432/mydb?schema=public
\end{lstlisting}
\end{exampleblock}
\begin{exampleblock}{MySQL}
\begin{lstlisting}[language=bash]
mysql://user:password@localhost:3306/mydb
\end{lstlisting}
\end{exampleblock}
\begin{exampleblock}{MongoDB}
\begin{lstlisting}[language=bash]
mongodb://user:password@localhost:27017/mydb
\end{lstlisting}
\end{exampleblock} \end{exampleblock}
\end{frame} \end{frame}
\begin{frame}{Connection pooling}
\begin{block}{Miért kell?}
\begin{itemize}
\item A kapcsolat fel- és leépítése drága
\item Pool újrahasznosítja a kapcsolatokat
\item Stabilabb teljesítmény csúcsterhelésen
\end{itemize}
\end{block}
\begin{alertblock}{Beállítási irányelv}
Túl kicsi pool lassít, túl nagy pool túlterheli a szervert.
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Konfiguráció alkalmazásban} \begin{frame}[fragile]{Konfiguráció alkalmazásban}
\begin{block}{Környezeti változók} \begin{block}{Környezeti változók (.env fájl)}
\begin{lstlisting}[language=bash] \begin{lstlisting}[language=bash]
DATABASE_URL="postgres://user:pass@localhost:5432/appdb" # Alapvető kapcsolat
DATABASE_URL="postgresql://user:pass@localhost:5432/appdb"
\end{lstlisting} \end{lstlisting}
\end{block} \end{block}
\begin{block}{Függőség kezelés} \begin{alertblock}{SOHA ne commitold a .env fájlt!}
A kapcsolat beállításait ne kódold a forráskódba, használj env fájlt. Használj .env.example sablont, a valódi értékeket .gitignore-ba!
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Prisma specifikus konfiguráció}
\begin{block}{schema.prisma fájl}
\begin{lstlisting}[language=JavaScript]
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
\end{lstlisting}
\end{block}
\begin{block}{Connection URL extended példa}
\begin{lstlisting}[language=bash]
DATABASE_URL="postgresql://user:pass@localhost:5432/mydb?schema=public\
&connection_limit=10&pool_timeout=20"
\end{lstlisting}
\end{block} \end{block}
\end{frame} \end{frame}
\begin{frame}{Prisma megjegyzés}
\begin{itemize}
\item Prisma-val a kapcsolat a \texttt{DATABASE\_URL}-on keresztül jön létre
\item A koncepció ugyanaz, csak a keretrendszer kezeli a részleteket
\item Ebben a részben nem feltétel a Prisma használata
\end{itemize}
\end{frame}
\begin{frame}{Hibakezelés és stabilitás}
\begin{itemize}
\item Használj újracsatlakozást ideiglenes hibákra
\item Naplózd a kapcsolat hibákat, de ne írj ki jelszavakat
\item Tranzakcióknál kezeld a visszagörgetést
\end{itemize}
\end{frame}
+52 -8
View File
@@ -4,14 +4,16 @@
\begin{block}{Data Transfer Object} \begin{block}{Data Transfer Object}
\begin{itemize} \begin{itemize}
\item Adatok szállítására szolgáló objektum \item Adatok szállítására szolgáló objektum
\item Elválasztja az adatbázis sémát a kliens felőli interfésztől \item Elválasztja az adatbázis sémát\\
a kliens felőli interfésztől
\item Kontroll az átadott adatok felett \item Kontroll az átadott adatok felett
\item Validáció és transzformáció helye \item Validáció és transzformáció helye
\end{itemize} \end{itemize}
\end{block} \end{block}
\begin{exampleblock}{Példa} \begin{exampleblock}{Példa}
Felhasználó entitás tartalmaz jelszó hash-t, de a DTO nem adja ki. Felhasználó entitás tartalmaz jelszó hash-t,\\
de a DTO nem adja ki.
\end{exampleblock} \end{exampleblock}
\end{frame} \end{frame}
@@ -116,7 +118,7 @@ class UserResponseDTO {
\end{frame} \end{frame}
\begin{frame}[fragile]{DTO használata service-ben} \begin{frame}[fragile]{DTO használata service-ben}
\begin{block}{UserService példa} \begin{block}{UserService példa (1)}
\begin{lstlisting}[language=JavaScript] \begin{lstlisting}[language=JavaScript]
const prisma = require('./prisma'); const prisma = require('./prisma');
const bcrypt = require('bcrypt'); const bcrypt = require('bcrypt');
@@ -126,6 +128,13 @@ class UserService {
const hashedPassword = await bcrypt.hash( const hashedPassword = await bcrypt.hash(
createUserDTO.password, 10 createUserDTO.password, 10
); // Jelszó hash-elés ); // Jelszó hash-elés
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{DTO használata service-ben (folyt.)}
\begin{block}{UserService példa (2)}
\begin{lstlisting}[language=JavaScript]
const user = await prisma.user.create({ const user = await prisma.user.create({
data: { data: {
email: createUserDTO.email, email: createUserDTO.email,
@@ -138,7 +147,7 @@ class UserService {
\end{frame} \end{frame}
\begin{frame}[fragile]{DTO használata service-ben (folyt.)} \begin{frame}[fragile]{DTO használata service-ben (folyt.)}
\begin{block}{UserService példa folytatás} \begin{block}{UserService példa (3)}
\begin{lstlisting}[language=JavaScript] \begin{lstlisting}[language=JavaScript]
// DTO-vá alakítás visszaadás előtt // DTO-vá alakítás visszaadás előtt
return UserResponseDTO.fromPrismaUser(user); return UserResponseDTO.fromPrismaUser(user);
@@ -147,6 +156,13 @@ class UserService {
const users = await prisma.user.findMany(); const users = await prisma.user.findMany();
return UserResponseDTO.fromManyPrismaUsers(users); return UserResponseDTO.fromManyPrismaUsers(users);
} }
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{DTO használata service-ben (folyt.)}
\begin{block}{UserService példa (4)}
\begin{lstlisting}[language=JavaScript]
async getUserById(id) { async getUserById(id) {
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
where: { id } where: { id }
@@ -160,7 +176,7 @@ class UserService {
\end{frame} \end{frame}
\begin{frame}[fragile]{Express integráció DTO-val} \begin{frame}[fragile]{Express integráció DTO-val}
\begin{block}{REST endpoint} \begin{block}{REST endpoint (POST)}
\begin{lstlisting}[language=JavaScript] \begin{lstlisting}[language=JavaScript]
const express = require('express'); const express = require('express');
const userService = new UserService(); const userService = new UserService();
@@ -174,6 +190,13 @@ app.post('/api/users', async (req, res) => {
res.status(400).json({ error: error.message }); res.status(400).json({ error: error.message });
} }
}); });
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Express integráció DTO-val (folyt.)}
\begin{block}{REST endpoint (GET)}
\begin{lstlisting}[language=JavaScript]
app.get('/api/users', async (req, res) => { app.get('/api/users', async (req, res) => {
const usersDTO = await userService.getAllUsers(); const usersDTO = await userService.getAllUsers();
res.json(usersDTO); res.json(usersDTO);
@@ -364,7 +387,7 @@ class UserFilterDTO {
\end{frame} \end{frame}
\begin{frame}[fragile]{Szűrési DTO használata} \begin{frame}[fragile]{Szűrési DTO használata}
\begin{block}{Express endpoint szűréssel} \begin{block}{Express endpoint szűréssel (1)}
\begin{lstlisting}[language=JavaScript] \begin{lstlisting}[language=JavaScript]
app.get('/api/users', async (req, res) => { app.get('/api/users', async (req, res) => {
const filterDTO = new UserFilterDTO(req.query); const filterDTO = new UserFilterDTO(req.query);
@@ -374,6 +397,13 @@ app.get('/api/users', async (req, res) => {
skip: (filterDTO.page - 1) * filterDTO.pageSize, skip: (filterDTO.page - 1) * filterDTO.pageSize,
take: filterDTO.pageSize take: filterDTO.pageSize
}); });
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Szűrési DTO használata (folyt.)}
\begin{block}{Express endpoint szűréssel (2)}
\begin{lstlisting}[language=JavaScript]
const total = await prisma.user.count({ where }); const total = await prisma.user.count({ where });
const result = new PaginatedResponseDTO( const result = new PaginatedResponseDTO(
UserResponseDTO.fromManyPrismaUsers(users), UserResponseDTO.fromManyPrismaUsers(users),
@@ -386,7 +416,7 @@ app.get('/api/users', async (req, res) => {
\end{frame} \end{frame}
\begin{frame}[fragile]{Mapper függvények} \begin{frame}[fragile]{Mapper függvények}
\begin{block}{Alternatív megközelítés - Pure functions // dto/user.mapper.js} \begin{block}{Alternatív megközelítés (1)}
\begin{lstlisting}[language=JavaScript] \begin{lstlisting}[language=JavaScript]
function toUserResponseDTO(user) { function toUserResponseDTO(user) {
return { return {
@@ -398,6 +428,13 @@ function toUserResponseDTO(user) {
function toUserResponseDTOs(users) { function toUserResponseDTOs(users) {
return users.map(toUserResponseDTO); return users.map(toUserResponseDTO);
} }
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Mapper függvények (folyt.)}
\begin{block}{Alternatív megközelítés (2)}
\begin{lstlisting}[language=JavaScript]
module.exports = { module.exports = {
toUserResponseDTO, toUserResponseDTO,
toUserResponseDTOs toUserResponseDTOs
@@ -407,7 +444,7 @@ module.exports = {
\end{frame} \end{frame}
\begin{frame}[fragile]{Mapper használata} \begin{frame}[fragile]{Mapper használata}
\begin{block}{Service-ben} \begin{block}{Service-ben (1)}
\begin{lstlisting}[language=JavaScript] \begin{lstlisting}[language=JavaScript]
const { toUserResponseDTO, toUserResponseDTOs } const { toUserResponseDTO, toUserResponseDTOs }
= require('./dto/user.mapper'); = require('./dto/user.mapper');
@@ -416,6 +453,13 @@ class UserService {
const users = await prisma.user.findMany(); const users = await prisma.user.findMany();
return toUserResponseDTOs(users); return toUserResponseDTOs(users);
} }
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Mapper használata (folyt.)}
\begin{block}{Service-ben (2)}
\begin{lstlisting}[language=JavaScript]
async getUserById(id) { async getUserById(id) {
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
where: { id } where: { id }
+136
View File
@@ -0,0 +1,136 @@
\section{Adatbázis replikáció}
\begin{frame}{Mi az adatbázis replikáció?}
\begin{block}{Definíció}
Az adatok \textbf{több adatbázis példány között} vannak másolva annak érdekében,
hogy növekedjen a \textbf{rendelkezésre állás}, \textbf{skálázhatóság} és
\textbf{hibatűrés}.
\end{block}
\begin{itemize}
\item PrimaryReplica (masterslave) felépítés a leggyakoribb
\item A replikáció lehet \textbf{szinkron} vagy \textbf{aszinkron}
\item Read-heavy alkalmazásoknál különösen hasznos
\end{itemize}
\end{frame}
\begin{frame}{Miért jó a replikáció?}
\begin{block}{Főbb előnyök}
\begin{itemize}
\item \textbf{Nagyobb rendelkezésre állás}: hiba esetén átváltás (failover)
\item \textbf{Skálázás olvasásra}: több replica olvasási terhelést visz el
\item \textbf{Biztonsági másolat}: adatvesztés kockázatának csökkentése
\item \textbf{Földrajzi közelség}: alacsonyabb késleltetés regionális replikákkal
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Replikációs topológiák}
\begin{itemize}
\item \textbf{PrimaryReplica}: egy írható csomópont, több olvasó
\item \textbf{Multi-primary}: több írható csomópont (konfliktuskezelés szükséges)
\item \textbf{Chain/Cascade}: láncolt replikák nagy földrajzi területre
\end{itemize}
\begin{alertblock}{Gyakorlatban}
A legtöbb backend szolgáltatásnál a PrimaryReplica modell az alapértelmezett.
\end{alertblock}
\end{frame}
\begin{frame}{Szinkron replikáció}
\begin{block}{Hogyan működik?}
\begin{itemize}
\item Az írás \textbf{csak akkor sikeres}, ha a replika is visszaigazolta
\item Erős \textbf{konzisztencia} (nincs adatvesztés írás után)
\item A primary \textbf{vár} a replikákra → nagyobb latency
\end{itemize}
\end{block}
\begin{exampleblock}{Mikor jó?}
Pénzügyi, tranzakciós rendszerek, ahol az adatvesztés nem elfogadható.
\end{exampleblock}
\end{frame}
\begin{frame}{Szinkron replikáció előnyök / hátrányok}
\begin{columns}
\begin{column}{0.48\textwidth}
\begin{block}{Előnyök}
\begin{itemize}
\item Erős konzisztencia
\item Minimális adatvesztés
\item Egyszerűbb olvasási modell
\end{itemize}
\end{block}
\end{column}
\begin{column}{0.48\textwidth}
\begin{alertblock}{Hátrányok}
\begin{itemize}
\item Nagyobb válaszidő írásnál
\item Érzékenyebb hálózati késleltetésre
\item Replikák kiesése lassítja az írást
\end{itemize}
\end{alertblock}
\end{column}
\end{columns}
\end{frame}
\begin{frame}{Aszinkron replikáció}
\begin{block}{Hogyan működik?}
\begin{itemize}
\item Az írás \textbf{azonnal sikeres}, a replika később frissül
\item Jobb \textbf{teljesítmény} és alacsonyabb latency
\item \textbf{Időbeli eltérés} lehetséges (eventual consistency)
\end{itemize}
\end{block}
\begin{exampleblock}{Mikor jó?}
Nagy forgalmú rendszerek, ahol az olvasási skálázás fontosabb, mint a tökéletes
konzisztencia (pl. hírportál, analytics).
\end{exampleblock}
\end{frame}
\begin{frame}{Aszinkron replikáció előnyök / hátrányok}
\begin{columns}
\begin{column}{0.48\textwidth}
\begin{block}{Előnyök}
\begin{itemize}
\item Alacsonyabb írási késleltetés
\item Jobb skálázhatóság
\item Replikák nem lassítják az írást
\end{itemize}
\end{block}
\end{column}
\begin{column}{0.48\textwidth}
\begin{alertblock}{Hátrányok}
\begin{itemize}
\item Ideiglenes inkonzisztencia
\item Failover esetén adatvesztés kockázata
\item Komplexebb olvasási logika
\end{itemize}
\end{alertblock}
\end{column}
\end{columns}
\end{frame}
\begin{frame}{Szinkron vs. aszinkron döntési szempontok}
\begin{itemize}
\item \textbf{Konzisztencia igény}: kritikus adatok → szinkron
\item \textbf{Teljesítmény igény}: magas throughput → aszinkron
\item \textbf{Hálózat megbízhatósága}: nagy latency → aszinkron
\item \textbf{Üzleti kockázat}: adatvesztés megengedett? → aszinkron
\end{itemize}
\begin{alertblock}{Ökölszabály}
Ha az írások számítanak jobban, válaszd a szinkront. Ha az olvasási skálázás
és az alacsony latency fontos, válaszd az aszinkront.
\end{alertblock}
\end{frame}
\begin{frame}{Hogyan használjuk a gyakorlatban?}
\begin{block}{Tipikus architektúra}
\begin{itemize}
\item \textbf{Primary} kezeli az írásokat
\item \textbf{Replica} kiszolgálja az olvasásokat
\item \textbf{Load balancer} irányítja az olvasást a replikákhoz
\end{itemize}
\end{block}
\begin{exampleblock}{ORM/Prisma oldal}
A legtöbb ORM-ben (így Prismában is) külön connection stringet használsz az
író és az olvasó adatbázisokhoz, vagy read-replica routert konfigurálsz.
\end{exampleblock}
\end{frame}
Binary file not shown.
+60
View File
@@ -6,6 +6,16 @@
\usepackage{tikz} \usepackage{tikz}
\usetikzlibrary{positioning} \usetikzlibrary{positioning}
\usepackage{fancyvrb} \usepackage{fancyvrb}
\usepackage{amssymb}
\usepackage{pifont}
\usepackage{newunicodechar}
% Unicode szimbólumok definiálása
\newcommand{\cmark}{\ding{51}} % ✓ check mark
\newcommand{\xmark}{\ding{55}} % ✗ ballot x
\newunicodechar{✓}{\cmark}
\newunicodechar{✗}{\xmark}
\newunicodechar{❌}{\textcolor{red}{\xmark}}
% Globális verbatim beállítás - tiny betűméret minden verbatim blokkhoz % Globális verbatim beállítás - tiny betűméret minden verbatim blokkhoz
\fvset{fontsize=\tiny} \fvset{fontsize=\tiny}
@@ -26,6 +36,56 @@
{ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1 {ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1
{€}{{\EUR}}1 {£}{{\pounds}}1 {ő}{{\H{o}}}1 {ű}{{\H{u}}}1 {€}{{\EUR}}1 {£}{{\pounds}}1 {ő}{{\H{o}}}1 {ű}{{\H{u}}}1
} }
% Docker nyelvdefiníció
\lstdefinelanguage{Docker}{
keywords={FROM, RUN, CMD, LABEL, MAINTAINER, EXPOSE, ENV, ADD, COPY,
ENTRYPOINT, VOLUME, USER, WORKDIR, ARG, ONBUILD, STOPSIGNAL,
HEALTHCHECK, SHELL, AS},
keywordstyle=\color{blue}\bfseries,
identifierstyle=\color{black},
sensitive=false,
comment=[l]{\#},
commentstyle=\color{purple}\ttfamily,
stringstyle=\color{red}\ttfamily,
morestring=[b]',
morestring=[b]"
}
% JavaScript nyelvdefiníció
\lstdefinelanguage{JavaScript}{
keywords={typeof, new, true, false, catch, function, return, null, catch,
switch, var, const, let, if, in, while, do, else, case, break, async,
await, class, export, import, extends, super, this, throw, try, default},
keywordstyle=\color{blue}\bfseries,
ndkeywords={class, export, boolean, throw, implements, import, this},
ndkeywordstyle=\color{darkgray}\bfseries,
identifierstyle=\color{black},
sensitive=false,
comment=[l]{//},
morecomment=[s]{/*}{*/},
commentstyle=\color{purple}\ttfamily,
stringstyle=\color{red}\ttfamily,
morestring=[b]',
morestring=[b]"
}
% YAML nyelvdefiníció
\lstdefinelanguage{yaml}{
keywords={true,false,null,y,n},
keywordstyle=\color{darkgray}\bfseries,
sensitive=false,
comment=[l]{\#},
commentstyle=\color{purple}\ttfamily,
stringstyle=\color{red}\ttfamily,
morestring=[b]',
morestring=[b]",
basicstyle=\ttfamily\scriptsize,
breaklines=true,
columns=fullflexible,
keepspaces=true,
showstringspaces=false
}
\lstdefinestyle{HTML}{ \lstdefinestyle{HTML}{
language=HTML, language=HTML,
breaklines=true, breaklines=true,
Binary file not shown.
+24
View File
@@ -0,0 +1,24 @@
\documentclass[usenames,dvipsnames,aspectratio=169]{beamer}
\usepackage{../common/webfejl}
% Automatikus frame törés engedélyezése túl hosszú tartalomnál
\setbeamertemplate{frametitle continuation}[from second][\insertcontinuationcountroman]
\title[Webtechnológia és webalkalmazás-fejlesztés - Docker]{Webtechnológia és webalkalmazás-fejlesztés - Docker}
\subtitle{Docker}
\begin{document}
\begin{frame}[plain]
\titlepage
\logoalul
\end{frame}
\input{docker_basics.tex}
\input{docker_file.tex}
\input{docker_images.tex}
\input{docker_container.tex}
\input{docker_compose.tex}
\input{docker_network.tex}
\end{document}
+432
View File
@@ -0,0 +1,432 @@
\section{Docker Alapok}
\begin{frame}{Mi a Docker?}
\begin{block}{Docker -- Konténerizációs platform}
\begin{itemize}
\item 2013-ban indult nyílt forráskódú projekt
\item Alkalmazások csomagolása és futtatása izolált környezetben
\item Könnyűsúlyú alternatíva a virtuális gépeknek
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Docker -- Definíció}
\begin{exampleblock}{Definíció}
A Docker egy platform, amely lehetővé teszi alkalmazások és függőségeik \textbf{konténerekbe} csomagolását, amelyek bárhol futtathatók.
\end{exampleblock}
\begin{block}{Filozófia}
\textbf{``Build once, run anywhere''} -- egyszer csomagolva, bárhol fut.
\end{block}
\end{frame}
\begin{frame}{A probléma, amit megold}
\begin{alertblock}{``Works on my machine'' probléma}
\begin{itemize}
\item Fejlesztői gépen működik, production-ön nem
\item Különböző operációs rendszerek
\item Eltérő függőség verziók
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{A probléma -- Következmények}
\begin{alertblock}{További problémák}
\begin{itemize}
\item Bonyolult telepítési folyamatok
\item Nehezen reprodukálható hibák
\item Inkonzisztens viselkedés környezetek között
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Docker megoldás}
\begin{exampleblock}{Hogyan oldja meg?}
\begin{itemize}
\item Azonos környezet mindenhol (dev, test, prod)
\item Összes függőség a konténerben
\item Gyors telepítés és indítás
\end{itemize}
\end{exampleblock}
\begin{block}{Lényeg}
Egyszer csomagolva, bárhol fut -- garantáltan!
\end{block}
\end{frame}
\begin{frame}{Miért használjunk Dockert? -- Fejlesztőknek}
\begin{block}{Fejlesztői előnyök}
\begin{itemize}
\item Gyors setup -- percek helyett másodpercek
\item Konzisztens környezet minden fejlesztőnél
\item Izoláció -- egymástól független projektek
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Miért használjunk Dockert? -- Gyakorlatban}
\begin{exampleblock}{Gyakorlati előnyök}
\begin{itemize}
\item Új csapattag: \texttt{docker compose up} és kész
\item Nincs ``nálam működik'' probléma
\item Különböző Node.js verziók párhuzamosan
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Miért használjunk Dockert? -- DevOps}
\begin{block}{DevOps előnyök}
\begin{itemize}
\item Automatizálás -- CI/CD pipeline egyszerűsítése
\item Skálázhatóság -- könnyű horizontális skálázás
\item Mikroszolgáltatások -- ideális architektúra
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Docker fő előnyök}
\begin{block}{Összesítve}
\begin{itemize}
\item Hordozhatóság -- bárhol fut
\item Könnyűsúlyú -- MB-ok VM GB-jai helyett
\item Gyors indítás -- másodpercek
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Docker vs Virtuális gépek -- VM jellemzői}
\begin{block}{Virtuális gép (VM)}
\begin{itemize}
\item Teljes operációs rendszer minden VM-nek
\item Hypervisor szükséges (VMware, VirtualBox)
\item Lassabb indítás -- perceket vehet igénybe
\end{itemize}
\end{block}
\begin{exampleblock}{Szerkezet}
Hardware $\rightarrow$ Host OS $\rightarrow$ Hypervisor $\rightarrow$ Guest OS $\rightarrow$ App
\end{exampleblock}
\end{frame}
\begin{frame}{Docker vs Virtuális gépek -- VM hátrányok}
\begin{alertblock}{VM hátrányok}
\begin{itemize}
\item Nagy méret -- több gigabájt
\item Több erőforrás igény -- CPU, memória, tárhely
\item Teljes OS virtualizálás -- minden VM-nek saját kernel
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Docker vs Virtuális gépek -- Docker jellemzői}
\begin{block}{Docker konténer}
\begin{itemize}
\item Osztott OS kernel a host-tal
\item Docker Engine futtatja
\item Gyors indítás -- másodpercek
\end{itemize}
\end{block}
\begin{exampleblock}{Szerkezet}
Hardware $\rightarrow$ Host OS $\rightarrow$ Docker Engine $\rightarrow$ App
\end{exampleblock}
\end{frame}
\begin{frame}{Docker vs VM -- Kulcskülönbség}
\begin{alertblock}{Kulcskülönbség}
\begin{itemize}
\item Alkalmazás szintű izoláció az OS kernelen
\item Konténerek osztják a host kernel-t
\item Kisebb méret -- megabájtok vs gigabájtok
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Architektúra összehasonlítás}
\begin{center}
\begin{tikzpicture}[node distance=0.25cm, scale=0.85, every node/.style={scale=0.85}]
\node[font=\bfseries\footnotesize] at (-3, 4.5) {Virtuális gép};
\node[draw, rectangle, fill=blue!20, minimum width=2.5cm, minimum height=0.5cm, align=center, font=\scriptsize] (app1) at (-3, 3.8) {App A};
\node[draw, rectangle, fill=blue!20, minimum width=2.5cm, minimum height=0.5cm, below=of app1, align=center, font=\scriptsize] (os1) {Guest OS};
\node[draw, rectangle, fill=blue!20, minimum width=2.5cm, minimum height=0.5cm, font=\scriptsize] (app2) at (-3, 2.2) {App B};
\node[draw, rectangle, fill=blue!20, minimum width=2.5cm, minimum height=0.5cm, below=of app2, align=center, font=\scriptsize] (os2) {Guest OS};
\node[draw, rectangle, fill=green!20, minimum width=5.5cm, minimum height=0.5cm, below=of os2, align=center, yshift=-0.2cm, font=\scriptsize] (hypervisor) {Hypervisor};
\node[draw, rectangle, fill=yellow!20, minimum width=5.5cm, minimum height=0.5cm, below=of hypervisor, align=center, font=\scriptsize] (hostos1) {Host OS};
\node[draw, rectangle, fill=red!20, minimum width=5.5cm, minimum height=0.5cm, below=of hostos1, align=center, font=\scriptsize] (hw1) {Hardware};
\node[font=\bfseries\footnotesize] at (3, 4.5) {Docker konténer};
\node[draw, rectangle, fill=blue!20, minimum width=1.2cm, minimum height=0.5cm, align=center, font=\scriptsize] (dapp1) at (2, 3.8) {App A};
\node[draw, rectangle, fill=blue!20, minimum width=1.2cm, minimum height=0.5cm, align=center, font=\scriptsize] (dapp2) at (3.3, 3.8) {App B};
\node[draw, rectangle, fill=blue!20, minimum width=1.2cm, minimum height=0.5cm, align=center, font=\scriptsize] (dapp3) at (4.6, 3.8) {App C};
\node[draw, rectangle, fill=green!20, minimum width=5.5cm, minimum height=0.5cm, align=center, font=\scriptsize] (docker) at (3, 3) {Docker Engine};
\node[draw, rectangle, fill=yellow!20, minimum width=5.5cm, minimum height=0.5cm, below=of docker, align=center, font=\scriptsize] (hostos2) {Host OS};
\node[draw, rectangle, fill=red!20, minimum width=5.5cm, minimum height=0.5cm, below=of hostos2, align=center, font=\scriptsize] (hw2) {Hardware};
\end{tikzpicture}
\end{center}
\end{frame}
\begin{frame}{Docker életciklus}
\begin{center}
\begin{tikzpicture}[node distance=2cm]
\node[draw, rectangle, fill=blue!20, minimum width=2.5cm, minimum height=1cm, align=center] (dockerfile) {Dockerfile\\(utasítások)};
\node[draw, rectangle, fill=green!20, minimum width=2.5cm, minimum height=1cm, right=of dockerfile, align=center] (image) {Image\\(sablon)};
\node[draw, rectangle, fill=orange!20, minimum width=2.5cm, minimum height=1cm, right=of image, align=center] (container) {Container\\(futó app)};
\draw[->, thick] (dockerfile) -- (image) node[midway, above, font=\small] {build};
\draw[->, thick] (image) -- (container) node[midway, above, font=\small] {run};
\node[draw, rectangle, fill=purple!20, minimum width=2.5cm, minimum height=1cm, below=of image, align=center] (registry) {Registry\\(Docker Hub)};
\draw[->, thick] (image) -- (registry) node[midway, right, font=\small] {push};
\draw[->, thick] (registry) -- (image) node[midway, left, font=\small] {pull};
\end{tikzpicture}
\end{center}
\end{frame}
\begin{frame}{Docker Engine}
\begin{block}{Docker Engine -- A fő komponens}
\begin{itemize}
\item A Docker fő komponense
\item Kliens-szerver architektúra
\item 3 fő rész: Daemon, REST API, CLI
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Docker Engine -- Részei}
\begin{enumerate}
\item \textbf{Docker Daemon (dockerd):} Háttérfolyamat, kezeli a konténereket
\item \textbf{Docker CLI (docker):} Parancssor interfész
\item \textbf{REST API:} Kommunikáció daemon és CLI között
\end{enumerate}
\begin{exampleblock}{Működés}
Parancs: \texttt{docker run nginx} \\
CLI \textrightarrow{} REST API \textrightarrow{} Daemon \textrightarrow{} Image letöltés \& Konténer indítás
\end{exampleblock}
\end{frame}
\begin{frame}{Használati esetek -- Fejlesztés}
\begin{block}{Fejlesztési környezet}
\begin{itemize}
\item Gyors projekt setup másodpercek alatt
\item Különböző verziók párhuzamosan (Node 16, 18, 20)
\item Csapat tagjai azonos környezetben dolgoznak
\end{itemize}
\end{block}
\begin{exampleblock}{Példa}
Új fejlesztő csatlakozik: \texttt{git clone} + \texttt{docker compose up}\\
$\Rightarrow$ Azonnal dolgozhat, telepítés nélkül
\end{exampleblock}
\end{frame}
\begin{frame}{Használati esetek -- Mikroszolgáltatások}
\begin{block}{Mikroszolgáltatások}
\begin{itemize}
\item Minden szolgáltatás saját konténerben fut
\item Független skálázás és deployment
\item Könnyű verziókezelés
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Használati esetek -- CI/CD}
\begin{block}{CI/CD pipeline}
\begin{itemize}
\item Automatizált build és tesztelés
\item Konzisztens deployment minden környezetben
\item Gyors rollback hibás verzióról
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Mi kerül konténerbe? -- Alapok}
\begin{exampleblock}{Alapvető elemek}
\begin{itemize}
\item \textbf{Alap OS réteg:} Linux disztribúció (Alpine, Ubuntu)
\item \textbf{Runtime:} Node.js futtatókörnyezet (pl. 18.x)
\item \textbf{Függőségek:} npm csomagok (node\_modules mappa)
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Mi kerül konténerbe? -- Alkalmazás}
\begin{exampleblock}{Alkalmazás specifikus elemek}
\begin{itemize}
\item \textbf{Alkalmazás kód:} forrásfájlok (src/, index.js)
\item \textbf{Konfigurációk:} package.json, környezeti beállítások
\item \textbf{Indítási parancs:} npm start vagy node index.js
\end{itemize}
\end{exampleblock}
\begin{block}{Eredmény}
Önálló, hordozható csomag, amely bárhol futtatható
\end{block}
\end{frame}
\begin{frame}{Mi NEM kerül konténerbe? -- Adatok}
\begin{alertblock}{Perzisztens adatok}
\begin{itemize}
\item \textbf{Adatbázis adatok} -- volume-ban kell tárolni
\item \textbf{Nagy méretű log fájlok} -- host-ra vagy log service-re
\item \textbf{Feltöltött fájlok} -- user uploads, media files
\end{itemize}
\end{alertblock}
\begin{exampleblock}{Miért?}
Konténer törléskor ezek az adatok elvesznének!
\end{exampleblock}
\end{frame}
\begin{frame}{Mi NEM kerül konténerbe? -- Biztonság}
\begin{alertblock}{Biztonsági és development elemek}
\begin{itemize}
\item \textbf{Érzékeny konfigurációk} -- titkos kulcsok, jelszavak
\item \textbf{Fejlesztői eszközök} -- debugging, testing tools
\item \textbf{Build artifacts} -- ideiglenesen használt fájlok
\end{itemize}
\end{alertblock}
\begin{exampleblock}{Jó gyakorlat}
Titkos kulcsok: Docker secrets vagy környezeti változók\\
Dev tools: csak development image-ben
\end{exampleblock}
\end{frame}
\begin{frame}{Docker Desktop -- Mi az?}
\begin{block}{Docker Desktop alkalmazás}
\begin{itemize}
\item Grafikus felületű alkalmazás Windows és macOS rendszerekhez
\item Tartalmazza az összes szükséges Docker komponenst
\item Beépített GUI konténerek és image-ek kezeléséhez
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Docker Desktop -- Technológia}
\begin{exampleblock}{Technológiai előnyök}
\begin{itemize}
\item Integrált Kubernetes támogatás
\item WSL 2 backend Windows-on (Linux kernel)
\item Automatikus frissítések
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Docker Desktop -- Funkciók}
\begin{block}{Fő funkciók}
\begin{itemize}
\item Konténerek vizuális monitorozása
\item Resource használat követése (CPU, RAM)
\item Volume és network kezelés GUI-n keresztül
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Docker Desktop -- Kiegészítők}
\begin{exampleblock}{Kiegészítők}
\begin{itemize}
\item Extension marketplace -- további funkciók
\item Dev Environments támogatás
\item Docker Scout -- biztonsági elemzés
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Docker Desktop -- Telepítés}
\begin{exampleblock}{Telepítési lépések}
\begin{enumerate}
\item Letöltés: \texttt{docker.com/products/docker-desktop}
\item Telepítő futtatása
\item Rendszer újraindítása (ha szükséges)
\end{enumerate}
\end{exampleblock}
\end{frame}
\begin{frame}{Docker Desktop -- Ellenőrzés}
\begin{exampleblock}{Ellenőrzés}
\begin{enumerate}
\item Docker Desktop indítása
\item Ellenőrzés terminálban: \texttt{docker --version}
\end{enumerate}
\end{exampleblock}
\end{frame}
\begin{frame}{Docker Desktop -- Windows és macOS}
\begin{block}{Windows és macOS}
\begin{itemize}
\item \textbf{Docker Desktop ajánlott} -- grafikus telepítő
\item Tartalmaz mindent: Docker Engine, CLI, Compose
\item Automatikus frissítések
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Docker Desktop -- Linux}
\begin{alertblock}{Linux}
\begin{itemize}
\item \textbf{Docker Engine} közvetlenül telepíthető
\item Docker Desktop opcionális (beta)
\item Parancssorból: \texttt{apt install docker.io}
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Összefoglalás -- Docker lényege}
\begin{block}{Docker = Modern konténerizáció}
\begin{itemize}
\item Alkalmazások izolált, hordozható csomagolása
\item Könnyűsúlyú alternatíva a virtuális gépeknek
\item ``Build once, run anywhere'' filozófia
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Összefoglalás -- Előnyök}
\begin{exampleblock}{Miért használjuk?}
\begin{itemize}
\item Gyors és könnyű deployment
\item Hatékony erőforrás kihasználás
\item Skálázható mikroszolgáltatások
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Összefoglalás -- Fogalmak}
\begin{block}{Build és futtatás}
\begin{itemize}
\item \textbf{Dockerfile:} Utasítások az image építéséhez
\item \textbf{Image:} Csak olvasható sablon az alkalmazásról
\item \textbf{Container:} Futó példány egy image-ből
\end{itemize}
\end{block}
\begin{exampleblock}{Folyamat}
Dockerfile $\rightarrow$ build $\rightarrow$ Image $\rightarrow$ run $\rightarrow$ Container
\end{exampleblock}
\end{frame}
\begin{frame}{Összefoglalás -- Tárolás}
\begin{block}{Tárolás és kommunikáció}
\begin{itemize}
\item \textbf{Registry:} Image-ek tárolása (pl. Docker Hub)
\item \textbf{Volume:} Perzisztens adattárolás
\item \textbf{Network:} Konténerek közötti kommunikáció
\end{itemize}
\end{block}
\begin{alertblock}{Következő lépések}
Dockerfile készítés, image build, konténer kezelés, Docker Compose
\end{alertblock}
\end{frame}
+903
View File
@@ -0,0 +1,903 @@
\section{Docker Compose}
\begin{frame}{Mi a Docker Compose?}
\begin{block}{Docker Compose -- Több konténer kezelése}
\begin{itemize}
\item Eszköz \textbf{több konténerből álló} alkalmazások definiálására
\item YAML formátumú konfigurációs fájl (\texttt{docker-compose.yml})
\item Egyetlen parancs: teljes alkalmazás indítása/leállítása
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Docker Compose -- Használati eset}
\begin{exampleblock}{Példa használati eset}
Node.js backend + PostgreSQL adatbázis + Redis cache\\
$\Rightarrow$ 3 konténer, 1 docker-compose.yml, 1 parancs: \texttt{docker compose up}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Miért? -- Docker Compose nélkül}
\begin{alertblock}{Docker Compose nélkül}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
docker network create myapp
docker run -d --name postgres \
--network myapp \
-e POSTGRES_PASSWORD=secret \
postgres:15
docker run -d --name redis \
--network myapp redis:7
docker run -d --name backend \
--network myapp \
-p 3000:3000 my-backend
\end{lstlisting}
\end{alertblock}
\end{frame}
\begin{frame}{Miért? -- A probléma}
\begin{alertblock}{Probléma}
Bonyolult, sok parancs, nehezen karbantartható
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Miért? -- Docker Compose-zal}
\begin{exampleblock}{Docker Compose-zal}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
docker compose up
\end{lstlisting}
\end{exampleblock}
\begin{block}{Előnyök}
\begin{itemize}
\item Egyetlen parancs!
\item Minden konfiguráció a \texttt{docker-compose.yml}-ben
\item Reprodukálható és verziókezelhető
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Miért? -- Csapatmunka}
\begin{block}{Csapatmunka előnyök}
\begin{itemize}
\item Verziókezelhető (Git)
\item Csapatmunkában könnyen megosztható
\item Konzisztens környezet minden fejlesztőnél
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{Docker Compose telepítés}
\begin{block}{Modern Docker verzió}
Docker Desktop és újabb Docker Engine verziók tartalmazzák:
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Ellenőrzés
docker compose version
# Docker Compose version v2.24.0
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{Docker Compose -- Régi vs új szintaxis}
\begin{alertblock}{Régi vs új szintaxis}
\begin{itemize}
\item Régi (v1): \texttt{docker-compose up} (kötőjellel, külön telepítés)
\item Új (v2): \texttt{docker compose up} (szóköz, built-in)
\end{itemize}
Ajánlott: v2 (docker compose)
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Első docker-compose.yml -- Kód}
\begin{exampleblock}{Egyszerű webszerver példa}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
version: '3.8'
services:
web:
image: nginx:alpine
ports:
- "8080:80"
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Első docker-compose.yml -- Parancsok}
\begin{block}{Indítás és leállítás}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Indítás (háttérben)
docker compose up -d
# Leállítás és törlés
docker compose down
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{docker-compose.yml struktúra -- Kód}
\begin{block}{Fő elemek}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
version: '3.8' # Compose fájl verzió
services: # Konténerek definíciója
service1:
# konfiguráció
service2:
# konfiguráció
volumes: # Named volume-ok (opcionális)
data:
networks: # Egyedi hálózatok (opcionális)
backend:
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{docker-compose.yml struktúra -- Magyarázat}
\begin{block}{Elemek}
\begin{itemize}
\item \texttt{version}: Compose fájl formátum verzió
\item \texttt{services}: Konténerek (ezeket indítja)
\item \texttt{volumes}: Megosztott perzisztens tárolók
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{docker-compose.yml struktúra -- Networks}
\begin{block}{Hálózatok}
\begin{itemize}
\item \texttt{networks}: Hálózati konfiguráció
\item Compose automatikusan létrehoz egy default hálózatot
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{Service definíció -- image alapú}
\begin{exampleblock}{Existing image használata}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
database:
image: postgres:15-alpine
environment:
POSTGRES_DB: myapp
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret123
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
restart: unless-stopped
volumes:
postgres-data:
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Service definíció -- build alapú}
\begin{exampleblock}{Saját Dockerfile build-elése}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
NODE_ENV: production
DB_HOST: database
depends_on:
- database
restart: unless-stopped
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Service definíció -- build magyarázat}
\begin{block}{Build elemek}
\begin{itemize}
\item \texttt{build}: Dockerfile-ból épít
\item \texttt{context}: Build context útvonal
\item \texttt{depends\_on}: Függőségek (ez után indul)
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{Environment variables -- Inline}
\begin{block}{Inline környezeti változók}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
app:
environment:
NODE_ENV: production
PORT: 3000
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Environment variables -- Fájlból}
\begin{block}{.env fájlból}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
app:
env_file:
- .env
- .env.local
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Environment variables -- Host változók}
\begin{block}{Host environment változók}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
app:
environment:
# .env fájlból vagy host-ról
DB_PASSWORD: ${DB_PASSWORD}
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Volumes -- Named volumes}
\begin{block}{Named volumes (ajánlott)}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
db:
image: postgres:15
volumes:
- db-data:/var/lib/postgresql/data
volumes:
db-data:
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Volumes -- Bind mounts}
\begin{block}{Bind mounts (fejlesztéshez)}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
app:
volumes:
# Relatív útvonal
- ./src:/app/src
# Abszolút útvonal
- /host/path:/container/path
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Networks -- Automatikus}
\begin{block}{Automatikus hálózat}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
backend:
image: my-app
database:
image: postgres
\end{lstlisting}
Compose automatikusan létrehoz egy hálózatot!\\
\texttt{backend} eléri \texttt{database}-t a név alapján.
\end{block}
\end{frame}
\begin{frame}[fragile]{Networks -- Egyedi hálózatok}
\begin{block}{Egyedi hálózatok}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
backend:
networks:
- frontend
- backend
database:
networks:
- backend
networks:
frontend:
backend:
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{MERN stack -- Adatbázisok}
\begin{exampleblock}{MongoDB és Redis}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
version: '3.8'
services:
mongodb:
image: mongo:7
volumes:
- mongo-data:/data/db
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: secret
restart: unless-stopped
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{MERN stack -- Redis és volumes}
\begin{exampleblock}{Redis és adattárolás}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
mongo-data:
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{MERN stack -- Adatbázis magyarázat}
\begin{block}{Adattárolás}
\begin{itemize}
\item \textbf{MongoDB:} perzisztens volume (mongo-data)
\item \textbf{Redis:} cache, nincs szükség volume-ra
\item \textbf{Restart policy:} biztosítja a rendelkezésre állást
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{MERN stack -- Backend}
\begin{exampleblock}{Backend szolgáltatás}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
backend:
build: ./backend
ports:
- "3001:3001"
environment:
MONGO_URL: mongodb://admin:secret@mongodb:27017
REDIS_URL: redis://redis:6379
depends_on:
- mongodb
- redis
restart: unless-stopped
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{MERN stack -- Frontend}
\begin{exampleblock}{Frontend szolgáltatás}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
environment:
REACT_APP_API_URL: http://localhost:3001
depends_on:
- backend
restart: unless-stopped
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{depends\_on -- Alap használat}
\begin{block}{Alapvető függőség}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
backend:
depends_on:
- database
database:
image: postgres
\end{lstlisting}
\texttt{database} indul először, \textbf{de nem vár} amíg kész!
\end{block}
\end{frame}
\begin{frame}{depends\_on -- Figyelmeztetés}
\begin{alertblock}{Fontos}
\texttt{depends\_on} csak az indítási sorrendet szabályozza,\\
\textbf{NEM várja meg} amíg a szolgáltatás tényleg készen áll!
\end{alertblock}
\begin{exampleblock}{Megoldás}
\begin{itemize}
\item Alkalmazásban: retry logika
\item Healthcheck használata
\item wait-for-it.sh script
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Healthcheck a Compose-ban}
\begin{exampleblock}{Szolgáltatás készenlét ellenőrzés}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
database:
image: postgres:15
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
backend:
depends_on:
database:
condition: service_healthy
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Healthcheck -- Magyarázat}
\begin{block}{Healthcheck elemek}
\begin{itemize}
\item \texttt{condition: service\_healthy}: Vár amíg healthcheck OK
\item \texttt{test}: Ellenőrző parancs
\item \texttt{interval}: Ellenőrzések gyakorisága
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{Compose parancsok -- Indítás}
\begin{block}{Indítás}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Indítás (előtérben, logokkal)
docker compose up
# Indítás háttérben
docker compose up -d
# Rebuild és indítás
docker compose up --build
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Compose parancsok -- Leállítás}
\begin{block}{Leállítás}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Leállítás (konténerek megmaradnak)
docker compose stop
# Leállítás és törlés
docker compose down
# Törlés volume-okkal együtt
docker compose down -v
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Compose parancsok -- Státusz}
\begin{block}{Státusz és logok}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Futó szolgáltatások listája
docker compose ps
# Összes szolgáltatás (leállítottak is)
docker compose ps -a
# Logok megjelenítése
docker compose logs
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Compose parancsok -- Log szűrés}
\begin{block}{Log szűrés}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Követés (egyik szolgáltatás)
docker compose logs -f backend
# Utolsó 100 sor
docker compose logs --tail=100
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Exec és run -- Futó konténerben}
\begin{block}{Parancs futtatása futó szolgáltatásban}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Shell futó konténerben
docker compose exec backend sh
# PostgreSQL konzol
docker compose exec database psql -U admin -d myapp
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Exec és run -- Egyszeri parancs}
\begin{block}{Egyszeri parancs (új konténer)}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Database migráció
docker compose run backend npm run migrate
# Teszt futtatás
docker compose run --rm backend npm test
\end{lstlisting}
\texttt{--rm}: Konténer törlése futás után
\end{block}
\end{frame}
\begin{frame}[fragile]{Scale -- Több példány}
\begin{block}{Szolgáltatás skálázása}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# 3 backend példány indítása
docker compose up -d --scale backend=3
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Scale -- Port konfliktus}
\begin{alertblock}{Port konfliktus}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
backend:
ports:
- "3000:3000" # Nem skálázható!
\end{lstlisting}
\end{alertblock}
\begin{exampleblock}{Megoldás: dinamikus port}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
ports:
- "3000-3002:3000" # 3 példány
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Override fájlok -- Dev config}
\begin{block}{docker-compose.override.yml}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
# docker-compose.yml (base)
services:
app:
image: my-app
# docker-compose.override.yml (dev)
services:
app:
volumes:
- ./src:/app/src # live reload
environment:
DEBUG: "true"
\end{lstlisting}
Automatikusan egyesül a base-zel fejlesztéskor!
\end{block}
\end{frame}
\begin{frame}[fragile]{Override fájlok -- Production}
\begin{block}{docker-compose.prod.yml}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
app:
image: my-app:1.0.0
restart: always
deploy:
replicas: 3
resources:
limits:
cpus: '0.5'
memory: 512M
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Override fájlok -- Használat}
\begin{block}{Használat}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Specifikus fájl megadása
docker compose -f docker-compose.yml \
-f docker-compose.prod.yml up -d
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Secrets kezelés -- .env fájl}
\begin{block}{Érzékeny adatok .env fájlban}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# .env fájl (ne commitold!)
POSTGRES_PASSWORD=supersecret123
API_KEY=abc123xyz
JWT_SECRET=random_secret_key
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Secrets kezelés -- Compose-ban}
\begin{block}{Használat docker-compose.yml-ben}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
database:
environment:
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
backend:
env_file:
- .env
\end{lstlisting}
\end{block}
\begin{alertblock}{Biztonság}
\texttt{.env} legyen a \texttt{.gitignore}-ban!\\
Használj \texttt{.env.example} sablont repository-ban!
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Profiles -- Opcionális szolgáltatások}
\begin{block}{Fejlesztői eszközök csak manuális indításkor}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
app:
image: my-app
database:
image: postgres
adminer:
image: adminer
profiles:
- debug
ports:
- "8080:8080"
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Profiles -- Használat}
\begin{block}{Használat}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Normál indítás: app + database
docker compose up
# Debug profillal: app + database + adminer
docker compose --profile debug up
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Resource limits}
\begin{exampleblock}{CPU és memória korlátok}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
backend:
image: my-app
deploy:
resources:
limits:
cpus: '1.0'
memory: 1G
reservations:
cpus: '0.5'
memory: 512M
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Logging konfiguráció}
\begin{exampleblock}{Log beállítások}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
backend:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
\end{lstlisting}
\end{exampleblock}
\begin{block}{Driverek}
\texttt{json-file}, \texttt{syslog}, \texttt{journald}, \texttt{awslogs}
\end{block}
\end{frame}
\begin{frame}[fragile]{Teljes projekt -- PostgreSQL}
\begin{exampleblock}{PostgreSQL szolgáltatás}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
version: '3.8'
services:
postgres:
image: postgres:15-alpine
environment:
POSTGRES_DB: ${DB_NAME}
POSTGRES_USER: ${DB_USER}
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- postgres-data:/var/lib/postgresql/data
restart: unless-stopped
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Teljes projekt -- PostgreSQL healthcheck}
\begin{exampleblock}{Healthcheck hozzáadása}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
postgres:
healthcheck:
test: ["CMD-SHELL",
"pg_isready -U ${DB_USER}"]
interval: 5s
timeout: 5s
retries: 5
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Teljes projekt -- Redis és volumes}
\begin{exampleblock}{Redis és adattárolás}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
redis:
image: redis:7-alpine
restart: unless-stopped
volumes:
postgres-data:
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Teljes projekt -- Backend}
\begin{exampleblock}{Backend hotreload-dal}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
backend:
build: ./backend
ports:
- "3001:3001"
environment:
DATABASE_URL: postgresql://${DB_USER}:
${DB_PASSWORD}@postgres:5432/${DB_NAME}
REDIS_URL: redis://redis:6379
volumes:
- ./backend/src:/app/src
depends_on:
postgres:
condition: service_healthy
restart: unless-stopped
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Teljes projekt -- Frontend}
\begin{exampleblock}{React frontend hotreload-dal}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
frontend:
build: ./frontend
ports:
- "3000:3000"
environment:
REACT_APP_API_URL: http://localhost:3001
volumes:
- ./frontend/src:/app/src
- /app/node_modules
depends_on:
- backend
restart: unless-stopped
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Teljes projekt -- Frontend magyarázat}
\begin{block}{Fejlesztői környezet}
\begin{itemize}
\item Volume mount: kód változások azonnal láthatóak
\item node\_modules izolált a konténerben
\item Restart policy védelem összeomlás ellen
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Compose vs Orchestration -- Compose}
\begin{block}{Mikor használj Docker Compose-t?}
\begin{itemize}
\item Fejlesztési környezet
\item Teszt környezet
\item Kisebb produkciós alkalmazások (1-2 szerver)
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Compose vs Orchestration -- Kubernetes}
\begin{block}{Mikor kell Kubernetes vagy Docker Swarm?}
\begin{itemize}
\item Nagy léptékű production (több szerver)
\item Magas rendelkezésre állás (HA)
\item Automatikus failover és auto-scaling
\end{itemize}
\end{block}
\begin{alertblock}{Fontos}
Kezdd Compose-zal, csak akkor válts orchestration-re, ha tényleg szükséges!
\end{alertblock}
\end{frame}
\begin{frame}{Best Practices -- Konfiguráció}
\begin{exampleblock}{Ajánlott gyakorlatok}
\begin{itemize}
\item \textbf{Verziókezeld} a \texttt{docker-compose.yml}-t
\item \textbf{.env fájl} érzékeny adatokhoz (.gitignore!)
\item \textbf{Named volumes} adatok perzisztálásához
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Best Practices -- Megbízhatóság}
\begin{exampleblock}{Ajánlott gyakorlatok}
\begin{itemize}
\item \textbf{Healthcheck} használata depends\_on-nál
\item \textbf{Restart policy}: unless-stopped production-ben
\item \textbf{Resource limits} beállítása
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Best Practices -- Build}
\begin{exampleblock}{Ajánlott gyakorlatok}
\begin{itemize}
\item \textbf{Specifikus image verziók} (ne latest)
\item \textbf{Multi-stage Dockerfile} kisebb image-ekhez
\item \textbf{Service nevek} beszédesek legyenek
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Anti-patterns -- Kerülendő}
\begin{alertblock}{Ne csináld}
\begin{itemize}
\item Érzékeny adatok közvetlenül a YAML-ban
\item \texttt{latest} tag production-ben
\item Adatok a konténerben (volume nélkül)
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Anti-patterns -- Kerülendő folyt.}
\begin{alertblock}{Ne csináld}
\begin{itemize}
\item Egy konténerben több alkalmazás
\item Hardcoded portok ha skálázni akarsz
\item Depends\_on healthcheck nélkül
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Összefoglalás -- Lényeg}
\begin{block}{Docker Compose = Egyszerű multi-container kezelés}
\begin{itemize}
\item YAML fájl: teljes alkalmazás stack leírása
\item Egy parancs: \texttt{docker compose up}
\item Automatikus hálózat, volume, service discovery
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Összefoglalás -- Előnyök}
\begin{exampleblock}{Előnyök}
\begin{itemize}
\item Gyors setup -- másodpercek alatt
\item Konzisztens környezet minden fejlesztőnél
\item Reprodukálható, verziókezelhető
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Összefoglalás -- Kulcs koncepciók}
\begin{block}{Fő elemek}
\begin{itemize}
\item \texttt{services}: Mi fusson (konténerek definíciója)
\item \texttt{volumes}: Adatok perzisztálása
\item \texttt{networks}: Szolgáltatások összekapcsolása
\end{itemize}
\end{block}
\begin{alertblock}{Következő lépés}
Docker hálózatok részletesen
\end{alertblock}
\end{frame}
+586
View File
@@ -0,0 +1,586 @@
\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 <image-nev>
\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 <host-port>:<container-port>
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 <container-id>
# Erőszakos leállítás
docker kill <container-id>
# Újraindítás
docker restart <container-id>
\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 <container-id>
docker unpause <container-id>
# Törlés (csak leállított konténer)
docker rm <container-id>
# Futó konténer törlése
docker rm -f <container-id>
\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 <container-id> bash
# Parancs futtatása
docker exec <container-id> ls -la /app
# Root userként
docker exec -u root -it <container-id> 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 <container-id>
# Utolsó 50 sor
docker logs --tail 50 <container-id>
# Követés (folyamatos, mint tail -f)
docker logs -f <container-id>
\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 <container-id>
# Utolsó 10 perc
docker logs --since 10m <container-id>
\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 <container-id>
# Specifikus mező (pl. IP cím)
docker inspect -f \
'{{.NetworkSettings.IPAddress}}' <container-id>
\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 <container-id>
\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 <container-id>
# Összes leállított konténer
docker container prune
# Futó konténer törlése
docker rm -f <container-id>
\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}}' <container>
\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 <id> 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}
+977
View File
@@ -0,0 +1,977 @@
\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}
+221
View File
@@ -0,0 +1,221 @@
\section{Docker Image-ek}
\begin{frame}{Mi a Docker image?}
\begin{block}{Image = futtatási sablon}
\begin{itemize}
\item Csak olvasható sablon egy konténer létrehozásához
\item Tartalmazza az alkalmazás kódját és a függőségeket
\item Rétegekből (layers) épül fel
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Image -- Jellemzők}
\begin{block}{Tulajdonságok}
\begin{itemize}
\item Egy image-ből több konténer is indulhat
\item Immutable -- nem módosítható közvetlenül
\end{itemize}
\end{block}
\begin{exampleblock}{Analógia}
Az image olyan, mint egy telepítő ISO, a konténer pedig a futó rendszer.
\end{exampleblock}
\end{frame}
\begin{frame}{Image felépítése -- rétegek}
\begin{block}{Layer alapú működés}
\begin{itemize}
\item Minden Dockerfile utasítás új réteget hozhat létre
\item A rétegek újrahasznosíthatók több image között
\item Kisebb tárhelyigény és gyorsabb build a cache miatt
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Image rétegek -- Konténer indítás}
\begin{block}{Konténer indulásakor}
\begin{itemize}
\item Egy írható réteg kerül az image fölé
\item Az image rétegek változatlanok maradnak
\end{itemize}
\end{block}
\begin{alertblock}{Miért fontos?}
A jó Dockerfile-sorrend jelentősen csökkenti a build időt.
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Image azonosítás: név és tag}
\begin{block}{Formátum}
\texttt{[registry/]repository:tag}
\end{block}
\begin{exampleblock}{Példák}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
nginx:1.27
node:20-alpine
postgres:16
myrepo/my-api:1.0.0
ghcr.io/acme/payment-service:2026-02-15
\end{lstlisting}
\end{exampleblock}
\begin{alertblock}{Best practice}
Production környezetben ne használd a \texttt{latest} taget.
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Image letöltése -- docker pull}
\begin{block}{Pull parancs}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Legfrissebb tag letöltése
docker pull nginx
# Konkrét verzió
docker pull nginx:1.27
# Privát registry
docker pull ghcr.io/acme/my-api:1.0.0
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{Image letöltése -- Tudnivalók}
\begin{block}{Automatikus letöltés}
\begin{itemize}
\item Ha a \texttt{docker run} során nincs helyben az image, automatikusan pull történik
\item Több réteg párhuzamosan töltődik le
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{Saját image építése -- docker build}
\begin{block}{Alap build}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Aktuális mappából build
docker build -t my-api:1.0.0 .
# Több tag egyszerre
docker build -t my-api:1.0.0 -t my-api:latest .
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Saját image építése -- Haladó}
\begin{block}{Haladó opciók}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Másik Dockerfile használata
docker build -f Dockerfile.prod -t my-api:prod .
\end{lstlisting}
\end{block}
\begin{alertblock}{Tipp}
A build context legyen kicsi (\texttt{.dockerignore} használata kötelezően ajánlott).
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Image lista és információk}
\begin{block}{Gyakori parancsok}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Lokális image-ek listája
docker images
# Csak azonosítók
docker images -q
# Részletes adatok JSON-ben
docker image inspect my-api:1.0.0
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Image történet}
\begin{block}{Réteg történet}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Réteg történet
docker history my-api:1.0.0
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Image publikálása -- docker push}
\begin{block}{Folyamat}
\begin{enumerate}
\item Registry-be bejelentkezés: \texttt{docker login}
\item Image tag-elése cél repository-ra
\item Feltöltés \texttt{docker push}-sal
\end{enumerate}
\end{block}
\end{frame}
\begin{frame}[fragile]{Image publikálása -- Példa}
\begin{exampleblock}{Példa Docker Hub-ra}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
docker login
docker tag my-api:1.0.0 myuser/my-api:1.0.0
docker push myuser/my-api:1.0.0
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Image mentés és visszatöltés}
\begin{block}{Offline terjesztés}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Image mentése tar fájlba
docker save -o my-api-1.0.0.tar my-api:1.0.0
# Visszatöltés
docker load -i my-api-1.0.0.tar
\end{lstlisting}
\end{block}
\begin{exampleblock}{Mikor hasznos?}
Zárt hálózati környezetben, ahol nincs közvetlen registry elérés.
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Image takarítás}
\begin{block}{Felesleges image-ek eltávolítása}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Egy image törlése
docker rmi my-api:1.0.0
# Címke nélküli (dangling) image-ek törlése
docker image prune
# Minden nem használt image törlése
docker image prune -a
\end{lstlisting}
\end{block}
\begin{alertblock}{Figyelem}
A \texttt{prune} műveletek törlése nem visszavonható.
\end{alertblock}
\end{frame}
\begin{frame}{Best practices -- Verzió és méret}
\begin{exampleblock}{Ajánlott gyakorlatok}
\begin{itemize}
\item Használj fix verzió tag-eket (\texttt{1.0.0}, \texttt{2026-02-15})
\item Tartsd kicsiben az image méretét (alpine, multi-stage build)
\item Kerüld az érzékeny adatok beégetését image-be
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Best practices -- Build és deploy}
\begin{exampleblock}{Ajánlott gyakorlatok}
\begin{itemize}
\item Építs reprodukálható módon (determinista build)
\item CI-ben automatikusan címkézz és push-olj
\end{itemize}
\end{exampleblock}
\begin{alertblock}{Összefoglaló}
Jó image stratégia = gyors build, gyors deploy, kevesebb hiba.
\end{alertblock}
\end{frame}
+721
View File
@@ -0,0 +1,721 @@
\section{Docker hálózatok}
\begin{frame}{Docker hálózatok -- Bevezetés}
\begin{block}{Miért fontosak a Docker hálózatok?}
\begin{itemize}
\item Konténerek közötti kommunikáció
\item Szolgáltatások izolálása
\item Biztonságos konténer-architektúra
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Probléma hálózatok nélkül}
\begin{alertblock}{Mi történik hálózatok nélkül?}
\begin{itemize}
\item Konténerek nem érik el egymást
\item Minden port-ot a host-ra kell publikálni
\item Nincs belső szolgáltatás-felderítés (DNS)
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Megoldás -- Docker hálózatok}
\begin{exampleblock}{Docker hálózatokkal}
\begin{itemize}
\item Konténerek név alapján érik el egymást
\item Belső kommunikáció port-publikálás nélkül
\item Automatikus DNS feloldás
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Hálózati driverek -- Áttekintés}
\begin{block}{Docker hálózati driverek}
\begin{itemize}
\item \texttt{bridge}: Alapértelmezett, izolált hálózat
\item \texttt{host}: Host hálózat közvetlen használata
\item \texttt{none}: Nincs hálózat
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Hálózati driverek -- További}
\begin{block}{Haladó driverek}
\begin{itemize}
\item \texttt{overlay}: Több Docker host közötti hálózat (Swarm)
\item \texttt{macvlan}: Saját MAC cím, fizikai hálózatba illeszkedik
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Bridge hálózat -- Mi az?}
\begin{block}{Bridge driver (alapértelmezett)}
\begin{itemize}
\item Szoftveres hálózati híd a host-on
\item Konténerek egymást elérik a bridge-en
\item Külvilág felé port-publikálás szükséges
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Bridge architektúra}
\begin{center}
\begin{tikzpicture}[
box/.style={draw, rounded corners, minimum width=2.2cm, minimum height=0.9cm, font=\footnotesize},
bridge/.style={draw, fill=szecyan!20, rounded corners,
minimum width=8cm, minimum height=0.7cm, font=\footnotesize},
arr/.style={->, thick, >=stealth}
]
% Host
\node[draw, dashed, rounded corners, minimum width=9.5cm, minimum height=5cm,
label={[font=\footnotesize]above:Host gép}] (host) at (0,0) {};
% Bridge
\node[bridge] (br) at (0, 0.5) {docker0 (bridge)};
% Containers
\node[box, fill=szezold!30] (c1) at (-2.5, -1.2) {Konténer A};
\node[box, fill=szezold!30] (c2) at (0, -1.2) {Konténer B};
\node[box, fill=szezold!30] (c3) at (2.5, -1.2) {Konténer C};
% veth pairs
\draw[arr] (c1.north) -- (br.south -| c1.north);
\draw[arr] (c2.north) -- (br.south);
\draw[arr] (c3.north) -- (br.south -| c3.north);
% External
\node[box, fill=szenavy!20, text=szenavy] (ext) at (0, 2.5) {Külvilág};
\draw[arr, dashed] (br.north) -- node[right, font=\scriptsize] {port publish} (ext.south);
\end{tikzpicture}
\end{center}
\end{frame}
\begin{frame}[fragile]{Hálózat parancsok -- Listázás}
\begin{block}{Hálózatok listázása}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Összes hálózat
docker network ls
# NETWORK ID NAME DRIVER SCOPE
# abc123 bridge bridge local
# def456 host host local
# ghi789 none null local
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Hálózat parancsok -- Létrehozás}
\begin{block}{Hálózat létrehozása}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Egyszerű bridge hálózat
docker network create mynetwork
# Megadott driver-rel
docker network create --driver bridge mynetwork
# Megadott subnet-tel
docker network create --subnet=172.20.0.0/16 mynetwork
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Hálózat parancsok -- Törlés}
\begin{block}{Hálózat törlése és tisztítás}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Egy hálózat törlése
docker network rm mynetwork
# Nem használt hálózatok törlése
docker network prune
# Részletes információk
docker network inspect mynetwork
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Konténer csatlakoztatás -- Indításkor}
\begin{block}{Hálózat megadása indításkor}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Konténer indítása adott hálózaton
docker run -d --name backend \
--network mynetwork my-app
# Több hálózat: indítás után csatlakoztatás
docker network connect frontend-net backend
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Konténer csatlakoztatás -- Utólag}
\begin{block}{Utólagos csatlakoztatás / leválasztás}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Futó konténer csatlakoztatása hálózathoz
docker network connect mynetwork mycontainer
# Leválasztás hálózatról
docker network disconnect mynetwork mycontainer
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{Default bridge vs User-defined}
\begin{alertblock}{Default bridge hálózat}
\begin{itemize}
\item \textbf{Nincs} automatikus DNS feloldás
\item Konténerek csak IP-vel érik el egymást
\item IP cím változhat újraindításkor
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{User-defined bridge -- Előnyök}
\begin{exampleblock}{User-defined bridge hálózat}
\begin{itemize}
\item \textbf{Van} automatikus DNS feloldás
\item Konténerek \textbf{név alapján} érik el egymást
\item Jobb izoláció, automatikus link
\end{itemize}
\end{exampleblock}
\begin{alertblock}{Ajánlás}
Mindig user-defined bridge-et használj!
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{DNS és Service Discovery -- Kód}
\begin{exampleblock}{Automatikus névfeloldás}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Hálózat létrehozása
docker network create app-net
# Adatbázis indítása
docker run -d --name database \
--network app-net postgres:15
# Backend indítása
docker run -d --name backend \
--network app-net \
-e DB_HOST=database \
my-backend
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{DNS és Service Discovery -- Magyarázat}
\begin{block}{Hogyan működik?}
\begin{itemize}
\item \texttt{backend} eléri \texttt{database}-t a nevével
\item Docker beépített DNS szerver: \texttt{127.0.0.11}
\item Konténer név = hostname a hálózaton
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{Fullstack példa -- Hálózat létrehozás}
\begin{exampleblock}{Hálózat előkészítése}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Hálózat létrehozása
docker network create fullstack-net
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Fullstack példa -- Adatbázis}
\begin{exampleblock}{PostgreSQL indítása}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
docker run -d --name postgres \
--network fullstack-net \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=myapp \
-v pgdata:/var/lib/postgresql/data \
postgres:15-alpine
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Fullstack példa -- Backend}
\begin{exampleblock}{Node.js backend}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
docker run -d --name backend \
--network fullstack-net \
-p 3001:3001 \
-e DATABASE_URL=postgresql://postgres:secret
@postgres:5432/myapp \
my-backend
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Fullstack példa -- Frontend}
\begin{exampleblock}{React frontend}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
docker run -d --name frontend \
--network fullstack-net \
-p 3000:3000 \
my-frontend
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Fullstack példa -- Magyarázat}
\begin{block}{Kommunikáció}
\begin{itemize}
\item Backend eléri az adatbázist: \texttt{postgres:5432}
\item Frontend eléri a backend-et: \texttt{backend:3001}
\item Külvilág eléri: \texttt{localhost:3000} és \texttt{:3001}
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Port publishing vs belső hálózat}
\begin{block}{Mikor kell port publishing?}
Csak ha a \textbf{host-ról} vagy \textbf{külvilágból} kell elérni!
\end{block}
\begin{exampleblock}{Belső hálózat}
\begin{itemize}
\item Adatbázis: \textbf{NEM} kell port publish
\item Backend API: kell, ha host-ról is elérik
\item Frontend: kell, mert böngészőből érik el
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Port példa -- Helyes konfiguráció}
\begin{exampleblock}{Best practice}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
database:
image: postgres # Nincs ports: belső!
networks:
- backend
api:
ports:
- "3001:3001" # Kívülről is elérhető
networks:
- backend
- frontend
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Host hálózat -- Mi az?}
\begin{block}{Host driver}
\begin{itemize}
\item Konténer közvetlenül a host hálózatát használja
\item Nincs port mapping szükség
\item Nincs hálózati izoláció
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{Host hálózat -- Használat}
\begin{block}{Parancs}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
docker run -d --network host nginx
# nginx elérhető: localhost:80 (port mapping nélkül)
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{Host hálózat -- Előnyök és hátrányok}
\begin{exampleblock}{Előnyök}
\begin{itemize}
\item Jobb hálózati teljesítmény
\item Egyszerűbb port-kezelés
\end{itemize}
\end{exampleblock}
\begin{alertblock}{Hátrányok}
\begin{itemize}
\item Nincs izoláció
\item Port ütközések lehetségesek
\item Csak Linuxon működik jól
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{None hálózat -- Mi az?}
\begin{block}{None driver}
\begin{itemize}
\item Teljesen izolált konténer
\item Nincs hálózati hozzáférés
\item Batch feldolgozáshoz, biztonsági feladatokhoz
\end{itemize}
\end{block}
\end{frame}
\begin{frame}[fragile]{None hálózat -- Használat}
\begin{block}{Parancs}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
docker run -d --network none my-batch-processor
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Network inspect}
\begin{block}{Hálózat részletes adatai}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
docker network inspect mynetwork
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Network inspect -- Kimenet}
\begin{block}{Kimenet részlet}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
{
"Name": "mynetwork",
"Driver": "bridge",
"Subnet": "172.20.0.0/16",
"Containers": {
"abc123": {
"Name": "backend",
"IPv4Address": "172.20.0.2/16"
}
}
}
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Egyedi subnet és IP}
\begin{block}{Subnet és fix IP beállítás}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Hálózat egyedi subnet-tel
docker network create \
--subnet=172.28.0.0/16 \
--gateway=172.28.0.1 \
custom-net
# Konténer fix IP-vel
docker run -d --name db \
--network custom-net \
--ip 172.28.0.10 \
postgres:15
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{Egyedi subnet -- Mikor használjuk?}
\begin{block}{Mikor hasznos a fix IP?}
\begin{itemize}
\item Tűzfal szabályokhoz
\item Legacy alkalmazásokhoz
\item Speciális hálózati konfigurációkhoz
\end{itemize}
\end{block}
\begin{alertblock}{Ajánlás}
Lehetőleg DNS neveket használj fix IP-k helyett!
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Docker Compose hálózatok -- Automatikus}
\begin{block}{Compose automatikus hálózat}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
backend:
image: my-app
database:
image: postgres
\end{lstlisting}
Compose automatikusan létrehozza: \texttt{<projektnév>\_default}\\
Mindkét szolgáltatás rajta van, név alapján érik el egymást.
\end{block}
\end{frame}
\begin{frame}[fragile]{Docker Compose hálózatok -- Egyedi}
\begin{exampleblock}{Egyedi hálózatok definiálása}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
frontend:
networks:
- frontend-net
backend:
networks:
- frontend-net
- backend-net
database:
networks:
- backend-net
networks:
frontend-net:
backend-net:
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Compose hálózatok -- Magyarázat}
\begin{block}{Izoláció}
\begin{itemize}
\item \texttt{frontend} $\leftrightarrow$ \texttt{backend}: OK (frontend-net)
\item \texttt{backend} $\leftrightarrow$ \texttt{database}: OK (backend-net)
\item \texttt{frontend} $\leftrightarrow$ \texttt{database}: \textbf{NEM} megy!
\end{itemize}
\end{block}
\begin{exampleblock}{Biztonsági előny}
Az adatbázis nem érhető el közvetlenül a frontendből.
\end{exampleblock}
\end{frame}
\begin{frame}{Links -- Régi módszer}
\begin{alertblock}{Legacy: links}
A \texttt{links} kulcsszó elavult!
\begin{itemize}
\item Régi Docker verziókban használták
\item Helyette: user-defined networks
\item Automatikus DNS feloldás jobb megoldás
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Network alias}
\begin{block}{Alternatív nevek a hálózaton}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
docker run -d --name postgres \
--network app-net \
--network-alias db \
--network-alias database \
postgres:15
\end{lstlisting}
A konténer 3 néven érhető el: \texttt{postgres}, \texttt{db}, \texttt{database}
\end{block}
\end{frame}
\begin{frame}[fragile]{Network alias -- Compose-ban}
\begin{block}{Compose alias}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
postgres:
image: postgres:15
networks:
backend:
aliases:
- db
- database
networks:
backend:
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{Overlay hálózat}
\begin{block}{Overlay driver}
\begin{itemize}
\item Több Docker host közötti hálózat
\item Docker Swarm és Kubernetes használja
\item Konténerek különböző gépeken kommunikálnak
\end{itemize}
\end{block}
\begin{alertblock}{Egyetemi keretek}
Fejlesztéshez bridge hálózat elég, overlay csak produkciós klaszterben szükséges.
\end{alertblock}
\end{frame}
\begin{frame}[fragile]{Troubleshooting -- Alapparancsok}
\begin{block}{Hálózati hibakeresés}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Konténer hálózati beállításai
docker inspect --format \
'{{json .NetworkSettings.Networks}}' backend
# Ping teszt konténerből
docker exec backend ping database
# DNS feloldás konténerből
docker exec backend nslookup database
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}[fragile]{Troubleshooting -- Haladó}
\begin{block}{Haladó hibakeresés}
\begin{lstlisting}[language=bash,basicstyle=\scriptsize\ttfamily]
# Hálózati konténer csatlakoztatás
docker run --rm -it --network mynetwork \
nicolaka/netshoot
# Hálózati port ellenőrzés
docker exec backend curl -v database:5432
\end{lstlisting}
\end{block}
\end{frame}
\begin{frame}{Gyakori problémák 1 -- Nem éri el}
\begin{alertblock}{Probléma: Konténer nem éri el a másikat}
\begin{itemize}
\item \textbf{Ok:} Nem ugyanazon a hálózaton vannak
\item \textbf{Megoldás:} \texttt{docker network connect} vagy közös hálózat
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Gyakori problémák 2 -- DNS nem működik}
\begin{alertblock}{Probléma: DNS névfeloldás nem működik}
\begin{itemize}
\item \textbf{Ok:} Default bridge-en nincs DNS
\item \textbf{Megoldás:} User-defined bridge hálózat használata
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Gyakori problémák 3 -- Port ütközés}
\begin{alertblock}{Probléma: Port already in use}
\begin{itemize}
\item \textbf{Ok:} Host-on már foglalt a port
\item \textbf{Megoldás:} Másik host port (\texttt{-p 3001:3000})
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Gyakori problémák 4 -- Connection refused}
\begin{alertblock}{Probléma: Connection refused}
\begin{itemize}
\item \textbf{Ok:} Alkalmazás csak localhost-on figyel
\item \textbf{Megoldás:} \texttt{0.0.0.0}-ra bind-olás
\end{itemize}
\end{alertblock}
\end{frame}
\begin{frame}{Biztonsági best practices 1}
\begin{exampleblock}{Hálózati biztonság}
\begin{itemize}
\item Külön hálózat minden szolgáltatás-rétegnek
\item Ne publikálj felesleges portokat
\item Adatbázis soha nem érhető el kívülről
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}{Biztonsági best practices 2}
\begin{exampleblock}{Hálózati biztonság -- Fejlesztés}
\begin{itemize}
\item Használj user-defined bridge-et
\item Network alias a rugalmasságért
\item Prod-ban minimális port exposure
\end{itemize}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Komplex hálózat -- 3-rétegű alkalmazás}
\begin{exampleblock}{Frontend réteg}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
version: '3.8'
services:
nginx:
image: nginx:alpine
ports:
- "80:80"
networks:
- frontend
depends_on:
- api
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Komplex hálózat -- API réteg}
\begin{exampleblock}{API réteg}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
api:
build: ./api
networks:
- frontend
- backend
depends_on:
- postgres
- redis
environment:
DB_HOST: postgres
REDIS_HOST: redis
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Komplex hálózat -- Adatbázis réteg}
\begin{exampleblock}{Adatbázis réteg}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
services:
postgres:
image: postgres:15
networks:
- backend
volumes:
- pgdata:/var/lib/postgresql/data
redis:
image: redis:7-alpine
networks:
- backend
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}[fragile]{Komplex hálózat -- Hálózat és volume definíciók}
\begin{exampleblock}{Hálózatok és volume-ok}
\begin{lstlisting}[language=yaml,basicstyle=\scriptsize\ttfamily]
networks:
frontend:
driver: bridge
backend:
driver: bridge
volumes:
pgdata:
\end{lstlisting}
\end{exampleblock}
\end{frame}
\begin{frame}{Komplex hálózat -- Magyarázat}
\begin{block}{Biztonsági izoláció}
\begin{itemize}
\item nginx $\leftrightarrow$ api: frontend hálózat
\item api $\leftrightarrow$ postgres/redis: backend hálózat
\item nginx $\leftrightarrow$ postgres: \textbf{NINCS} közvetlen út
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Összefoglalás -- Lényeg}
\begin{block}{Docker hálózatok}
\begin{itemize}
\item Konténerek közötti kommunikáció alapja
\item Szolgáltatás-felderítés DNS-sel
\item Biztonsági izoláció rétegekkel
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Összefoglalás -- Kulcs koncepciók}
\begin{block}{Fő elemek}
\begin{itemize}
\item \textbf{Bridge}: alapértelmezett, legtöbb esetben elég
\item \textbf{User-defined}: mindig ezt használd (DNS!)
\item \textbf{Compose}: automatikus hálózat létrehozás
\end{itemize}
\end{block}
\end{frame}
\begin{frame}{Összefoglalás -- Aranyszabályok}
\begin{exampleblock}{Aranyszabályok}
\begin{itemize}
\item Konténer név = hostname a hálózaton
\item Csak szükséges portokat publikáld
\item Külön hálózat = jobb biztonság
\end{itemize}
\end{exampleblock}
\end{frame}