Salt la conținut

Setări cookie-uri

Alegeți pentru fiecare tip ce cookie-uri permiteți. Puteți modifica oricând alegerea prin Setări cookie-uri, în partea de jos a fiecărei pagini. Declarație de confidențialitate

Necesare

Mereu active

Necesare pentru autentificare, pentru păstrarea coșului și pentru a vă reține alegerile. Acestea sunt mereu active.

Ce cookie-uri?
  • weboke_sessie, weboke_klant, weboke_remember: sesiunea și menținerea autentificării
  • weboke_basket: coșul de cumpărături
  • wkBtwIncl: afișarea prețurilor cu sau fără TVA
  • wok_cookies: alegerea privind cookie-urile, 12 luni

Măsoară ce reclamă duce la o vizită sau o comandă, ca să nu plătim pentru reclame care nu aduc nimic.

Ce cookie-uri?
  • Google Ads prin Google Tag Manager (_gcl_au, _gcl_aw), până la 90 de zile
  • OpenAI Ads, reclame în ChatGPT
  • wok_aff: prin ce partener ați ajuns la noi (program de afiliere), 60 de zile

4,6

Țară și limbă

Fiecare țară are propriul site, cu prețurile și TVA-ul pentru țara respectivă.

Vedeți

Înțelegerea containerelor

Modulul 9: Docker și docker compose · Timp de citire: 10 minute

Obiectivul lecției: După această lecție veți putea explica ce este un container, cum diferă de o mașină virtuală, unde rămân datele unui container și când Docker are sens pe serverul dumneavoastră.

Noțiuni cheie: image, container, strat, registry (Docker Hub), tag, digest, namespaces, cgroups, kernel partajat, sistem de fișiere volatil, volum, bind mount, publicarea porturilor, image oficial

De ce containere?

Să presupunem că doriți să rulați pe VPS-ul dumneavoastră o pagină de stare care arată dacă site-ul funcționează. Programul este scris în Node.js, are nevoie de o anumită versiune a acestuia, plus vreo două sute de biblioteci. Fără containere, instalați toate acestea pe server, alături de serverul web și de baza de date. Un an mai târziu doriți un al doilea program, care are nevoie de altă versiune de Node.js. Atunci începe bătaia de cap.

Un container rezolvă această problemă. Autorul programului livrează programul împreună cu tot ce îi trebuie, într-un singur pachet: un image. Pe server porniți acel image ca un container. Programul își vede propriile fișiere, propriul Node.js, propriile biblioteci și nu intră în conflict cu restul serverului. Nu mai aveți nevoie de el? Ștergeți containerul și image-ul, iar în /usr sau /etc nu rămâne nimic.

Docker este cel mai cunoscut instrument pentru descărcarea image-urilor și rularea containerelor. Există alternative (Podman, containerd însuși), dar noțiunile sunt aceleași peste tot.

Image, container și registry

Trei cuvinte pe care le veți întâlni mereu:

  • Image: un șablon numai pentru citire, cu un sistem de fișiere (program, biblioteci, setări) și comanda care trebuie pornită. Un image este alcătuit din straturi: un strat de bază (de exemplu un Debian minimal), peste acesta un strat cu Node.js, iar peste acesta programul. Două image-uri cu același strat de bază împart acel strat pe disc.
  • Container: o instanță în rulare (sau oprită) a unui image. Peste straturile numai pentru citire, containerul primește un strat de scriere propriu, subțire. Dintr-un singur image puteți porni zece containere.
  • Registry: locul în care se află image-urile, cum ar fi Docker Hub (docker.io) sau registry-ul GitHub (ghcr.io). Docker descarcă un image cu docker pull.

Numele unui image arată astfel:

louislam/uptime-kuma:2
caddy:2
vaultwarden/server:latest

Partea de după cele două puncte este tag-ul: o etichetă pentru o versiune. Un tag se poate schimba: caddy:2 indică astăzi alt build decât peste trei luni, de îndată ce apare o nouă versiune 2.x. Dacă doriți să fixați exact ce image rulați, folosiți digest-ul: o amprentă a conținutului, cum ar fi caddy@sha256:.... Aceasta nu se schimbă niciodată. Tag-ul latest este doar un nume ales de autor; nu înseamnă automat "cea mai nouă versiune stabilă" și de aceea este o alegere proastă dacă doriți să știți ce rulează.

Nu este o mașină virtuală

Un container seamănă cu o mașină virtuală mică, dar nu este una. Această diferență contează pentru securitate.

Mașină virtuală (cum este VPS-ul dumneavoastră)Container
KernelKernel propriuFolosește kernelul gazdei
PornireDe la câteva secunde la câteva minute, un întreg sistem de operareDe obicei într-o secundă, doar programul
SepararePrin hypervisor, la nivel hardwarePrin kernel: namespaces și cgroups
DimensiuneGigabytesAdesea zeci până la sute de megabytes

Un container este de fapt un proces obișnuit pe server, pe care kernelul îl plasează într-un mediu izolat:

  • namespaces fac ca procesul să aibă propria perspectivă asupra fișierelor, proceselor, rețelei și utilizatorilor. În container, programul pare să fie procesul numărul 1 și nu vede restul serverului;
  • cgroups limitează cât procesor și câtă memorie poate folosi.

Deoarece toate containerele folosesc același kernel, separarea este mai puțin strictă decât între două VPS-uri. O vulnerabilitate în kernel sau un container care primește prea multe drepturi poate afecta gazda. De aici regulile din acest modul: rulați doar image-uri în care aveți încredere, nu dați containerelor mai multe drepturi decât este nevoie și nu montați niciodată /var/run/docker.sock sau / într-un container (lecția 9.3 și 10.2).

Unde rămân datele dumneavoastră?

Aceasta este capcana clasică pentru începători. Stratul de scriere al unui container este volatil: dacă ștergeți containerul (de exemplu la o actualizare, lecția 9.4), tot ce a scris programul acolo dispare. De aceea, datele care trebuie păstrate se pun în afara containerului:

  • Volum: un spațiu de stocare administrat de Docker însuși (în /var/lib/docker/volumes/). Îi dați un nume, de exemplu uptime-kuma, și îl legați de un director din container: -v uptime-kuma:/app/data.
  • Bind mount: un director obișnuit de pe server pe care îl montați în container: -v /srv/vaultwarden:/data. Este practic, deoarece vedeți fișierele direct și le includeți ușor în backup (modulul 8).

Un container cu volume bine configurate poate fi șters și recreat fără să pierdeți nimic. Exact așa funcționează actualizarea: descărcați noul image, ștergeți containerul vechi, porniți un container nou pe aceleași volume. De aceea, includeți volumele în planul dumneavoastră de backup (lecția 8.1).

Publicarea porturilor

Un container are propria rețea. Un program web care ascultă în container pe portul 3001 nu este accesibil din afara serverului până când nu publicați acel port: -p 3001:3001 (port gazdă:port container). Atenție: fără adres, Docker publică portul pe toate adresele serverului, adică 0.0.0.0 și [::]. Asta înseamnă: accesibil din tot internetul, iar Docker face acest lucru ocolind ufw (lecția 9.3). Obiceiul sigur este publicarea pe loopback, -p 127.0.0.1:3001:3001, cu un reverse proxy cu https în față (lecția 9.4).

Cine creează image-ul?

Un image este software al altcuiva, care poate rula ca root pe serverul dumneavoastră. De aceea, verificați cine este autorul:

  • Docker Official Images (cum ar fi caddy, nginx, postgres) sunt întreținute de Docker împreună cu autorii;
  • image-urile autorului însuși (cum ar fi louislam/uptime-kuma și vaultwarden/server), recunoscute după numele indicat pe site-ul proiectului;
  • image-uri de la necunoscuți, cu nume asemănătoare: nu le folosiți.

Folosiți întotdeauna numele indicat pe site-ul oficial al proiectului, nu primul rezultat al unei căutări.

Când da, când nu?

Docker este util pentru programe pe care autorul le livrează ca image, pentru servicii pe care doriți să le puteți șterge sau muta rapid și pentru a rula unul lângă altul mai multe programe cu cerințe diferite. Pentru baza serverului (SSH, firewall, actualizări) nu folosiți containere. Iar un singur site cu nginx și PHP din depozitul de pachete (lecția 7.2) funcționează foarte bine fără Docker. Un container adaugă un strat pe care trebuie să îl înțelegeți și să îl actualizați; folosiți-l atunci când aduce un beneficiu.

Rezumat

  • Un image este un șablon numai pentru citire, alcătuit din straturi; un container este o instanță în rulare, cu propriul strat de scriere.
  • Containerele folosesc kernelul gazdei și sunt izolate prin namespaces și cgroups: mai ușoare decât o mașină virtuală, dar mai puțin strict separate.
  • Stratul de scriere este volatil: datele permanente se pun într-un volum sau într-un bind mount, iar acestea trebuie incluse în backup.
  • Un tag se poate schimba, un digest nu; latest spune puțin.
  • Publicați porturile pe 127.0.0.1 și folosiți doar image-uri de la autor sau image-uri oficiale.

Test (quiz)

1. Care este cea mai importantă diferență dintre un container și o mașină virtuală?



2. Rulați un container fără volum. Programul își păstrează setările în /app/data. Ștergeți containerul pentru a porni o versiune nouă. Ce se întâmplă cu setările?



3. De ce image:latest nu este o alegere bună într-un mediu de producție?



4. Porniți docker run -d -p 8080:80 nginx. De la ce adrese este accesibil portul 8080?



5. O căutare vă afișează image-ul vaultwarden-server-official/vaultwarden. Ce faceți?



Exercițiu

Exercițiul O9.1: Container sau nu? Alegeți două programe pe care doriți să le rulați pe server (sau folosiți ca exemplu Uptime Kuma și un site WordPress). Pentru fiecare program, aflați dacă autorul livrează un image oficial și sub ce nume, ce tag ați alege, ce director conține datele permanente și pe ce port ascultă. Explicați apoi dacă l-ați rula într-un container sau din depozitul de pachete și de ce.

Exercițiul O9.1: Container sau nu?

Acest exercițiu îl faceți singur; nimeni nu îl verifică. Bifați ce ați făcut și marcați exercițiul ca finalizat.




Bifele și notițele dumneavoastră rămân doar în acest browser; nu le trimitem nicăieri. Dacă sunteți autentificat, păstrăm în Cursurile mele doar faptul că ați finalizat exercițiul.

Lecturi suplimentare

Un moment…

Configurați domeniile

Stabiliți pentru fiecare domeniu nameserverele, legătura cu hostingul și cine devine titularul.

Se încarcă domeniile…