Docker 101: Osnove i praksa

Ako vam je dosadno slušati kako vaši suradnici hvale Dockera i njegove prednosti u svakoj prilici ili vam je dosadno klimati glavom i odlaziti svaki put kad se nađete u jednom od ovih razgovora, došli ste u pravu mjesto.

Također, ako tražite novi izgovor da odlutate bez otkaza, nastavite čitati i zahvalit ćete mi se kasnije.

Lučki radnik

Evo definicije Dockera, prema Wikipediji:

Docker je računalni program koji vrši virtualizaciju na razini operativnog sustava.

Prilično jednostavno, zar ne? Pa ne baš. U redu, evo moje definicije što je docker:

Docker je platforma za stvaranje i pokretanje spremnika od slika .

Još uvijek izgubljen? Bez brige, to je zato što vjerojatno ne znate što su spremnici ili slike .

Slike su pojedinačne datoteke koje sadrže sve ovisnosti i konfiguracije potrebne za pokretanje programa, dok su spremnici instance tih slika. Idemo naprijed i vidjeti primjer toga u praksi kako bismo stvari učinili jasnijima.

Važna napomena: Prije nego što nastavite, pobrinite se da instalirate docker koristeći preporučene korake za vaš operativni sustav.

Dio 1. "Zdravo, Svijete!" s Pythonove slike

Recimo da na vašem računalu nemate instaliran Python - ili barem ne najnoviju verziju - i potreban vam je python za ispis "Hello, World!" u vašem terminalu. Što radiš? Koristite docker!

Samo naprijed i pokrenite sljedeću naredbu:

docker run --rm -it python:3 python

Ne brinite, objasnit ću tu naredbu u sekundi, ali trenutno vjerojatno vidite nešto poput ovoga:

To znači da smo trenutno unutar listi kontejner stvorio iz piton 3 lučki radnik slike, trčanje pythonnaredbu. Da biste dovršili primjer, upišite print("Hello, World!")i gledajte kako se magija događa.

Dobro, uspjeli ste, ali prije nego što se počnete tapšati po leđima, vratimo se korak unatrag i shvatimo kako je to uspjelo.

Slomivši ga

Krenimo od početka. docker runNaredba je lučki radnik je standardni alat će vam pomoći započeti i pokrenuti svoje spremnike.

Oznaka --rmje tu da kaže Docker Daemonu da očisti spremnik i ukloni datotečni sustav nakon izlaska spremnika. To vam pomaže uštedjeti prostor na disku nakon pokretanja kratkotrajnih spremnika poput ovog koji smo tek počeli ispisivati ​​"Hello, World!".

Oznaka -t (or --tty)Dockeru govori da dodijeli virtualnu terminalsku sesiju unutar spremnika. To se obično koristi s -i (or --interactive)opcijom koja STDIN drži otvorenim čak i ako radi u odvojenom načinu (više o tome kasnije).

Napomena: Ne brinite se previše zbog ovih definicija trenutno. Samo znajte da ćete koristiti -itzastavicu kad god želite upisati neke naredbe u svoj spremnik.

I na kraju, python:3je osnovna slika koju smo koristili za ovaj spremnik. Trenutno uz ovu sliku između ostalog dolazi i instalirana verzija pythona 3.7.3. Sad se možda pitate odakle je potekla ova slika i što je unutra. Odgovore na oba ova pitanja možete pronaći ovdje, zajedno sa svim ostalim python slikama koje smo mogli upotrijebiti za ovaj primjer.

Posljednje, ali ne najmanje važno, pythonbila je naredba koju smo Dockeru rekli da je izvrši unutar naše python:3slike, koja je pokrenula python ljusku i omogućila da naš print("Hello, World!")poziv djeluje.

Još jedna stvar

Da biste izašli iz pythona i prekinuli naš spremnik, možete koristiti CTRL / CMD + D ili exit(). Samo naprijed i to odmah. Nakon toga pokušajte ponovno izvršiti našu docker runnaredbu i vidjet ćete nešto malo drugačije i puno brže.

To je zato što smo python:3sliku već preuzeli , tako da naš spremnik sada počinje puno brže.

Dio 2. Automatizirano "Hello World!" s Pythonove slike

Što je bolje od pisanja "Hello, World!" jednom u svom terminalu? Shvatili ste, napisali dva puta!

Budući da jedva čekamo vidjeti "Hello, World!" ponovno ispisane u našem terminalu i ne želimo prolaziti kroz gužvu otvaranja pythona i printponovnog tipkanja , idemo naprijed i malo automatiziramo taj proces. Započnite stvaranjem hello.pydatoteke gdje god želite.

# hello.py
print("Hello, World!")

Dalje, iz te iste mape pokrenite sljedeću naredbu.

docker run --rm -it -v $(pwd):/src python:3 python /src/hello.py

Ovo je rezultat koji tražimo:

Napomena: Koristio sam lsprije naredbe da vam pokažem da sam u istoj mapi u kojoj sam stvorio hello.pydatoteku.

Kao i ranije, vratimo se korak unatrag i shvatimo kako je to funkcioniralo.

Slomivši ga

U osnovi radimo istu naredbu kao i u prošlom odjeljku, osim dvije stvari.

-v $(pwd):/srcOpcija govori listi Daemon da pokrene i Volume n našu posudu . Svesci su najbolji način za zadržavanje podataka u Dockeru. U ovom primjeru govorimo Dockeru da želimo da se trenutni direktorij - preuzet iz $(pwd)- doda u naš spremnik u mapi /src.

Napomena: Možete koristiti bilo koje drugo ime ili mapu koje želite, ne samo/src

Ako želite provjeriti /src/hello.pypostoji li zapravo unutar našeg spremnika, možete promijeniti kraj naše naredbe iz python hello.pyu bash. Ovo će otvoriti interaktivnu ljusku unutar našeg spremnika i možete je koristiti baš onako kako biste očekivali.

Napomena: Ovdje možemo koristiti samo bashzato što je unaprijed instaliran na python:3slici. Neke su slike toliko jednostavne da nemaju bash. To ne znači da ga ne možete koristiti, ali ako ga želite, morat ćete ga sami instalirati.

Posljednji dio naše naredbe je python /src/hello.pyuputa. /srcIzvršavajući ga, poručujemo našem spremniku da pogleda unutar svoje mape i izvrši hello.pydatoteku pomoću python.

Možda već vidite čuda koja možete učiniti s ovom snagom, ali svejedno ću vam ih istaknuti. Koristeći ono što smo upravo naučili, možemo u velikoj mjeri pokrenuti bilo koji kôd s bilo kojeg jezika unutar bilo kojeg računala, bez potrebe za instaliranjem bilo kakvih ovisnosti na glavnom računalu - osim Dockera, naravno.To je puno podebljanog teksta za jednu rečenicu, pa svakako dvaput pročitajte!

3. dio Najlakši "Hello, World!" moguće iz Python slike koristeći Dockerfile

Jeste li se već umorili od pozdrava s našim prekrasnim planetom? Šteta, jer ćemo to ponoviti!

Posljednja naredba koju smo naučili bila je malo opširna i već vidim kako mi je dosadno tipkati sav taj kod svaki put kad želim reći "Zdravo, Svijete!" Hajde sada automatizirati stvari malo dalje. Stvorite datoteku s imenom Dockerfilei dodajte joj sljedeći sadržaj:

# Dockerfile
FROM python:3
WORKDIR /src/app
COPY . .
CMD [ "python", "./hello.py" ]

Sada pokrenite ovu naredbu u istoj mapi u kojoj ste kreirali Dockerfile:

docker build -t hello .

Sve što preostaje sada je poludjeti koristeći ovaj kod:

docker run hello

Već znate kako je. Uzmimo trenutak da shvatimo kako Dockerfile sada radi.

Slomivši ga

Počevši s našim Dockerfile, prvi red FROM python:3je reći listi za početak sve sa osnovnom slikom smo već upoznati s, python:3.

Drugi redak, WORKDIR /src/apppostavlja radni direktorij unutar našeg spremnika. Ovo je za neke upute koje ćemo izvršiti kasnije, poput CMDili COPY. Ostatak podržanih uputa za WORKDIRovdje možete vidjeti ovdje.

Treći redak COPY . .zapravo govori Dockeru da kopira sve iz naše trenutne mape (prva .) i zalijepi je /src/app(druga .). Mjesto lijepljenja postavljeno je WORKDIRnaredbom točno iznad njega.

Napomena: Iste bismo rezultate mogli postići uklanjanjem WORKDIRupute i zamjenom COPY . .upute s COPY . /src/app. U tom bismo slučaju također trebali promijeniti posljednju uputu, CMD ["python", "./hello.py"]na CMD ["python", "/src/app/hello.py"].

Napokon, posljednji redak CMD ["python", "./hello.py"]pruža zadanu naredbu za naš spremnik. U osnovi se kaže da bi se svaki put kad runspremnik iz ove konfiguracije trebao pokrenuti python ./hello.py. Imajte na umu da implicitno trčimo /src/app/hello.pyumjesto samo hello.pyzato što smo na to usmjerili WORKDIR.

Napomena:CMD naredba može biti prepisana na vrijeme izvođenja. Na primjer, ako bashumjesto toga želite pokrenuti , to biste učinili docker run hello bashnakon izgradnje spremnika.

Kad je naš Dockerfile završen, nastavljamo i započinjemo naš buildproces. docker build -t hello .Naredba čita sve konfiguracije smo upisan u našu Dockerfile i stvara listi sliku od njega. Točno, baš kao i python:3slika koju koristimo za cijeli ovaj članak. Na .kraju Dockeru govori da želimo pokrenuti Dockerfile na našem trenutnom mjestu, a -t helloopcija daje ovoj slici ime hello, tako da je možemo lako referencirati tijekom izvođenja.

Nakon svega toga, sve što trebamo je pokrenuti uobičajenu docker runuputu, ali ovaj put s helloimenom slike na kraju retka. To će pokrenuti spremnik sa slike koju smo nedavno izgradili i konačno ispisati dobru sliku 'Zdravo, Svijete!' u našem terminalu.

Proširenje naše osnovne slike

Što ćemo učiniti ako nam treba neka ovisnost za pokretanje našeg koda koji nije unaprijed instaliran s našom osnovnom slikom? Da bi riješio taj problem, docker ima RUNupute.

Slijedeći naš primjer pythona, ako nam je potrebna numpybiblioteka za pokretanje našeg koda, mogli bismo dodati RUNuputu odmah nakon naše FROMnaredbe.

# Dockerfile
FROM python:3
# NEW LINERUN pip3 install numpy
WORKDIR /src/app
COPY . .
CMD [ "python", "./hello.py" ]

RUNInstrukcija u osnovi daje naredbu da se izvrši terminala spremnika. Na taj način, budući da naša osnovna slika već dolazi s pip3instaliranim, možemo je koristiti pip3 install numpy.

Napomena: Za stvarnu aplikaciju python vjerojatno biste dodali sve ovisnosti koje su vam potrebne u requirements.txtdatoteku, kopirali je u spremnik, a zatim ažurirali RUNupute na RUN pip3 install -r requirements.txt.

Dio 4. "Zdravo, Svijete!" sa Nginx slike pomoću odvojenog spremnika dugog vijeka trajanja

Znam da ste vjerojatno umorni dok me čujete kako to kažem, ali moram još jedan pozdrav reći prije nego što krenem. Krenimo i iskoristimo našu novostečenu dockersku snagu za stvaranje jednostavnog dugotrajnog spremnika, umjesto ovih kratkotrajnih koje smo do sada koristili.

Stvorite index.htmldatoteku u novoj mapi sa sljedećim sadržajem.

# index.html

Hello, World!

Sada, kreirajmo novu Dockerfile u istoj mapi.

# Dockerfile
FROM nginx:alpine
WORKDIR /usr/share/nginx/html
COPY . .

Izgradite sliku i dajte joj ime simple_nginx, kao što smo to prije radili.

docker build -t simple_nginx .

Na kraju, pokrenimo našu novostvorenu sliku sa sljedećom naredbom:

docker run --rm -d -p 8080:80 simple_nginx

Možda mislite da se ništa nije dogodilo jer ste se vratili na terminal, ali pogledajmo detaljnije docker psnaredbu.

U docker psnaredba prikazuje sve pokrenute kontejneri u vašem uređaju. Kao što možete vidjeti na gornjoj slici, simple_nginxu mom stroju trenutno radi spremnik s imenom . Otvorimo web preglednik i provjerimo nginxradi li svoj posao pristupanjem localhost:8080.

Čini se da sve radi prema očekivanjima, a mi služimo statičnoj stranici kroz nginxpokretanje unutar našeg spremnika. Uzmimo trenutak da shvatimo kako smo to postigli.

Slomivši ga

Preskočit ću objašnjenje Dockerfilea jer smo te naredbe već naučili u prošlom odjeljku. Jedina "nova" stvar u toj konfiguraciji je nginx:alpineslika, o kojoj više možete pročitati ovdje.

Osim što je novo, ova konfiguracija funkcionira jer mapu nginxkoristi usr/share/nginx/htmlza traženje index.htmldatoteke i započinjanje posluživanja, pa budući da smo datoteku imenovali index.htmli konfigurirali WORKDIRda bude usr/share/nginx/html, ova će postavka raditi odmah iz okvira.

buildNaredba je točno kao ona koju smo koristili u zadnjem dijelu, kao, mi samo koristite Dockerfile konfiguraciju izgraditi sliku s određenim nazivom.

Sada za zabavni dio, docker run --rm -d -p 8080:80 simple_nginxupute. Ovdje imamo dvije nove zastave. Prva je oznaka detached ( -d), što znači da ovaj spremnik želimo pokrenuti u pozadini i zato smo se vratili na terminal odmah nakon korištenja docker runnaredbe, iako naš spremnik i dalje radi.

Druga nova zastava je -p 8080:80opcija. Kao što ste mogli pretpostaviti, ovo je portzastava i u osnovi preslikava luku 8080s našeg lokalnog stroja na luku 80unutar našeg spremnika. Umjesto toga mogli ste upotrijebiti bilo koji drugi priključak 8080, ali ne možete ga promijeniti 80bez dodavanja dodatne postavke nginxslici, jer 80je to standardni port koji nginxslika izlaže.

Napomena: Ako želite zaustaviti odvojeni spremnik poput ovog, možete upotrijebiti docker psnaredbu za dobivanje imena spremnika (ne slike), a zatim upotrijebite docker stopuputu sa željenim imenom spremnika na kraju retka.

Dio 5. Kraj

To je to! Ako ovo još uvijek čitate, imate sve osnove kako biste već danas počeli koristiti Docker na svojim osobnim projektima ili svakodnevnom poslu.

Javite mi što ste mislili o ovom članku u komentarima i pobrinut ću se da napišem sljedeći članak koji pokriva naprednije teme poput docker-composenegdje u bliskoj budućnosti.

Ako imate pitanja, javite mi.

Živjeli!