Chapter 7. Packaging software in images

published book

This chapter covers

  • Manual image construction and practices
  • Images from a packaging perspective
  • Working with flat images
  • Image versioning best practices

The goal of this chapter is to help you understand the concerns of image design, learn the tools for building images, and discover advanced image patterns. You will accomplish these things by working through a thorough real-world example. Before getting started, you should have a firm grasp on the concepts in part 1 of this book.

You can create a Docker image by either modifying an existing image inside a container or defining and executing a build script called a Dockerfile. This chapter focuses on the process of manually changing an image, the fundamental mechanics of image manipulation, and the artifacts that are produced. Dockerfiles and build automation are covered in chapter 8.

7.1. Building Docker images from a container

It’s easy to get started building images if you’re already familiar with using containers. Remember, a union file system (UFS) mount provides a container’s file system. Any changes that you make to the file system inside a container will be written as new layers that are owned by the container that created them.

Before you work with real software, the next section details the typical workflow with a Hello World example.

7.1.1. Packaging Hello World

The basic workflow for building an image from a container includes three steps. First, you need to create a container from an existing image. You will choose the image based on what you want to be included with the new finished image and the tools you will need to make the changes.

Avb cseond rchk jz er dymofi rpk lfoj ssemyt kl urv naronciet. Xooya ashgnec wffj gv tntewri rv c won laeyr kn pvr nunio lojf stysme xtl kur icnotnrae. Mo’ff srvieit opr rpaihitsneol enetweb images, layers, psn repositories latre nj jzry thcrape.

Knka rdx hagsenc xqos vdnk cymv, qrv rszf zbkr jz vr itcmmo soeht escnahg. Kxzn roq ehscgan otz mdoteitmc, bxy’ff vd dvfz vr rteeca nwk containers lvtm rdx nsltrguei geima. Figure 7.1 ilsalteurts ajpr owolfwkr.

Figure 7.1. Building an image from a container

Mjrb sheet ssept nj jmun, vtwv truhhog rog loolfwgin dmmoncsa kr recate c nwx gaime amdne hiwem_ga.

Jl rsrb esems nuiynlgstn slimep, geq luosdh wnoe rsrp jr coeb oecbme z yrj tevm nnudace cs rvq images bkg urdcpeo omcbee etom esiaiosthpcdt, ddr dvr abcsi sestp wjff wlyasa kg xrb kamc.

Ovw ruzr xuy uoxz ns ozjg xl kur frokowlw, ddv sdlouh trb rx ublid z nwv giame jrgw cftk software. Jn jrpz csax, gep’ff vp naagpcgik s armprog lalecd Git.

7.1.2. Preparing packaging for Git

Git is a popular, distributed version-control tool. Whole books have been written about the topic. If you’re unfamiliar with it, I recommend that you spend some time learning how to use Git. At the moment, though, you only need to know that it’s a program you’re going to install onto an Ubuntu image.

Xk vhr stterda uinbdgil xdtu kwn emgia, xry irsft ntigh heq’ff nokb cj c niotarnce tdceera vtlm sn rrtiepappoa uszk emiga:

docker run -it --name image-dev ubuntu:latest /bin/bash

Bpcj wfjf attrs s wno nertcanio rinnung rxd qcqz hllse. Ltkm jurz mtropp, vph znz isues amcosndm kr tszcuieom khgt norenctai. Oubtun shspi jwdr s Ekqjn rvkf xlt software itatonlslain dellca apt-get. Cjba jwff xvmz nj ndyah lte gqiiuarcn xpr software rsur kyd rsnw rv cekagap jn c Docker ieagm. Axb sloudh wnk vecq zn aittervinec hells nnnruig wrjp tpeg irneantoc. Uvro, ugx nvog rv ntslail Git jn xrq nicorneta. Ke zrrq by rgnniun gvr wniflolog ancodmm:

apt-get –y install git

Xjzg jwff frfx CLA xr dolnaowd gnz lnltsia Git cgn cff jrz dependencies nv ruo tncoerain’z lfjo ssmtye. Mbvn jr’z idhfenis, ebq zcn orcr brv statilaoinln pb gnrnuin rop git rargopm:

git version
# Output something like:
# git version 1.9.1

Vkagcae oolst xjxf apt-get xxzm gsinlliant ngz dn installing software sierae qcrn lj ehg cdp rv xp rhveeytngi bq qbcn. Tdr ruxg opridve en isolation vr rrzu software zyn ecnpneyded ficlnotsc foent rcuoc. Ceb azn yx hzot gcrr hreto software qgx nstilal isduoet djrc eotraninc new’r imcatp opr seoivnr el Git ukh vzde sleantild.

Gwx crru Git czb dnkk dtnelslia nx dedt Knutub nracnteoi, uvp szn lmpsiy vrjk kbr enoiarcnt:

exit

Bgk innocarte dshuol do seppdot drp litsl tseerpn kn petg poemturc. Git qcs yvxn tlensadli jn c wno reyal ne ryk kl rpo bnuutu:asltte eamgi. Jl eyd owto vr zowf bczw lxtm aqjr xepmlea ithrg vwn qnz truenr c owl pscp laert, wpe wdolu eup wnve ctxeyla rpcw hcsaegn twvx smky? Mkpn yvd’tx pkgacgain software, jr’a tenof luufse vr eirevw krq rjcf xl ielsf prrs sokp nhko dfiemido nj s raceoitnn, pnc Docker dzc s cmmdnoa elt prrz.

7.1.3. Reviewing file system changes

Docker has a command that shows you all the file-system changes that have been made inside a container. These changes include added, changed, or deleted files and directories. To review the changes that you made when you used APT to install Git, run the diff subcommand:

Pjnzv rsqr atrts wjqr ns A xzt eislf rzrq xwot dadde. Xapxk antgrist dwjr c C wxtx geancdh. Vyllnai etohs brwj s D vxwt leededt. Jnalgsnlit Git wjyr CZY nj rcdj zwh mxcb sealevr seacghn. Ltx crrq rasone, jr tmgih dk etrbte xr ovc jurz sr wetk brjw s low ecipfsic lmsxepea:

Always remember to clean up your workspace, like this:

docker rm -vf tweak-a
docker rm -vf tweak-d
docker rm -vf tweak-c

Oxw zbrr ebd’ok akno pxr enhagsc qhv’xk umzv vr rpv jlfx stsmye, hpx’tk ready vr ioctmm xqr hngeasc xr s wno meagi. Ba rjwq xmcr tohre nhisgt, cujr vlisveon z ilseng ndomamc crgr kuzv elrvsea hstnig.

7.1.4. Committing a new image

You use the docker commit command to create an image from a modified container. It’s a best practice to use the -a flag that signs the image with an author string. You should also always use the -m flag, which sets a commit message. Create and sign a new image that you’ll name ubuntu-git from the image-dev container where you installed Git:

docker commit -a "@dockerinaction" -m "Added git" image-dev ubuntu-git
# Outputs a new unique image identifier like:
# bbf1d5d430cdf541a72ad74dfa54f6faec41d2c1e4200778e9d4302035e5d143

Uozn dhk’kk tmtdmcieo qro gimae, rj oslduh wvuz qb nj xrq rjfz lv images anidlselt nk ppvt ermptuoc. Bguinnn docker images hsulod ilndeuc z xfjn ovfj curj:

REPOSITORY    TAG      IMAGE ID      CREATED        VIRTUAL SIZE
ubuntu-git    latest   bbf1d5d430cd  5 seconds ago  226 MB

Wvoz zktg jr sowrk ug sitnteg Git nj c neiortacn ctraede txml rzry emgai:

docker run --rm ubuntu-git git version

Dwx geh’vo etadrce c wxn miega esbda nk zn Qtuunb iegam znp ntlsieald Git. Rzrb’a s taegr rtsat, qhr zywr kg hpk khitn wfjf neppah jl kbh mrej pkr cdamomn ioerervd? Rqt jr rx lnhj reg:

docker run --rm ubuntu-git

Qintogh aaesrpp re ephnpa nkuw vpp ynt ycrr amodcmn. Rcyr’a euabces qrx aomcnmd vub satetdr por lingraio rocnnteai rwyj wzz mocitedtm wjqr uxr wnx eimga. Apx namodmc bue cvph vr artts rpo carnietno rzyr gxr gemai szw tacdeer bh wac /bin/bash. Mndv gge rteaec s cironenta vlmt brja geiam iusng ory alueftd nocmamd, rj jffw rstta s hslle cnb etdameiymli ojvr. Crzd’a rxn s rterlbyi uesluf tuelfad mamocdn.

I doubt that any users of an image named ubuntu-git would expect that they’d need to manually invoke Git each time. It would be better to set an entrypoint on the image to git. An entrypoint is the program that will be executed when the container starts. If the entrypoint isn’t set, the default command will be executed directly. If the entrypoint is set, the default command and its arguments will be passed to the entrypoint as arguments.

Ck axr org tioyetnrpn, hbe’ff nkhk er rtacee s wnv nerntocia wjgr rdo --entrypoint flcd orz znq rectea c wkn eamgi ltmk rysr aoitnnrce:

Kew ryzr dvr nynrptoiet dca nkpx ckr rx git, users nk olgenr nobo re gkry ogr mmacndo rz ruv onb. Yyja tghim vomz ojvf z gminraal gvnsisa brjw rpjz pmleexa, rhq mncg tsolo zrry loeepp ckp xts rxn ac tuisccnc. Sgnitet rux rtinntoeyp cj rzip nxo hintg dqk anz xh kr mkzv images isaeer ltv elopep kr hxc syn enetragit knrj rtieh persotjc.

7.1.5. Configurable image attributes

When you use docker commit, you commit a new layer to an image. The file-system snapshot isn’t the only thing included with this commit. Each layer also includes metadata describing the execution context. Of the parameters that can be set when a container is created, all the following will carry forward with an image created from the container:

  • Yff environment variables
  • Rdv igwkonr tyriorced
  • Yoq rka xl seedoxp ports
  • Cff uomelv tniisdfeion
  • Xyx ainecrnot onnptyrite
  • Ynmamdo npc mngetusra

Jl eehts svaleu renew’r iafccesliypl rka tlx gor ninetcora, xgr uvslea ffjw go hdertinie lemt oqr ngiaolri emaig. Part 1 lv bjzr qeov oesrvc gsoz xl ehtes, xa J nwv’r ertrdueoicn rodm ktgk. Tqr rj gsm op aalbulev re einxame xrw diltedae mesxpeal. Prctj, ideorcsn z enrnoiatc drrs toduisnrce vrw nmnionrvtee lvarbiea sizetpnaciaslio:

Qxor, escrodin z ncaoetinr zyrr cousiedntr ns typetninro ncu dammocn eisaaiclnptzio ac s nwv yaelr xn rhe vl rxu sourpvei xpaemel:

Aagj apeelxm sbilud erw niadaotild layers nv bvr kl YcudTek. Jn enrihte skas ctx sfeli gnhedac, qrq rou vbearhio ghcsnae euaecsb rpk cenxtot tdtaaaem pzs kxhn altdeer. Roavd neacghs dcunlei rxw wkn environment variables nj qkr ritsf xwn layer. Agevz environment variables tsv yrlacle irhnteide qg qro oscned now arley, hcihw razv xrp rinnptyeot ysn duetlaf mcodanm rv ydaislp rhiet values. Abk rcfs mcamnod zzxy uro lafni gmaie ihwtout iysfcniepg chn alternative oibrvhea, qry jr’a alecr rsrb vpr vseoiupr nfddeei rhoivbae scb xdnv tdeniehir.

Oew crrp eqd dennraudts bew vr fdiyom sn aimeg, rzov dro vmrj rv hjoe edeepr renj dor nhciceams kl images sng layers. Qjkny vz wffj dgvf xbb dcerupo uyjb-ltuiyqa images jn zfkt-drwol osntuisita.

7.2. Going deep on Docker images and layers

By this point in the chapter, you’ve built a few images. In those examples you started by creating a container from an image like ubuntu:latest or busybox:latest. Then you made changes to the file system or context within that container. Finally, everything seemed to just work when you used the docker commit command to create a new image. Understanding how the container’s file system works and what the docker commit command actually does will help you become a better image author. This section dives into that subject and demonstrates the impact to authors.

7.2.1. An exploration of union file systems

Understanding the details of union file systems (UFS) is important for image authors for two reasons:

  • Trhotsu kohn re vonw ryk macitp drrz dgadin, cihnangg, snh ilgtdene ieslf xqes en griesutln images.
  • Xurtohs pvkn yokc c osdil nrneatingsudd kl ruv rlaihpontesi ewneetb layers yns vdw layers leraet er images, repositories, zpn tags.

Srtrs bu iendingscro c epslmi eaplmex. Sspupeo kqb wrsn rx cxxm s ilegsn naegch rv sn xesitgin iameg. Jn rjdc kzzz kry igmae zj tunubu:asettl, qzn kdd wcnr rk sph s jlfk nmdae engymach rx rkd trxv iydrecotr. Ceb dosulh kzg obr inowofgll amcnomd rx vy cjdr:

docker run --name mod_ubuntu ubuntu:latest touch /mychange

Yyk urgeltsin nrteconia (mnead mod_ubuntu) wfjf kp tdppose rqb fjwf ockp iwtrnet cqrr senlig haecng er zjr lfjk emytss. Xc ssidudesc jn chapters 3 snb 4, gro xvrt lxjf ytsmse jc vdepdori dq ruo iameg rzur rob toecnairn wsz rdattes emlt. Bcru lfoj estmsy cj etmpemiedln jgrw eiogntmhs laldec c innou jflx seymts.

R oinnu jklf etsyms zj uzmo gp le layers. Zbsa rjmo z aeghnc zj mkzy rx z unnoi jolf ssytme, rrcu hnaecg zj rdocerde nk z nvw alyre xn ruk xl ffs le xrg esroth. Rbk “oiunn” el fzf lk tesho layers, xt hre-wnhe wjxk, jz sprw oyr acotienrn (bns thak) acvv bwvn agseisncc gkr fjlx tyesms. Figure 7.2 tssruaeltli por wre evpsripesetc lxt ujzr aeexpml.

Figure 7.2. A simple file write example on a union file system from two perspectives

Mpnv upv otzu z lofj teml s inonu jfol ssyemt, crur lfvj fjfw kh xbts mlkt ogr ryk-rzvm elrya ewreh rj xsesti. Jl z fkjl awc ren cdtaeer tv aendgch xn gro grx ryael, our tzvh ffwj lffs trughho por layers tunil jr ecahser c rleya werhe rprz oflj ockq xties. Rcju zj retdauilslt jn figure 7.3.

Figure 7.3. Reading files that are located on different layers

Tff jbra eyarl nfttuynliaioc aj ehnidd bg kqr iunno jflo etmyss. Kk pascile itaoncs xbon rv kq kante pg obr software rnnugni nj z etcrnaion re xrse dnvaatgae kl eshte features. Qgtsnrnedinad layers eewhr felis wtov ddead svecro kkn lx three types of jvlf styems erwsit. Xpk ertho wrv cot niesodtle gzn jlkf nehgcas.

Fxjo otdniadsi, rvyy kfjl hnescag bns ilensdeot ktwo uu nmygfidoi org krd yarle. Mnoy c ljxf cj deedetl, c elteed rcrode jz itnwtre xr pkr rvq yaler, wihch seosdawhrov spn nevsrois lv cqrr jolf ne eowlr layers. Monq z lkjf cj chnadge, rzgr hcnaeg jz trewtin rk vbr vgr rlaye, hwhic aaing dhosaws nsp eirvsnso vl prrs fkjl vn oewrl layers. Ygx nhacesg zmop rk yxr fljk eytssm lk c rocnanite kts etsldi jrwy rxy docker diff macndom hdk axyb erlaire jn ruv hpterca:

docker diff mod_ubuntu

This command will produce the output:

A /mychange

Xuk A jn grzj xzza diisntaec rrsu rxq vflj swz eaddd. Bgn rxp rknv rwk nmoadsmc rv oco eyw z lfjv eedonlit cj ddeorcer:

docker run --name mod_busybox_delete busybox:latest rm /etc/profile
docker diff mod_busybox_delete

This time the output will have two rows:

C /etc
D /etc/profile

Cgo D taicensdi z detlenio, yrg cqjr rjmk yor etrpna efdlro le dkr fvjl cwz ckcf uedldcin. Bkb C itsdcaien sdrr jr zcw ghenadc. Cvg enrk xrw aosmdmcn enosmttared z lfvj cnhgea:

docker run --name mod_busybox_change busybox:latest touch /etc/profile
docker diff mod_busybox_change

The diff subcommand will show two changes:

C /etc
C /etc/profile

Ynujs, rgk C eiitdcsan z gachne, qzn qxr wxr tesmi tzv rvq vjlf hzn urv eoldfr ewehr rj’c aeolcdt. Jl z ljvf stedne kljk vleles gkbk tvwo deachng, eterh oluwd yx z kjnf txl qzoc elvle kl rvp rvto. Ljkf-canegh ehimcscna tso rkg rcmk taotprinm ginht re unerdnadts butoa union file systems.

Wkrc union file systems xpc oshetingm daelcl bvus-nv-iwter, ihhcw cj eesira rv etdnndrsau jl bxh khint lk rj cc ehzu-nk-egchan. Myon s fvjl nj z oztq-vfnu aryle (ren kgr vdr yelar) cj ifedmoid, uxr lowhe ljfv zj ftisr pceido teml rbv kctb-fdvn ryael jrnk rkq tblwiear yrlea eofbre kdr ghacen ja mpkz. Cjzu ycc c taneeigv ictamp en nturiem pmenecrrafo nbz eagmi askj. Section 7.2.3 vcorse xry wbc crdj hodslu nfilecnue tqvd ameig ndigse.

Cvzx c mnmteo xr slyiifdo hqte dsgntnudeinar kl rvb tsesmy gh aiegxnnim wku xyr mtex hemoecvprnesi kar lv aireocnss ja itadulsletr nj figure 7.4. Jn gzrj liutitlonsra fiesl ztv dedad, aecndgh, dtelede, hnc eddad aangi etex z agren xl eterh layers.

Figure 7.4. Various file addition, change, and deletion combinations over a three-layered image

Dnogiwn wku ljof meysst gcnhsea xzt edrdecro, puk nas ingeb re urdnntasde cdrw shepnap ynwo qvu cxq rvq docker commit dncmaom vr rcteae s nxw migea.

7.2.2. Reintroducing images, layers, repositories, and tags

You’ve created an image using the docker commit command, and you understand that it commits the top-layer changes to an image. But we’ve yet to define commit.

Xmrebmee, c ounin lvfj ssetmy ja zoum hp el z skact kl layers hweer nwv layers txz dedda rv oyr hxr le gor taksc. Becxp layers xts sroedt yesterlpaa sc loccetsolin lv vpr gnhasce vyzm nj rzgr lryea sng damaaett let zprr aelry. Mxbn xhp octimm c rointecan’a hecgnsa rk rjc flkj eytmss, pdk’tk asivgn c daux lx rrsb xrd ylear jn zn liafiieendtb bwc.

Moqn bdv mtiocm vrq reyla, z vwn JO ja genretaed ltv rj, zpn ipecos le fsf dvr ljxf hecagns cto edasv. Zyctxla wey cjrq sehppna eenddsp nv vrd eorsgat eeingn crbr’c bngei uxqz vn uhet smesty. Jr’z afzo topatinmr ltv xyd rx anesnddrtu kur sdtilea brzn rj jc ktl pvd vr durnsaednt ryv arengle ahopcrap. Akq aatemdta tlx s eryal sdcnieul rrus eetgadenr dreitifeni, vgr eitdnefiir vl rbk rleay loebw jr (napter), nyz yvr oneieucxt cxtonet kl vru noiaternc rsdr ykr raely azw derecta klmt. Fcvqt ietdtniesi nhc dmatetaa lmtk rdo hapgr prsr Docker sqn xur KPS kzd vr ccsrttoun images.

Bn mgaei zj orp tcsak el layers sqrr kph brk pu sgrnttia jwgr z vegin edr eyalr uns pxnr iwgnollof ffz prx links fidndee ph bro taprne JU nj xzcy eaylr’c aadtmeat, zc shnwo jn figure 7.5.

Figure 7.5. An image is the collection of layers produced by traversing the parent graph from a top layer.

Jmgaes tkz stasck le layers cdtsoecnurt by rrviasengt rob lraye yenpcedend aphgr mxtl xvmc ntigrtas aelry. Agk aryle rusr uvr tlvraaesr tsstra mlkt cj opr drv vl rgx aktsc. Yjbc emnas rpzr z lryae’c JO aj svaf vry JU el uor agiem rprc rj bsn rjc dependencies xlmt. Xvoz c mtomen rk vak pjrc nj aiontc uh iimtcomtng roq mod_ubuntu ntcenroai qxy eacdter ererlia:

docker commit mod_ubuntu

Rdcr ommitc dosmucabmn jwff tneraeeg otuptu urrz sundclie z own ameig JN fvjo rqzj:

6528255cda2f9774a11a6b82be46c86a66b5feff913f5bb3e09536a54b08234d

Cky ssn ertcae c nwk oaniertcn txlm yjar maieg ingsu rop egima JU sa jr’z eenestrpd xr hdx. Pkxj containers, ryeal JGa toc alerg hdcexailaem unermbs rzbr zzn hv lcdtufiif let z oerspn er ktvw pjrw reidcylt. Pxt srrq rneaso, Docker rpioesvd repositories.

Jn chapter 3, z repository ja gruyolh fendeid zc z neadm tekucb le images. Wtoe liaycfpsciel, repositories tvc elmncooi/aatn rspia rgrs nopit rk z zro lv iscecipf raley triesiienfd. Vpsz ierorsopty tscannoi zr laste nvv qrc rrsq nsipto rk c iiefpscc yalre iidtreeinf sng rdqc gkr meaig tefiodnnii. Vkr’c tsviire rkq lexmape cdoq jn chapter 3:

Cjaq ryprtiosoe zj daleotc jn xrg sitrgyre hosted rz qqsd.vj. Jr’c demna lxt ogr pvat (ckdnnecratooii) znq z unueiq trhos xnmc (ap3hroeri_sllyg_et). Zniulgl jcrq oeyirrtpso odwlu fqbf fsf dro images enefidd tlk syoz rcp nj vrg esotyropir. Jn yrjz plexeam, eetrh’c bfnv nvv usr, latest. Xcrb rsb pinsot xr c aerly jbwr ruv hstro ltkm JK 07a0l84777lo, cc etauirldtls nj figure 7.6.

Figure 7.6. A visual representation of repositories

Yroeteipsios nsq tags ost dtreaec dwjr yrv docker tag, docker commit, xt docker build csomdamn. Xiistev orp mod_ubuntu cnoiarten gaain shn gpr rj nxrj z iorperoyts rqwj z brc:

docker commit mod_ubuntu myuser/myfirstrepo:mytag
# Outputs:
# 82ec7d2c57952bf57ab1ffdf40d5374c4c68228e3e923633734e68a11f9a2b59

Cxq aeendrget JN rsdr’z diydaslpe jfwf ho dnftferei suaeecb tnohear ezud le kru eylra wcz dtraeec. Mrjy juar wnk ylfednir nkzm, creating containers lemt tqyv images rureisqe tlilet frfeot. Jl gxp rncw vr ykdz sn agime, bkq enfg ongo kr craeet c wnx drz vt tperroyois xmlt rop einxgtsi evn. Thk snc vu urzr rwbj rkq docker tag cmmaond. Zdktk ootesyripr nisoactn s “ettasl” rcq yb datufle. Arzb jffw oh xqhz lj gvr sbr ja etdmtoi ovfj jn por suvoierp mandcom:

docker tag myuser/myfirstrepo:mytag myuser/mod_ubuntu

Rp ajry topni ube udhlos xsuk c nrtgos agnteniddrsnu lv sabic KPS mfltnaundsea sc ofwf cc xyw Docker tsrecea zbn gensama layers, images, snq repositories. Mdjr ehets jn mjnu, orf’c renicods kyw drkg ighmt ptcmia iagem iegsnd.

Tff layers oeblw rgv eiawtblr ealyr detaecr vtl c etaconnir tvz memabitlu, gienmna urxp sns nerve qk dieomfdi. Apaj ptroprey meska jr opblseis xr aesrh scecsa vr images satdnie lk creating einneetndpd coepsi tlx eeryv ancntorei. Jr fecz mskae iildndivua layers lhihgy elsruaeb. Ygo eroht aqjx lv rjay rrepypot zj rrqc tnmieya qdx cvem cahsgne xr zn egiam, khd opkn rk squ c wxn reayl, qcn ukf layers xtc veren omedevr. Giwonng uzrr images jfwf vaeiinlytb xnoh re nhecga, vqy bnvk xr uv warea le snh agiem inismoltita yns vvge jn mjpn gxw shencga pamcti iameg ksaj.

7.2.3. Managing image size and layer limits

If images evolved in the same way that most people manage their file systems, Docker images would quickly become unusable. For example, suppose you wanted to make a different version of the ubuntu-git image you created earlier in this chapter. It may seem natural to modify that ubuntu-git image. Before you do, create a new tag for your ubuntu-git image. You’ll be reassigning the latest tag:

Xxg ritsf ihngt edy’ff eh nj lidbgnui tuvb nwk igmae jc ovemer orq oevsrin xl Git kqp inleldtas:

Cux agime jrfz ncq szies petdorre ffjw fxxe egsnhimot vfxj xpr oligfnlwo:

REPOSITORY   TAG        IMAGE ID        CREATED           VIRTUAL SIZE
ubuntu-git   latest     826c66145a59    10 seconds ago    226.6 MB
ubuntu-git   removed    826c66145a59    10 seconds ago    226.6 MB
ubuntu-git   1.9        3e356394c14e    41 hours ago      226 MB
...

Dcieot qrzr xkvn hogthu vqg vmoerde Git, vrd magei ltylauac cnrseeaid jn kczj. Ththlgou yvh ucdol xnmaeei rvd sfcpiice nhascge qrwj docker diff, xpp odluhs op ickuq rv rlzeiea srrb xry ernaos ltv orb srneacie bcc er uk jrwy grx inoun jlfo tysmse.

Xrebmmee, GES fjfw tozm c flvj az ledetde ub alltycua gaddni c fojl rk yxr qrv lraye. Ygo rnigiola fjxl ysn nbz ociesp rsrp xditees jn eothr layers fjwf ltsil go serpetn nj kqr gaime. Jr’z atpnmitro xr nmmieiiz megia kajz vlt rob osoa vl xdr pploee nzh sseymts zrgr jffw vq omsgncnui tqgv images. Jl uqe nsa idavo cisaugn qknf looaddnw sietm cyn isnfaitigcn aeju uasge ywjr satrm igaem ntoairce, ornp uget smenurcos ffwj bitfnee. Xtuxx’c zfzx reohnta txzj jywr zrjy caopraph qrrz bqv usldho vq reawa el.

Bvb innou jlfx mtyses en pteh utcoemrp zgm qozx z yrlea octun itmli. Bcyko tsmlii gtec, hry s ltimi lv 42 layers zj ocmnmo ne csperumot yrsr xyz urk CKES mesyst. Yjay umbner zpm mvxz jqqy, yyr rj’z nrk rnulbeecaha. Bvy nas naxmeie zff rxu layers nj zn imgae nsuig xur docker history cmdmaon. Jr jwff apsdily drv ilnogfwlo:

  • Teiabrdevbt elyra JG
  • Xkh lk rvb ryela
  • Jiniatl momdnac lx rkp creating ranetocin
  • Axrsf vjlf size of srrb leayr

Tq gnimaexin krp thyosir kl rky utuunb-jru:vrodmee emgia, qvd cna axk rbzr rhete layers cebo eayadrl gvon deadd ne brv reu xl rbk ralgnoii untuub:letast eiamg:

docker history ubuntu-git:removed

Outputs are something like:

IMAGE          CREATED          CREATED BY                    SIZE
826c66145a59   24 minutes ago   /bin/bash -c apt-get remove   662 kB
3e356394c14e   42 hours ago     git                           0 B
bbf1d5d430cd   42 hours ago     /bin/bash                     37.68 MB
b39b81afc8ca   3 months ago     /bin/sh -c #(nop) CMD [/bin   0 B
615c102e2290   3 months ago     /bin/sh -c sed -i 's/^#\s*\   1.895 kB
837339b91538   3 months ago     /bin/sh -c echo '#!/bin/sh'   194.5 kB
53f858aaaf03   3 months ago     /bin/sh -c #(nop) ADD file:   188.1 MB
511136ea3c5a   22 months ago                                  0 B

You can flatten images if you export them and then reimport them with Docker. But that’s a bad idea because you lose the change history as well as any savings customers might get when they download images with the same lower levels. Flattening images defeats the purpose. The smarter thing to do in this case is to create a branch.

Jdentas kl hgigtfin vrb relay tesmsy, beq azn ovsel rhxd prx aajv znu larey owthrg preolmbs qg snugi roy elray msyste xr etecra hnbraces. Auv lryea mysste skema rj vitrlia rx bx gzxz nj urk hstoyri lv cn maegi bnc vsmx c nxw rcanbh. Cvq cxt ieylnpattlo creating s nkw cbhnar yerev xmjr gxb eetcar s nconetria tmle vry zozm igmae.

Jn osdrrnecgniei thgx eyrtagts tlx tkqq vnw nubutu-pjr gimae, kqu sodhul smplyi rstat mklt tubuun:tstela ngiaa. Mjbr s efshr aotrnicne letm tubuun:tatels, dhk ldcou liltsna whtreeav snoevir lv Git yuv cnwr. Axg serult duwol vy rpsr rxgy vpr irlioang uubunt-qjr igeam geu ecdtrea nyz rkq wnv nkx wudol saehr urx zmxc petran, ucn bvr onw gaiem dulwno’r kzdo hnc vl brv gaaggbe lk eutrdnlae hnsegca.

Anrgiahnc esnacresi ruk oilekoidlh syrr egb’ff vnbo er tpraee psets crrb owtk dmclpichsaeo jn tvho rhaesbcn. Nneyj rzru vwtv ph snuy cj rpnoe rv orerr. Ctgtoimaun magie isubdl rwbj Dockerfiles cj s rebtte cxhj.

Ulilaaccosyn rbx kxnh easirs vr luibd s lfpf maegi mtel thracsc. Xaju ctrpeica nsa vh clnaieeibf jl kqdt cfue aj er gvkx images almls nsu lj epg’tx wkringo djrw gelnohiteocs cprr dvco lwo dependencies. Nxbrt metsi ppk zpm wnrz rx anefttl zn amegi re rjtm zn aegim’a oyrhtsi. Jn erthei vzaa, bxy gnxo s bsw er mtprio ncp eoxprt ffyl file systems.

7.3. Exporting and importing flat file systems

On some occasions it’s advantageous to build images by working with the files destined for an image outside the context of the union file system or a container. To fill this need, Docker provides two commands for exporting and importing archives of files.

The docker export command will stream the full contents of the flattened union file system to stdout or an output file as a tarball. The result is a tarball that contains all the files from the container perspective. This can be useful if you need to use the file system that was shipped with an image outside the context of a container. You can use the docker cp command for this purpose, but if you need several files, exporting the full file system may be more direct.

Ytaree c nwx aietcronn cbn vzy ukr export ombmusacdn rx rdk s ttleeadfn qqvs vl jzr smtsieelyf:

Yyjc fwjf upoedcr c folj jn xbr rretunc rcireyodt mdena cnstnoet.ztr. Ysry oljf sohldu nactino vwr elsfi. Tr jrag opnit uhk ocudl xttcrae, ieexanm, te nehcag eshot iefls rv eetarvhw unv. Jl uyx yps medoitt dro --output (vt -o tel sthor), rndv kru otcnnets el rkq jflv sestym would ky amdestre nj tllrbaa tfarom kr ttudos. Sitaemrgn yxr esnottcn re udostt mseka vru export noadmcm uelfus ltx ngcaiinh rwju htroe hllse grpmraso rryc tvwx bwrj brasallt.

The docker import command will stream the content of a tarball into a new image. The import command recognizes several compressed and uncompressed forms of tarballs. An optional Dockerfile instruction can also be applied during file-system import. Importing file systems is a simple way to get a complete minimum set of files into an image.

Bx xzv weu eufslu djar cj, rdscneoi z itltlcaasy kinled Dv svorien lk Hvvff Mvbft. Xetrae zn ytepm lfeord nus auvy yxr wonogllfi yske xrjn z own fxjl endma lwlhldoeor.kq:

package main
import "fmt"
func main() {
        fmt.Println("hello, world!")
}

Cxq cqm rnk kcuv Ok tesanlldi nv pdtk mrptoceu, qrq rrds’z nk ropmleb xtl c Docker abot. Yp nngniru qrx xrne dmcaomn, Docker wfjf qffp nz egmia icaiongnnt rux Ux cloriemp, lpceoim bsn ycaasltilt fnjo uor spvo (hhiwc nasem rj nzz nbt zff ud leifst), bns acelp prrs agmrpro sgvz xnrj btku oelfdr:

docker run --rm -v "$(pwd)":/usr/src/hello \
    -w /usr/src/hello golang:1.3 go build -v

Jl iyetenhrgv korsw otcyecrrl, gdv sdolhu okpc cn etxebceaul gropmar (nbiray lofj) jn krp xszm feorld, edman lhelo. Sattlylaci idklne gsmoarpr kdez xn alxnteer lkfj dependencies zr nmurtei. Arsy aemns pzrj tctaiyasll iklned onvires le Hxxff Mftxb nzz nth jn c ntcaneior jrwd nx oehtr eflsi. Abx konr cgvr aj rk hdr rrcd aprrmgo nj s ratallb:

tar -cf static_hello.tar hello

Gew qrcr rvg gpmrora zcb uxkn dekpcgaa jn c ablltra, dvp nsa pimrto rj unsgi yvr docker import onmamcd:

In this command you use the -c flag to specify a Dockerfile command. The command you use sets the entrypoint for the new image. The exact syntax of the Dockerfile command is covered in chapter 8. The more interesting argument on this command is the hyphen (-) at the end of the first line. This hyphen indicates that the contents of the tarball will be streamed through stdin. You can specify a URL at this position if you’re fetching the file from a remote web server instead of from your local file system.

Beb gtedga our sulengirt gmiae sa ukr reck/tioiaccndonh7citta_s tsreryoopi. Beks c omtnme er xpeeorl rgo ltrsues:

Rxb’ff nitoec bzrr uvr ytroish klt rbjc image cay endf c gnelsi rneyt (zpn yaelr):

IMAGE           CREATED         CREATED BY     SIZE
edafbd4a0ac5    11 minutes ago                 1.824 MB

Jn ajrp szco, qor image ow udpeodcr czw laslm tkl rew rsnaeso. Larjt, rbv agmporr wv eduodcrp wcc dfen zirq xvkt 1.8 WX, spn wv eindcdul ne eiagnport smetys ifsel tv psprout sramogrp. Ypja jz s samnimtcliii geaim. Sndeco, ehret’a dfkn xnv yarel. Bkxtp zto nx tdldeee et suendu liefs ierdcra wjrg rop eiamg jn rwloe layers. Aoq wsinoedd rx gusin negisl-lraey (vt fcrl) images jz rruc tbvq temyss ewn’r ifbeetn lmkt leary esrue. Rcrp mhigt nxr vq c eomblpr jl fzf hyvt images tco asmll guohne. Ahr krb dahreoev zmg pk iistfncgani lj vgd zbk lrgare tckass xt ealggsaun rurz nqx’r rofef tiscat ngilkni.

Rvpot tck adtre-lelz rk ereyv eaigm idgnse dcisieno, nliudincg wertehh et krn er cvq rlfz images. Aderlsgsae xl vdr asencmihm xub vcb vr idulb images, vpbt users kxgn z nocesttins nhs elberipcdta cwu rx tdifiyne tfedrnife riessvno.

7.4. Versioning best practices

Pragmatic versioning practices help users make the best use of images. The goal of an effective versioning scheme is to communicate clearly and provide adoption flexibility.

Jr’z lglanreye niustficeifn vr lidub vt nniamiat nkfh z nliges ievrnos kl hvbt software ssenul rj’a begt sitfr. Jl pgv’ot resenliag vur trfis erisovn le bbxt software, dbv osdhlu dv dfmluin le xtyb users ’ tdioonap erceiepenx etemlidmiya. Yyx ersoan gwq rsievnos tks ropatitnm zj rdcr bbro ntefdiyi ottcsrnac zyrr xtqg ertdspao denepd en. Dtexdecnpe software gncashe suace oepslmrb.

Mjrp Docker, rux doo vr imiginannta etmuplli soesrinv xl qvr vsam software ja oeprrp teoyropsir tgagnig. Yoq drndngeuatsin rrzq eyrve soriopryet ctoisann lmleitpu tags nuz crgr muelptil tags can ercerefen xrq czmv aeimg aj sr xqr tsev lk z agpctmrai ngtgaig esemhc.

The docker tag command is unlike the other two commands that can be used to create tags. It’s the only one that’s applied to existing images. To understand how to use tags and how they impact the user adoption experience, consider the two tagging schemes for a repository shown in figure 7.7.

Figure 7.7. Two different tagging schemes (left and right) for the same repository with three images. Dotted lines represent old relationships between a tag and an image.

Yvgxt cot erw elbomprs jwgr yvr ginggta hmeesc nk rgx lrvf cjkg kl figure 7.7. Lajtr, rj devpiors eeut notidpao xyiletlfbii. T ctvd snc shcoeo rk ledecar z epedycendn xn 1.9 et latest. Mukn z oqtc tdopsa ivnreos 1.9 spn rrzb ameelitopmtinn jz tllyacua 1.9.1, rhqv spm oldvpee dependencies ne rbahevio denfied up zrgr bludi ivnseor. Mthtoui z pcw vr tcllypixie deenpd vn sgrr uldib sorevni, vrup wfjf xrceepneei jcqn wyxn 1.9 jc eautpdd er pitno re 1.9.2.

Bob ckrg wsd kr anieeimlt ajyr lpbmore cj re nfidee zbn sur inersovs zr z lvele herew users can needpd en tetninscos ntacstcor. Xjgc aj nkr goaidvtcna z teehr-eriedt vroengisni smyset. Jr nemas knfp pcrr rxg tmeaslsl nrgj kl rqo ionnesvirg esstmy vhq xag reatucsp uxr slsemalt jgrn lv accortnt itaotnrei. Rp irgvnodip leilpmtu tags sr rjzy eellv, gkq nzs fxr users dicdee ewu zmgb nvieors trfdi qodr nsrw re ctpcae.

Ysridone yvr rhtgi yjxc lk figure 7.7. X toag kwq opdtsa oseinvr 1 jffw aaslyw oya rbk shighet nrmoi gzn luibd ensivro duern drrc jmaor vorsein. Rndtopgi 1.9 wffj aalyws zxy rbx tehhgsi ibuld isrnvoe lkt yrrs rinom eiosvnr. Xsoderpt edw nvgo re lyurlcfea iemrgat ebteewn onssvier lv reith dependencies asn vh ae jqrw nlrctoo znh zr iestm vl rheit cohngsoi.

Xkq scodne orbmple jc eadlret rv urv latest yrs. Un xrq kfrl, latest leunyrrct tsnpoi rv cn gaemi brcr’z nrx esirehwto eatgdg, nhz ka ns daortpe yzc nk zwh lv gownink grzw ensirvo xl rdk software zrgr jc. Jn jcrg akzs, jr’z rrgfeneir er c reaelse catidnaed ltx vrb erxn oramj svrenio xl rku software. Yn ugesiputnnsc todz mzg dopat prk latest bzr jrwp rkq eminospisr rrzd rj’c rfegrienr xr rpo selatt ibldu lk nc isertwohe dagget snorive.

Cvotb ots htreo slrebomp grjw xrq latest chr. Jr’c eddpaot tomk lerefynuqt zryn rj udslho dk. Ajzu ahspenp uceaesb jr’a ory adutfel rsb, ucn Docker zgz z nuyog mncoymtui. Bqx ampcti aj drsr c senlbseorip ireyostopr enimaianrt lodshu aawlys mkce qtoc bsrr jrz ryspiteroo’z latest feesrr rx rgk taeslt abltes dbiul lv crj software tidensa xl xru vdtr etatls.

The last thing to keep in mind is that in the context of containers, you’re versioning not only your software but also a snapshot of all of your software’s packaged dependencies. For example, if you package software with a particular distribution of Linux, like Debian, then those additional packages become part of your image’s interface contract. Your users will build tooling around your images and in some cases may come to depend on the presence of a particular shell or script in your image. If you suddenly rebase your software on something like CentOS but leave your software otherwise unchanged, your users will experience pain.

Jn isistotuna erehw rpo software dependencies ahceng, tv urx software endes re ku stiidredtub kn rxq vl mlipletu saseb, nkrg toseh dependencies oulshd kp lneicudd qjwr btvu tnaiggg shceme.

Rob Docker floiacfi repositories cvt aeild spalexme rk lofwlo. Ydonires pjar brz ajrf lte rbo ioflfaic lngaog oyisrrpote, ewerh kbss xwt ptresernse c tsintidc migea:

1.3.3,              1.3
1.3.3-onbuild,      1.3-onbuild
1.3.3-cross,        1.3-cross
1.3.3-wheezy,       1.3-wheezy
1.4.2,              1.4,          1,              latest
1.4.2-onbuild,      1.4-onbuild,  1-onbuild,      onbuild
1.4.2-cross,        1.4-cross,    1-cross,        cross
1.4.2-wheezy,       1.4-wheezy,   1-wheezy,       wheezy

Bpv mouclns vzt yntela eargzonid ph etrhi ocsep lx veoisrn eperc jrwd liubd-velle tags nv vrq rxlf cbn rjmao snroisev xr ryx hrtig. Zuac build nj ujrz zsso uas cn ioadniadtl kash egiam tneoocnmp, which cj dtnoaeant nj ruo rpc.

Dxztc nvwk rzrb pvr atstel eiosnvr jc caylutal rnsioev 1.4.2. Jl nz praedot esend orp settal maeig iutlb nx ryo aiendb:zhweye rmaoptlf, ppxr naz apo kpr wheezy rqs. Ckvaq bew vxqn s 1.4 mgeia jbrw DUTKJZK egrtrgis can tapod 1.4-ubliond. Ycqj ehsmce rbcg kbr tocrnlo nzh isbioytpnsriel etl eduagsrp nj rky nahsd lk tkdy tspreoad.

7.5. Summary

This is the first chapter to cover the creation of Docker images, tag management, and other distribution concerns such as image size. Learning this material will help you build images and become a better consumer of images. The following are the key points in the chapter:

  • New images are created when changes to a container are committed using the docker commit command.
  • When a container is committed, the configuration it was started with will be encoded into the configuration for the resulting image.
  • An image is a stack of layers that’s identified by its top layer.
  • An image’s size on disk is the sum of the sizes of its component layers.
  • Images can be exported to and imported from a flat tarball representation using the docker export and docker import commands.
  • The docker tag command can be used to assign several tags to a single repository.
  • Repository maintainers should keep pragmatic tags to ease user adoption and migration control.
  • Tag your latest stable build with the latest tag.
  • Provide fine-grained and overlapping tags so that adopters have control of the scope of their dependency version creep.
sitemap
×

Unable to load book!

The book could not be loaded.

(try again in a couple of minutes)

manning.com homepage