joi, 22 august 2019

2.3 Scrierea primului Dockerfile

Problema

Ruland un container in modul interactiv, facand schimbari si dupa salvand aceste schimbari pentru a creea o noua imagine mergea bine (vezi Reteta 2.1). Dar, chiar si asa, iti doresti sa automatizezi procesul builduind imaginea ta si impartasindu-ti pasii creati cu ceilalti.

Solutia

Pentru a automatiza crearea unei imagini Docker, vei descrie pasii create intr-un manifest Docker numit Dockerfille. Acest fisier text foloseste un set de instructiuni pentru a descrie pe care imagine de baza se bazeaza noul container, ce pasi trebuie facuti pentru a instala variatele dependinte si aplicatii, ce fisiere trebuie sa fie prezente in imagine, cum sunt ele disponibile containerului, ce porturi ar trebui expuse, si ce comanda ar trebui rulata cand incepe un container, ca si alte cateva alte lucruri.
Pentru a ilustra asta haideti sa scriem un prim Dockerfile. Imaginea rezultata iti va permite sa creezi un container care executa comanda /bin/echo. Creeaza un fisier text numit Dockerfile in directorul in care lucrezi si scrie urmatorul continut in el:
FROM ubuntu:14.04
ENTRYPOINT ["/bin/echo"]
Instructiunea FROM iti spune din ce imagine este bazata noua imagine. Aici vei allege imagine Ubuntu: 14.04 imagine din repositoriul Oficial Ubuntu din Docker Hub.
Instructiunea ENTRYPOINT iti spune ce comanda sa rulezi cand este pornit un container bazat pe aceasta imagine. Pentru a creea imaginea, scrie in prompter docker built . ca mai jos:
$ docker build .
                Sending build context to Docker daemon  2.56 kB
Sending build context to Docker daemon
 Step 0 : FROM ubuntu:14.04 ---> 9bd07e480c5b
Step 1 : ENTRYPOINT /bin/echo ---> Running in da3fa01c973a ---> e778362ca7cf
 Removing intermediate container da3fa01c973a
Successfully built e778362ca7cf
 $ docker images
REPOSITORY          TAG         IMAGE ID       ...    VIRTUAL SIZE
 <none>              <none>      e778362ca7cf   ...    192.7 MB
ubuntu              14.04       9bd07e480c5b   ...    192.7 MB
Acum esti pregatit sa rulezi acest container, specificand ID-ul proaspetei imagini create si pasand un argument. (de exemplu: Hi Docker !):
$ docker run e778362ca7cf Hi Docker !
Hi Docker !
Uimitor – poti rula comanda echo in container! Un container a fost pornit folosind imagine ape care ai creat-o din acest fisier din doua linii. Containerul ruleaza si executa comanda definite the instructiunea ENTRYPOINT. Odata ce aceasta comanda a fost finalizata, jobul containerului s-a finalizat si oprit. Daca il vei rula din nou fara a-I pasa un parametru, nu va fi afisat nimic:
$ docker run e778362ca7cf
Poti de asemenea sa folosesti instructiuni CMD intr-un DOckerfile. Acesta avand avantajul ca poti suprascrie comportamentul CMD cand lansezi un container, prin pasarea unui nou CMD ca argument in rularea dockerului. Hai sa cream o noua imagine folosind instructiuni CMD, ca urmatoarele:
FROM ubuntu:14.04
CMD ["/bin/echo" , "Hi Docker !"]
Acum haideti sa il builduim si sa il rulam:
$ docker build . ... $ docker run eff764828551 Hi Docker !
In comanda precedent de build, vei specifica directorul radacina. Dockerfileul pe care tocmai l-ai creat a fost creat automat pentru build. Daca vrei sa sa faci un build al unei imagini bazate pe un dockerfile care este intr-o locatie diferita, trebuie sa folosesti optiunea –f a buildului docker sis a specifici calea.
Arata la fel, dar daca pasezi un nou executabil ca argument in comanda docker run, aceasta comanda va fi executata in loc de cea din /bin/echo definite in Dockerfile:
$ docker run eff764828551 /bin/date
Thu Dec 11 02:49:06 UTC 2014

 Discutie

Un Dockerfile este un fisier text care reprezinta felul in care o imagine Docker este builduita si ce se intampla cand un container este pornit cu aceasta imagine. Incepand cu trei pasi simpli, poti contrui un container functional complet: FROM, ENTRYPOINT, CMD. Bineinteles este destul de limitat in aceasta reteta. Citeste referinta Dockerfile pentru a invata despre toate celelalte instructiuni, sau du-te la Reteta e.4 pentru un exemplu mai detaliat.
Proiectul CentOS mentine o multime mare the exemple de Dockerfile. Verifica acest repository si ruleaza cateva din exemplele lor pentru a te familiariza mai mult cu fisierele Docker.
Aminteste-ti ca CMD poate fi suprascris de un argument in Docker run, in timp ce ENTRYPOINT poate fi suprescris numai folosinf optiunea –entrypoint a docker run. De asemenea, ati observant ca dup ace o comanda s-a finalizat, containerul se opreste. Un process pe care il vrei sa rulezi intr-un container trebuie sa ruleze in prim plan; altfel containerul se va opri.
Odata ce primul tau build este executat, o noua imagine este create cu , in acest caz, ID-ul e778362ca7cf. Ia aminte ca niciun repository sau tag nu este definit pentru ca nu ai specificat niciunul. Poti rebuildui imaginea cu cookbook-ul repositoriului ca nume si tagul hello, folosint optiunea –t a docker build. Cat timp faci asta local, alegerea repositoriului si a tagului depinde de tine, dar odata ce incepi sa publici aceasta imagine intr-un registru, va trebui sa te conformezi conventiei de nume.
$ docker build -t cookbook:hello .
$ docker images
                REPOSITORY          TAG         IMAGE ID        CREATED         VIRTUAL SIZE
cookbook            hello       e778362ca7cf    4 days ago      192.7 MB
 ubuntu              14.04       9bd07e480c5b    10 days ago     192.7 MB
Comanda Docker build are o parte de optiuni pe care sa le folosesti atunci cand ai de-a face cu containere intermediare:
$ docker build -h
Folosire: docker build [OPTIONS] PATH | URL |
Builduie o noua imagine din codul sursa la calea
--force-rm=false     Sterge intotdeauna containerele intermediare

--no-cache=false     Nu folosi cache cand builduiesti…

 -q, --quiet=false    Suprima verbozitatea outputului generat…

--rm=true           Sterge containerele intermediare dupa …

-t, --tag=""         Numele repositorului (si optional a tagului)…

Vezi si:

 • Dockerfile referinta
 • Cele mai bune practice pentru scrierea unui Dockerfile
 • Multimea de fisiere Docker a proiectului CentOS
 

Niciun comentariu:

Trimiteți un comentariu