
Cum instalezi Docker si Docker Compose pe Debian si Ubuntu
Mai devreme sau mai tarziu, aproape orice tutorial de self-hosting incepe cu aceeasi fraza: “mai intai, instaleaza Docker”. Pare o treaba de cinci secunde si tocmai de aceea atat de multe servere ajung cu un Docker vechi, luat din pachetul gresit, cu un utilizator care trebuie sa scrie sudo in fata fiecarei comenzi si, cel mai grav, cu un port de baza de date deschis catre tot internetul, desi firewall-ul jura ca e inchis. In ghidul asta facem lucrurile cum trebuie, o singura data, pe un VPS proaspat cu Debian 13 sau Ubuntu 24.04, si explicam fiecare pas, ca sa stii ce s-a schimbat pe server si de ce.
La final vei avea Docker Engine si pluginul Docker Compose instalate din repository-ul oficial Docker, vei rula containere ca utilizator normal si vei intelege comportamentul Docker care ii surprinde pe aproape toti: porturile publicate de Docker trec direct pe langa UFW. Reproducem problema pe viu, apoi o reparam intr-un mod suficient de simplu cat sa devina un obicei.
Ce sunt, de fapt, Docker si Docker Compose
Un container este un proces Linux obisnuit, care ruleaza pe kernelul serverului tau, dar cu propria vedere izolata asupra sistemului de fisiere, a retelei si a listei de procese. Din interior arata ca o mica masina dedicata; din exterior, e doar inca un proces. Spre deosebire de o masina virtuala, nu porneste un al doilea sistem de operare in interior, de aceea un container porneste in aproximativ o secunda si foloseste doar memoria de care are nevoie aplicatia lui.
Un container porneste intotdeauna dintr-o imagine: un pachet read-only care contine aplicatia plus tot ce ii trebuie ca sa ruleze (biblioteci, runtime, configuratie implicita). Imaginile se descarca dintr-un registry, de cele mai multe ori Docker Hub. Aceeasi imagine ruleaza la fel pe laptopul tau si pe VPS, si acesta e motivul principal pentru care Docker a devenit modul standard de a livra aplicatii self-hosted.
Ce numim “Docker” sunt, de fapt, cateva componente care lucreaza impreuna:
- Docker Engine (
dockerd), serviciul din fundal care gestioneaza imagini, containere, retele si volume. - containerd si runc, runtime-ul de nivel jos care porneste efectiv procesele containerelor si le supravegheaza.
- CLI-ul
docker, comanda pe care o scrii; vorbeste cu engine-ul printr-un socket aflat la/var/run/docker.sock. - Docker Compose, care iti permite sa descrii unul sau mai multe containere intr-un fisier YAML (
compose.yaml) si sa le pornesti pe toate cu o singura comanda.
Compose este astazi un plugin al comenzii docker, deci scrii docker compose, cu spatiu. Vechiul docker-compose, cu cratima, era Compose v1, scris in Python si care nu mai e intretinut. Multe tutoriale mai vechi inca il folosesc; daca vezi docker-compose up, citeste-l pur si simplu ca docker compose up. La fel, linia version: din capul fisierelor Compose vechi e depasita si poate fi stearsa.
De ce instalam din repository-ul oficial Docker
Atat Debian cat si Ubuntu au in repository-urile lor un pachet numit docker.io, iar Ubuntu ofera Docker si ca snap (installer-ul Ubuntu Server chiar ti-l sugereaza). Functioneaza, dar au dezavantaje:
- Pachetul distributiei ramane in urma. E intretinut de distributie, nu de Docker, asa ca versiunile noi si fix-urile ajung mai tarziu, iar pluginurile Compose si Buildx sunt impachetate diferit.
- Snap-ul ruleaza izolat (confined). Asta produce probleme de permisiuni greu de inteles la bind mount-uri din afara directorului home si la anumite cai de stocare.
- Scriptul de instalare rapida al Docker (de la get.docker.com) e ok pentru masini de test, dar face totul ca root, dintr-o bucata. Pe un server vrem sa vedem fiecare schimbare.
Repository-ul oficial iti da ultima versiune stabila, fix-uri de securitate direct de la sursa si actualizari prin acelasi apt upgrade pe care il rulezi oricum. Documentatia oficiala este pe docs.docker.com
, daca vrei referinta de la sursa.
De ce ai nevoie
- Un VPS cu Debian 13 (trixie) sau Ubuntu 24.04 LTS (noble) proaspat instalat, pe 64 de biti (amd64 sau arm64).
- Un utilizator obisnuit cu drepturi
sudo. Nu e nevoie sa te loghezi ca root. - Acces SSH la server. Daca SSH asculta pe alt port decat 22, noteaza-l, conteaza la pasul 6.
- Cel putin 1 GB RAM; 2 GB e mai confortabil daca vrei sa rulezi si o baza de date langa aplicatie.
- Aproximativ 15 minute.
KVM sau LXC: unde ruleaza Docker?
Pe un VPS KVM ai propriul kernel, iar Docker merge din prima. Intr-un container LXC neprivilegiat imparti kernelul cu host-ul, iar Docker are nevoie ca optiunile “nesting” (si de obicei “keyctl”) sa fie activate pe host. Fara ele, dockerd nu porneste sau containerele cad cu erori de permisiuni legate de mount-uri ori setari sysctl, iar regulile de firewall din interiorul containerului pot sa nu se comporte cum descriem mai jos. Daca ai un plan LXC, cere suportului sa activeze nesting, sau alege un VPS
KVM pentru proiecte bazate pe Docker.
Cat de mare trebuie sa fie VPS-ul?
Docker in sine e usor. Engine-ul si containerd folosesc impreuna in jur de 75 MB RAM in repaus, iar fiecare container pornit adauga un mic proces de supraveghere (“shim”) de cativa megabytes. Ce decide cu adevarat dimensiunea VPS-ului sunt aplicatiile din containere.
In practica, un VPS cu 1 GB RAM ruleaza confortabil Docker plus doua-trei servicii mici, in timp ce o baza de date plus o aplicatie Node.js sau PHP se simt mai bine cu 2 GB. Conteaza si discul: o imagine are de obicei intre 10 MB si 1 GB, asa ca pastreaza cel putin 10 GB liberi pentru datele Docker din /var/lib/docker.
Cum instalezi Docker pe Ubuntu si Debian: planul
Pasii 1-4 se fac o singura data; pasii 5-7 sunt obiceiurile care fac Docker comod si sigur in fiecare zi. Ruleaza toate comenzile prin SSH, cu utilizatorul tau cu sudo.
Pasul 1: Actualizeaza sistemul si elimina pachetele in conflict
Pornim de la un sistem la zi, ca pachetele pe care le instalam apoi sa gaseasca dependinte actuale:
sudo apt-get update
sudo apt-get upgrade -y
update reimprospateaza lista de pachete disponibile, upgrade instaleaza versiunile mai noi. Daca s-a instalat si un kernel nou, reporneste inainte sa mergi mai departe. Aici Debian si Ubuntu difera. Pe Ubuntu, un restart necesar e semnalat printr-un fisier:
# Ubuntu: afiseaza "*** System restart required ***" daca e nevoie de restart
cat /var/run/reboot-required 2>/dev/null || echo "No reboot needed"
Pe Debian, fisierul acesta nu este creat implicit, asa ca compari kernelul care ruleaza cu cel mai nou instalat:
# Debian: kernelul curent vs kernelurile instalate
uname -r
ls /boot/vmlinuz-*
Daca cea mai noua versiune vmlinuz din /boot e mai mare decat ce arata uname -r, ruleaza sudo reboot si reconecteaza-te dupa un minut.
Apoi eliminam eventualele pachete Docker care ar putea intra in conflict cu cele oficiale. Pe un VPS nou, de obicei nu e nimic de sters, dar verificarea nu costa nimic:
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do
sudo apt-get remove -y "$pkg"
done
Bucla incearca sa stearga fiecare pachet pe rand. Mesaje ca “Package ‘docker.io’ is not installed, so not removed” sunt normale, iar pe Debian vei vedea si “Unable to locate package docker-compose-v2”, pentru ca acel pachet exista doar pe Ubuntu. Ambele sunt inofensive. Daca aveai un Docker mai vechi, imaginile si volumele lui din /var/lib/docker raman pe disc.
Pe Ubuntu, verifica si ca Docker nu a fost instalat ca snap la instalarea sistemului:
snap list 2>/dev/null | grep -i docker && sudo snap remove docker
Daca nu apare nimic, nu exista niciun snap de sters.
Pasul 2: Adauga repository-ul oficial Docker
APT, managerul de pachete din Debian si Ubuntu, instaleaza software din repository-uri: servere care publica liste de pachete semnate. Ca sa folosim repository-ul Docker avem nevoie de doua lucruri: cheia GPG Docker, cu care APT verifica faptul ca pachetele vin cu adevarat de la Docker, si un fisier de surse care ii spune lui APT unde se afla repository-ul.
Mai intai, uneltele si directorul pentru cheie (la fel pe ambele distributii):
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
Acum partea care difera: Docker are repository-uri separate pentru Debian si pentru Ubuntu, iar tu trebuie sa il folosesti pe cel potrivit sistemului tau. Amestecarea lor e cel mai frecvent motiv pentru care instalarea esueaza.
Pe Debian 13
sudo curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
Pe Ubuntu 24.04
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc
sudo tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/ubuntu
Suites: $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF
Bucata $(. /etc/os-release ...) citeste automat numele de cod al versiunii tale, iar tee afiseaza fisierul tocmai scris, cu Suites: trixie pe Debian 13 sau Suites: noble pe Ubuntu 24.04. Acesta este formatul modern “deb822” pentru sursele APT; face acelasi lucru ca fisierele docker.list pe un singur rand din ghidurile mai vechi, dar e mai usor de citit.
Reimprospateaza listele de pachete:
sudo apt-get update
In output ar trebui sa apara o linie de la download.docker.com (de exemplu Get:5 https://download.docker.com/linux/debian trixie InRelease) si nicio eroare. Daca vezi NO_PUBKEY sau un 404, sari la sectiunea de depanare.
Pasul 3: Instaleaza Docker Engine si pluginul Compose
O singura comanda instaleaza tot:
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Ce este fiecare pachet:
docker-ce: Docker Engine, serviciuldockerd(“ce” vine de la Community Edition).docker-ce-cli: comandadocker.containerd.io: runtime-ul de containere pe care se bazeaza engine-ul.docker-buildx-plugin: builder-ul modern de imagini folosit dedocker build.docker-compose-plugin: Compose v2, adica comandadocker compose.
Verifica faptul ca APT a luat Docker din repository-ul oficial, nu din cel al distributiei:
apt-cache policy docker-ce | head -n 4
Versiunea de la “Candidate” trebuie sa fie urmata de o linie care indica download.docker.com. Atat pe Debian cat si pe Ubuntu, pachetul porneste serviciul Docker si il activeaza automat la boot. Verifica:
sudo systemctl status docker --no-pager
Cauta Active: active (running). Daca ai nevoie de o versiune anume (de exemplu ca sa fie identica cu alt server), vezi versiunile disponibile cu apt-cache madison docker-ce si instaleaza cu docker-ce=<VERSIUNE>; pentru un server nou, ultima versiune stabila e alegerea corecta.
Pasul 4: Verifica instalarea
Docker ofera o imagine de test minuscula exact pentru momentul asta:
sudo docker run --rm hello-world
Output asteptat (prescurtat):
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
...
Hello from Docker!
This message shows that your installation appears to be working correctly.
In aceste cateva secunde Docker a contactat Docker Hub, a descarcat imaginea, a creat un container, l-a rulat, i-a afisat mesajul si, datorita lui --rm, a sters containerul cand acesta s-a oprit. Acesta e ciclul complet de viata al unui container.
Acum verifica ambele unelte:
docker --version
docker compose version
Ar trebui sa vezi Docker version XX.Y.Z, build ... si Docker Compose version v2.Y.Z, numerele exacte depinzand de momentul instalarii. Observa ca aici nu am folosit sudo: afisarea versiunii nu are nevoie de engine. Rularea containerelor are, si asta rezolvam in pasul urmator.
Pasul 5: Ruleaza Docker fara sudo
Comanda docker vorbeste cu engine-ul prin socket-ul /var/run/docker.sock, care apartine utilizatorului root si grupului docker. Installer-ul a creat deja grupul; trebuie doar sa ne adaugam utilizatorul in el:
sudo usermod -aG docker $USER
-aG inseamna “adauga in grup” (append), fara sa te scoata din celelalte grupuri (daca uiti -a, poti pierde drepturile de sudo, o greseala clasica). Apartenenta la grupuri se citeste la login, asa ca iesi din SSH si conecteaza-te din nou. Apoi verifica:
groups
docker run --rm hello-world
groups trebuie sa contina docker, iar hello-world ar trebui sa ruleze acum fara sudo. Daca nu vrei sa te reconectezi, newgrp docker deschide un subshell cu noul grup activ, dar doar in acel terminal.
Important: apartenenta la grupul docker este echivalenta cu acces root. Oricine e in grup poate porni un container care monteaza sistemul de fisiere al host-ului si poate modifica orice pe el. Adauga in grup doar administratori de incredere. Daca un utilizator trebuie sa foloseasca Docker fara sa fie root, uita-te la rootless mode, in care tot engine-ul ruleaza ca utilizator neprivilegiat (cu anumite limitari la retea si la porturile sub 1024).
Pasul 6: Intelege si repara ocolirea UFW
Acesta e pasul pe care majoritatea ghidurilor il sar si cel care produce incidente reale.
Ce este un port si ce inseamna “publicare”
Un port este un numar intre 1 si 65535 care permite unei singure adrese IP sa ofere mai multe servicii de retea: SSH asculta de obicei pe 22, serverele web pe 80 (HTTP) si 443 (HTTPS), PostgreSQL pe 5432. Containerele traiesc intr-o retea interna privata (implicit 172.17.0.0/16, in spatele unui bridge virtual numit docker0), invizibila din afara. Cand publici un port cu -p 8080:80, ii spui lui Docker: preia conexiunile care ajung pe portul 8080 al host-ului si trimite-le pe portul 80 din container. Scris asa, fara adresa IP, portul este publicat pe toate interfetele, IPv4 si IPv6, ceea ce pe un VPS inseamna internetul public.
De ce UFW nu vede porturile Docker
UFW (Uncomplicated Firewall) este o interfata prietenoasa peste filtrul de pachete din Linux. Cand permiti sau blochezi un port, UFW scrie reguli verificate in lantul INPUT, drumul pe care il parcurg pachetele adresate serverului insusi.
Docker publica porturile altfel. Adauga o regula DNAT (translatare a adresei de destinatie) care rescrie pachetele venite pe portul 8080 spre adresa privata a containerului, de exemplu 172.17.0.2:80, inainte ca lantul INPUT sa fie consultat. Din punctul de vedere al kernelului, pachetul nu mai e destinat host-ului; trebuie trimis mai departe, catre alta retea, deci trece prin lantul FORWARD. Docker isi pune propriile lanturi in capul lui FORWARD si accepta traficul acolo. Regulile UFW nu il vad niciodata.
Vezi cu ochii tai
Hai sa reproducem problema. UFW e preinstalat (dar inactiv) pe Ubuntu; pe Debian, instaleaza-l mai intai:
# Doar pe Debian, Ubuntu il are deja
sudo apt-get install -y ufw
Activam un firewall strict care permite doar SSH. Permite SSH inainte sa activezi UFW, altfel te blochezi singur afara (inlocuieste 22 cu portul tau SSH daca l-ai schimbat):
sudo ufw allow 22/tcp
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw enable
sudo ufw status verbose
Raspunde y la avertismentul despre conexiunile SSH. Statusul ar trebui sa arate Status: active, Default: deny (incoming) si o singura regula pentru 22/tcp. Acum pornim un server web de test, publicat in modul “obisnuit”:
docker run -d --name ufw-test -p 8080:80 nginx:1.28-alpine
docker ps --format 'table {{.Names}}\t{{.Ports}}'
Coloana PORTS arata 0.0.0.0:8080->80/tcp, [::]:8080->80/tcp: asculta pe toate adresele. De pe calculatorul tau (nu de pe VPS), incearca:
curl -I http://IP_VPS:8080
Primesti HTTP/1.1 200 OK, desi UFW blocheaza tot in afara de SSH si ufw status nu spune nimic despre 8080. Ca sa vezi motivul, uita-te pe VPS la lantul FORWARD:
sudo iptables -S FORWARD | head -n 6
De obicei vei vedea salturile Docker (DOCKER-USER, DOCKER-FORWARD sau similare, in functie de versiune) in partea de sus, inaintea lanturilor ufw-before-forward ale UFW. Debian 13 si Ubuntu 24.04 folosesc implicit varianta de iptables bazata pe nftables; logica e exact aceeasi.
Solutia: publica pe 127.0.0.1
Cea mai simpla si mai robusta solutie e sa ii spui lui Docker pe ce adresa sa publice. 127.0.0.1 este adresa de loopback, accesibila doar de pe serverul insusi:
docker rm -f ufw-test
docker run -d --name ufw-test -p 127.0.0.1:8080:80 nginx:1.28-alpine
curl -I http://127.0.0.1:8080
Pe VPS, curl raspunde in continuare cu 200 OK. De pe calculatorul tau, curl -I http://IP_VPS:8080 esueaza acum cu “connection refused” sau timeout, iar docker ps arata 127.0.0.1:8080->80/tcp. Serviciul merge, doar ca nu mai e public. Facem curat:
docker rm -f ufw-test
Acestea sunt regulile pe care le aplicam pe fiecare server pe care il administram:
- Publica serviciile interne doar pe 127.0.0.1: panouri de administrare, baze de date, aplicatii care stau in spatele unui proxy.
- Nu publica deloc cand containerele vorbesc doar intre ele. Containerele din acelasi proiect Compose impart o retea si se gasesc dupa numele serviciului (de exemplu
db:5432), fara niciun port publicat. - Doar reverse proxy-ul sta in fata lumii. Un reverse proxy (Caddy, Nginx sau Traefik) asculta pe 80 si 443, se ocupa de HTTPS si trimite cererile catre
127.0.0.1:8080. Daca proxy-ul ruleaza pe host, deschide 80 si 443 in UFW; daca ruleaza intr-un container, acestea sunt singurele porturi publicate public. - Nu seta
"iptables": falsein configuratia Docker ca sa “rezolvi” problema. Strica reteaua containerelor in moduri subtile (fara internet spre exterior, fara publicare de porturi functionala). - Avansat: Docker rezerva un lant numit
DOCKER-USERpentru regulile tale de filtrare. Ele sunt evaluate dupa DNAT, deci vad portul containerului, nu pe cel al host-ului: ca sa blochezi portul 8080 al host-ului ai nevoie de ceva de genulsudo iptables -I DOCKER-USER -p tcp -m conntrack --ctorigdstport 8080 --ctdir ORIGINAL -j DROP, iar persistenta trebuie sa o rezolvi singur. Merge, dar legarea pe 127.0.0.1 e mult mai greu de gresit.
Mai jos, in sectiunea despre daemon.json, adaugam si o plasa de siguranta care face din 127.0.0.1 adresa implicita.
Pasul 7: Primul tau proiect Docker Compose
Comenzile docker run lungi devin repede obositoare. Compose pastreaza aceleasi informatii intr-un fisier, deci configuratia ta e documentata, repetabila si usor de salvat in backup. Cream un mic site servit de Nginx, publicat in siguranta pe localhost.
mkdir -p ~/apps/hello/html
cd ~/apps/hello
echo '<h1>Salut din Docker Compose</h1>' > html/index.html
nano compose.yaml
Lipeste continutul de mai jos, salveaza cu Ctrl+O, Enter si iesi cu Ctrl+X:
services:
web:
image: nginx:1.28-alpine
restart: unless-stopped
ports:
- "127.0.0.1:8080:80"
volumes:
- ./html:/usr/share/nginx/html:ro
Pe rand: services enumera containerele proiectului, iar web e numele ales pentru al nostru. image fixeaza Nginx pe ramura 1.28, pe Alpine Linux. Evitam :latest pentru ca poate sari la o versiune majora noua la urmatorul pull si poate strica lucrurile fara avertisment, in timp ce o ramura fixata primeste in continuare patch-uri (verifica pe Docker Hub tag-ul stabil curent cand citesti asta). restart: unless-stopped reporneste containerul dupa un crash sau un reboot, cu exceptia cazului in care l-ai oprit intentionat. ports publica portul 80 al containerului pe portul 8080 al host-ului, doar pe 127.0.0.1, exact ca la pasul 6. volumes monteaza directorul html in container read-only (:ro), deci editezi site-ul pe host si Nginx il serveste. Nu exista linie version:: Compose actual nu are nevoie de ea.
Pornim proiectul in fundal (-d inseamna detached):
docker compose up -d
docker compose ps
curl http://127.0.0.1:8080
docker compose ps trebuie sa arate serviciul web ca Up, iar curl intoarce linia noastra <h1>. Ca sa vezi pagina in browserul de pe calculatorul tau fara sa deschizi vreun port, foloseste un tunel SSH. Ruleaza asta pe calculatorul tau:
ssh -L 8080:127.0.0.1:8080 utilizator@IP_VPS
Cat timp sesiunea e deschisa, http://localhost:8080 in browser afiseaza pagina, transportata prin conexiunea SSH criptata. E si o metoda excelenta de a ajunge la panouri de administrare care nu ar trebui sa fie niciodata publice.
Comenzile Compose pe care le vei folosi zilnic, rulate mereu din directorul proiectului:
docker compose logs -f # urmareste logurile, Ctrl+C pentru oprire
docker compose pull # descarca imagini mai noi pentru tag-urile fixate
docker compose up -d # aplica modificarile (recreeaza ce s-a schimbat)
docker compose restart web # reporneste un singur serviciu
docker compose down # opreste si sterge containerele (volumele raman)
Setari implicite utile in /etc/docker/daemon.json
Doua setari merita adaugate pe orice host cu Docker. Prima, rotirea logurilor: implicit, Docker pastreaza logurile containerelor in fisiere JSON care cresc la nesfarsit, iar un container vorbaret iti poate umple discul in cateva saptamani. A doua, o adresa implicita de publicare, ca un -p 8080:80 uitat sa ajunga pe localhost, nu pe internet.
sudo nano /etc/docker/daemon.json
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"ip": "127.0.0.1"
}
Asa pastrezi cel mult trei fisiere de log de 10 MB per container, iar 127.0.0.1 devine adresa folosita cand o mapare de port nu are IP explicit. Valideaza si aplica:
sudo dockerd --validate --config-file=/etc/docker/daemon.json
sudo systemctl restart docker
Prima comanda ar trebui sa afiseze configuration OK. Repornirea Docker opreste scurt containerele; cele cu restart policy revin singure. Doua lucruri de stiut: setarile de log se aplica doar containerelor create dupa modificare (ruleaza docker compose up -d --force-recreate in fiecare proiect), iar cu adresa implicita setata, un serviciu pe care chiar il vrei public trebuie sa o spuna explicit, de exemplu "0.0.0.0:443:443". Ne place asta: expunerea publica devine o decizie constienta.
Depanare si greseli frecvente
“permission denied while trying to connect to the Docker daemon socket”
Utilizatorul tau nu e inca in grupul docker sau sesiunea a pornit inainte sa il adaugi. Ruleaza groups; daca lipseste docker, repeta pasul 5, apoi iesi complet si conecteaza-te din nou (nu ajunge sa inchizi un tab daca clientul SSH reutilizeaza conexiunile).
“Unable to locate package docker-ce” sau “has no installation candidate”
APT nu vede repository-ul Docker. Verifica cat /etc/apt/sources.list.d/docker.sources: pe Debian, URI-ul trebuie sa contina /linux/debian si suita sa fie trixie; pe Ubuntu, /linux/ubuntu si noble. Corecteaza fisierul, ruleaza din nou sudo apt-get update si citeste output-ul dupa erori.
“NO_PUBKEY” sau erori de semnatura
Fisierul cheii lipseste, e gol sau nu poate fi citit. Verifica cu ls -l /etc/apt/keyrings/docker.asc: ar trebui sa aiba cativa KB si sa fie citibil de toti (-rw-r--r--). Descarca-l din nou cu liniile curl si chmod de la pasul 2.
“docker-compose: command not found”
Folosesti sintaxa Compose v1. Scrie docker compose, cu spatiu, si nu instala vechiul docker-compose in Python.
“port is already allocated” sau “address already in use”
Altceva asculta deja pe acel port al host-ului. Il gasesti cu sudo ss -tlnp | grep ':8080', apoi fie il opresti, fie alegi alt port pe host, de exemplu 127.0.0.1:8081:80.
Docker nu porneste deloc
Citeste logul engine-ului: sudo journalctl -u docker -n 50 --no-pager. Intr-un container LXC neprivilegiat, erorile despre overlay, sysctl sau keyctl inseamna ca nesting nu e activat pe host. O greseala de sintaxa in daemon.json opreste si ea serviciul, de aceea il validam inainte.
Te-ai blocat afara dupa activarea UFW
Ai activat UFW fara sa permiti portul SSH. Intra prin consola VPS-ului din panoul de control si ruleaza sudo ufw allow 22/tcp (sau portul tau personalizat).
Discul se umple in continuu
Imaginile vechi si containerele oprite se aduna. docker system df arata ce ocupa spatiu, iar docker image prune sterge imaginile nefolosite. Ai grija cu docker system prune --volumes: sterge si volumele care nu sunt atasate de niciun container, iar acestea pot contine date importante.
Note de securitate
- Grupul
dockerinseamna root. Trateaza apartenenta exact ca pe drepturile de sudo. - Nu expune niciodata API-ul Docker. Nu pune
dockerdsa asculte pe TCP (porturile 2375/2376) si ai grija la containerele care monteaza/var/run/docker.sock: cine controleaza socket-ul controleaza serverul. - Publica implicit pe 127.0.0.1 si verifica ce e cu adevarat public cu
docker pssisudo ss -tlnp. Dupa ce ai instalat Docker,ufw statusnu mai spune toata povestea. - Fixeaza tag-urile imaginilor si actualizeaza constient. Foloseste ramuri precise (
nginx:1.28-alpine,postgres:17), prefera imaginile oficiale sau pe cele publicate de proiect si ruleaza regulatdocker compose pull && docker compose up -d. - Tine si Docker la zi. Pachetele Docker se actualizeaza cu
sudo apt-get update && sudo apt-get upgrade. Daca folosestiunattended-upgrades, tine minte ca implicit aplica doar actualizarile de securitate Debian sau Ubuntu, nu pachetele din repository-ul Docker, deci include Docker in rutina ta manuala de update. - Roteste logurile si urmareste spatiul pe disc, ca mai sus. Un disc plin doboara toate containerele deodata.
- Fa backup la ce trebuie: directoarele cu fisierele Compose si volumele numite (din
/var/lib/docker/volumes). Containerele in sine sunt de unica folosinta.
Deci, e Docker gata pe serverul tau?
Acum ai Docker Engine si Compose v2 din repository-ul oficial, un utilizator care ruleaza containere fara sudo si cea mai importanta lectie despre reteaua Docker: un port publicat ignora UFW, cu exceptia cazului in care il legi pe 127.0.0.1 sau pui un reverse proxy in fata. Cu setarile din daemon.json, chiar si o mapare de port uitata ramane privata. De aici incolo, orice aplicatie self-hosted e la un compose.yaml si un docker compose up -d distanta.
Daca ai nevoie de un loc unde sa le rulezi, un VPS KVM din data center-ul nostru din Romania e gata in cateva minute, cu Debian 13 sau Ubuntu 24.04. Iar daca preferi ca altcineva sa instaleze, sa securizeze si sa actualizeze Docker si containerele tale, echipa noastra de administrare servere face exact asta, zi de zi.
Intrebari frecvente
Este Docker Compose inclus cand instalez Docker pe Ubuntu?
Este un pachet separat. Din repository-ul oficial Docker se numeste docker-compose-plugin si l-am instalat la pasul 3, impreuna cu engine-ul. Il folosesti ca docker compose, cu spatiu.
Pot rula Docker pe un VPS cu 1 GB RAM?
Da. Docker in sine are nevoie de sub 100 MB RAM; adevarata intrebare e ce rulezi in el. Cateva servicii usoare incap fara probleme, in timp ce o baza de date plus o aplicatie mai grea merita 2 GB (sau macar putin swap).
Cum actualizez Docker mai tarziu?
Ruleaza sudo apt-get update && sudo apt-get upgrade. Serviciul Docker se reporneste in timpul actualizarii, iar containerele cu restart policy revin automat. Imaginile se actualizeaza separat, pe fiecare proiect, cu docker compose pull && docker compose up -d.
Cum dezinstalez complet Docker?
Stergi pachetele, apoi directoarele de date. A doua comanda sterge toate imaginile, containerele si volumele, deci fa backup inainte:
sudo apt-get purge -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras
sudo rm -rf /var/lib/docker /var/lib/containerd
sudo rm /etc/apt/sources.list.d/docker.sources /etc/apt/keyrings/docker.asc
Merge ghidul si pe Debian 12, Ubuntu 22.04 sau servere ARM?
Da. Comenzile pentru repository citesc automat numele de cod, deci functioneaza si pe Debian 12 si Ubuntu 22.04. Docker publica si pachete pentru arm64, iar majoritatea imaginilor oficiale sunt disponibile pentru arm64.