Home
%3CLINGO-SUB%20id%3D%22lingo-sub-890295%22%20slang%3D%22en-US%22%3EAzure%20DevOps%20-%20Docker%20Release%20Pipeline%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-890295%22%20slang%3D%22en-US%22%3E%3CP%3EThis%20article%20provides%20an%20example%20of%20using%20Azure%20DevOps%20to%20manage%20the%20release%20pipeline%20of%20a%20Docker%20application.%20The%20goal%20of%20this%20article%20is%20to%20provide%20a%20practical%20example%20that%20can%20be%20used%20as%20a%20basis%20for%20more%20complex%20scenarios.%3C%2FP%3E%3CH1%20id%3D%22toc-hId-2047071805%22%20id%3D%22toc-hId-2047071805%22%3ESetup%3C%2FH1%3E%3CP%3ELet's%20start%20with%20a%20simple%20container%20and%20instead%20of%20spending%20time%20on%20how%20to%20construct%20this%20let's%20start%20as%20if%20we%20have%20completed%20the%20Microsoft%20Docs%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fdotnet%2Fcore%2Fdocker%2Fbuild-container%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3ETutorial%3A%20Containerize%20a%20.NET%20Core%20app%3C%2FA%3E.%20If%20you%20are%20not%20familiar%20with%20building%20a%20docker%20app%2C%20please%20refer%20to%20the%20tutorial%20to%20get%20started.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EA%20copy%20of%20the%20source%20in%20preparation%20for%20this%20article%20has%20been%20prepared%20here.%20If%20you%20want%20to%20follow%20along%2C%20then%20the%20easiest%20thing%20to%20do%20is%20clone%20the%20project%20as%20a%20starting%20point.%20This%20can%20be%20done%20by%20accessing%20the%20project%20in%20GitHub%3A%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fgithub.com%2Fchilberto%2FTechCommunity-DockerPipeline%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3ETechCommunity-DockerPipeline%3C%2FA%3E%20and%20performing%20a%20clone.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EAn%20Azure%20DevOps%20account%20will%20also%20be%20required.%20You%20can%20get%20started%20with%20the%20setup%20by%20following%20the%20steps%20in%20the%20Microsoft%20Docs%26nbsp%3B%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Fuser-guide%2Fsign-up-invite-teammates%3Fview%3Dazure-devops%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3ESign%20up%20for%20Azure%20DevOps%3C%2FA%3E%26nbsp%3Btutorial.%20With%20an%20Azure%20DevOps%2C%20an%20organization%20and%20project%20will%20also%20be%20required.%20And%20again%2C%20instead%20of%20repeating%20these%20steps%20let's%20refer%20to%20the%20following%20documentation%3A%20%3CA%20href%3D%22https%3A%2F%2Fdocs.microsoft.com%2Fen-us%2Fazure%2Fdevops%2Forganizations%2Faccounts%2Fcreate-organization%3Fview%3Dazure-devops%22%20target%3D%22_self%22%20rel%3D%22noopener%20noreferrer%20noopener%20noreferrer%22%3EQuickstart%3A%20Create%20an%20organization%20or%20project%20collection%3C%2FA%3E.%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EWe%20will%20also%20use%20a%20Container%20Registry%20and%20this%20can%20be%20created%20in%20the%20Azure%20Portal%20in%20the%20Container%20Registry%20section%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151419iAFE954ACFCFDFCF8%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_0.png%22%20title%3D%22clipboard_image_0.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EOne%20thing%20to%20note%20when%20creating%20the%20container%20registry%2C%20is%20the%20Admin%20user%20will%20be%20used%20in%20the%20example%20so%20the%20admin%20user%20should%20be%20enabled%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151420i58EB60A990BBCE13%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_1.png%22%20title%3D%22clipboard_image_1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3EThat%20is%20the%20basic%20setup%20so%20let's%20move%20to%20running%20the%20application%20in%20the%20local%20dev%20environment.%3C%2FP%3E%3CH1%20id%3D%22toc-hId--505085156%22%20id%3D%22toc-hId--505085156%22%3ERunning%20the%20application%20in%20Docker%3C%2FH1%3E%3CP%3EWith%20the%20source%20download%20navigate%20to%20the%20src%20folder%20using%20bash%20or%20powershell.%20The%20Dockerfile%20that%20we%20will%20use%20to%20build%20the%20project%20is%20indicated%20in%20the%20screenshot%20below%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20679px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F135227i836FC09A928D4C8A%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20alt%3D%222019-10-03%2015_15_43-Windows%20PowerShell.png%22%20title%3D%222019-10-03%2015_15_43-Windows%20PowerShell.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20container%20can%20be%20built%20using%20the%20following%20command%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Edocker%20build%20-t%20helloazuredev%20-f%20Dockerfile%20.%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ETake%20a%20moment%20to%20make%20sure%20the%20docker%20image%20runs%20using%20the%20following%20command%3A%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Edocker%20run%20-it%20--rm%20helloazuredev%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EYou%20should%20see%20the%20following%20output%20indicating%20the%20container%20is%20running%20and%20use%20ctrl-c%20to%20quit%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20726px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F135229iDCE9866A80232E89%2Fimage-size%2Flarge%3Fv%3D1.0%26amp%3Bpx%3D999%22%20alt%3D%222019-10-03%2015_24_48-Windows%20PowerShell.png%22%20title%3D%222019-10-03%2015_24_48-Windows%20PowerShell.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EWith%20the%20container%20running%20let's%20create%20the%20Azure%20DevOps%20pipeline.%3C%2FP%3E%3CH1%20id%3D%22toc-hId-1237725179%22%20id%3D%22toc-hId-1237725179%22%3EAdding%20to%20DevOps%3A%3C%2FH1%3E%3CP%3EFor%20this%20example%20we%20will%20be%20using%20an%20external%20source%2C%20a%20GitHub%20repo%2C%20to%20push%20a%20new%20docker%20container%20to%20an%20Azure%20Container%20Registry%20(ACR).%3C%2FP%3E%3CP%3ELet's%20start%20by%20creating%20a%20new%20pipeline%20in%20the%20Azure%20DevOps%20project%20by%20first%20clicking%20on%20the%20Builds%20menu%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151677i2762CFE640374C5C%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_0.png%22%20title%3D%22clipboard_image_0.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EFor%20a%20blank%20project%2C%20you%20will%20see%20the%20New%20pipeline%20button%20available%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151657i9BDAC656922E758A%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_1.png%22%20title%3D%22clipboard_image_1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3EThis%20starts%20a%20wizard%2C%20and%20the%20first%20step%20is%20to%20specify%20where%20the%20code%20will%20be%20located%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151658i8894CEF7B62DFB84%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_2.png%22%20title%3D%22clipboard_image_2.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EDepending%20on%20what%20projects%20you%20have%20been%20involved%20with%20on%20GitHub%2C%20you%20will%20be%20able%20to%20select%20the%20project%20from%20a%20collection%20of%20repos%20returned%20by%20GitHub%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151659iA05D87CDCD461E28%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_3.png%22%20title%3D%22clipboard_image_3.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIf%20you%20are%20using%20a%20public%20repository%2C%20then%20you%20will%20need%20to%20take%20an%20additional%20step%20to%20approve%20the%20installation%20of%20Azure%20Pipelines%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151661iE9761EE7EEE663E1%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_0.png%22%20title%3D%22clipboard_image_0.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20next%20step%20is%20to%20configure%20the%20pipeline%2C%20we%20will%20pick%20thee%20Docker%20pipeline%20to%20start%20with%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151662i557B0A010FC5FE26%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_1.png%22%20title%3D%22clipboard_image_1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20only%20setting%20required%20is%20to%20identify%20the%20Dockerfile%20to%20use%2C%20and%20in%20this%20case%2C%20we%20are%20looking%20for%20any%20Dockerfile%20within%20the%20project%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151663i5A9BEBAAE26E3891%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_2.png%22%20title%3D%22clipboard_image_2.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3EGo%20ahead%20and%20Save%20and%20run%20this%20pipeline%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151664i53F96DC641611BD3%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_3.png%22%20title%3D%22clipboard_image_3.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIf%20all%20goes%20well%20the%20the%20pipeline%20should%20complete%20without%20any%20errors%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151665i7A31F29B38AF96FE%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_0.png%22%20title%3D%22clipboard_image_0.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3ENext%20let's%20make%20a%20connection%20between%20the%20Azure%20DevOps%20project%20and%20the%20Azure%20Container%20Registry.%3C%2FP%3E%3CH2%20id%3D%22toc-hId--1510945287%22%20id%3D%22toc-hId--1510945287%22%3EPushing%20to%20an%20Azure%20Container%20Registry%3C%2FH2%3E%3CP%3EThe%20image%20is%20getting%20built%20without%20error%20but%20for%20this%20scenario%20we%20want%20to%20push%20the%20image%20to%20ACR.%20In%20order%20to%20do%20this%20we%20need%20to%20connect%20our%20ACR%20with%20the%20Azure%20DevOps%20project.%20This%20is%20done%20by%20adding%20a%20new%20Service%20connection.%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EUnder%20project%20settings%20(lower%20left%20corner)%2C%20select%20Service%20connections%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151666i5FFCD8C9CC0FD5F0%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_0.png%22%20title%3D%22clipboard_image_0.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3EThe%20in%20the%20New%20service%20connection%20drop%20down%2C%20select%20Docker%20Registry%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151667i103F61927682F685%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_1.png%22%20title%3D%22clipboard_image_1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3EThis%20will%20allow%20us%20to%20specify%20container%20registries%20in%20Docker%20Hub%2C%20Azure%20Container%20Registry%20and%20others.%20We%20will%20use%20it%20to%20connect%20to%20our%20ACR%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151668iE746C19BF7C4A5A9%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_2.png%22%20title%3D%22clipboard_image_2.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CH2%20id%3D%22toc-hId-231865048%22%20id%3D%22toc-hId-231865048%22%3EBuild%20and%20Push%20to%20ACR%3C%2FH2%3E%3CP%3EOnce%20that%20has%20been%20setup%2C%20let's%20go%20back%20to%20our%20pipeline%20and%20edit%20it%20so%20it%20pushes%20to%20our%20new%20service%20connection.%20There%20are%20many%20ways%20to%20do%20this%20so%20let's%20illustrate%20an%20interesting%20feature.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIf%20we%20navigate%20to%20our%20source%20in%20GitHub%2C%20we%20will%20see%20a%20new%20file%20has%20been%20added%3A%26nbsp%3B%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151669iE70E2F0EE00369BE%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_3.png%22%20title%3D%22clipboard_image_3.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20azure-pipelines.yml%20file%20can%20be%20selected%20and%20edited.%20In%20our%20situation%2C%20let's%20modify%20the%20task%20to%20instead%20perform%20a%20build%20and%20push%20operation.%20The%20source%20is%20shown%20below%20and%20take%20special%20care%20with%20indentation%20as%20indentation%20is%20significant%20in%20YAML%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3E%20%20%20%20-%20task%3A%20Docker%402%0A%20%20%20%20%20%20displayName%3A%20Push%20HelloAzureDev%0A%20%20%20%20%20%20inputs%3A%0A%20%20%20%20%20%20%20%20containerRegistry%3A%20'TechCommunityRegistry'%0A%20%20%20%20%20%20%20%20repository%3A%20'HelloAzureDev'%0A%20%20%20%20%20%20%20%20command%3A%20'buildAndPush'%0A%20%20%20%20%20%20%20%20dockerfile%3A%20'**%2FDockerfile'%0A%20%20%20%20%20%20%20%20tags%3A%20%7C%0A%20%20%20%20%20%20%20%20%20%20%24(tag)%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EOnce%20the%20file%20is%20save%2C%20a%20new%20build%20will%20be%20automatically%20started%20as%20by%20default%20a%20trigger%20is%20created%20to%20start%20whenever%20a%20commit%20is%20performed%20against%20the%20master%20branch.%20This%20is%20shown%20in%20the%20YAML%20file%3A%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-markup%22%3E%3CCODE%3Etrigger%3A%0A-%20master%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CH1%20id%3D%22toc-hId--2123778408%22%20id%3D%22toc-hId--2123778408%22%3EChecking%20the%20Registry%3C%2FH1%3E%3CP%3EThe%20final%20step%20is%20to%20confirm%20that%20a%20new%20image%20has%20been%20pushed%20to%20ACR.%20In%20the%20Azure%20Portal%2C%20select%20the%20Azure%20Container%20Registry%20and%20select%20the%20Repositories%20section%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151678i7D8AA3E5974AC113%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_1.png%22%20title%3D%22clipboard_image_1.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EIf%20all%20completed%20without%20error%2C%20then%20there%20will%20be%20a%20new%26nbsp%3B%3CEM%3Ehelloazuredev%3C%2FEM%3E%20repository%20with%20a%20tagged%20image%20as%20illustrated%20below%3A%3C%2FP%3E%3CP%3E%3CSPAN%20class%3D%22lia-inline-image-display-wrapper%20lia-image-align-inline%22%20style%3D%22width%3A%20400px%3B%22%3E%3CIMG%20src%3D%22https%3A%2F%2Fgxcuf89792.i.lithium.com%2Ft5%2Fimage%2Fserverpage%2Fimage-id%2F151679i125DA31D5448732E%2Fimage-size%2Fmedium%3Fv%3D1.0%26amp%3Bpx%3D400%22%20alt%3D%22clipboard_image_2.png%22%20title%3D%22clipboard_image_2.png%22%20%2F%3E%3C%2FSPAN%3E%3C%2FP%3E%3CP%3ENote%20the%20tag%20corresponds%20to%20the%20build%20id%20from%20the%20Azure%20DevOps%20pipeline.%3C%2FP%3E%3CH1%20id%3D%22toc-hId--380968073%22%20id%3D%22toc-hId--380968073%22%3ESummary%3C%2FH1%3E%3CP%3EThis%20article%20provides%20an%20example%20of%20using%20Azure%20DevOps%20to%20build%20and%20push%20a%20docker%20image%20to%20an%20Azure%20Container%20Registry.%20This%20provides%20many%20advantages%20including%20a%20consistent%20approach%20to%20producing%20container%20images%20and%20automating%20the%20build%20process.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-TEASER%20id%3D%22lingo-teaser-890295%22%20slang%3D%22en-US%22%3E%3CP%3EThis%20article%20provides%20an%20example%20of%20using%20Azure%20DevOps%20to%20manage%20the%20release%20pipeline%20of%20a%20Docker%20application.%3C%2FP%3E%3C%2FLINGO-TEASER%3E%3CLINGO-LABS%20id%3D%22lingo-labs-890295%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3EAzure%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EAzure%20Developer%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E
Occasional Contributor

This article provides an example of using Azure DevOps to manage the release pipeline of a Docker application. The goal of this article is to provide a practical example that can be used as a basis for more complex scenarios.

Setup

Let's start with a simple container and instead of spending time on how to construct this let's start as if we have completed the Microsoft Docs Tutorial: Containerize a .NET Core app. If you are not familiar with building a docker app, please refer to the tutorial to get started.

 

A copy of the source in preparation for this article has been prepared here. If you want to follow along, then the easiest thing to do is clone the project as a starting point. This can be done by accessing the project in GitHub: TechCommunity-DockerPipeline and performing a clone.

 

An Azure DevOps account will also be required. You can get started with the setup by following the steps in the Microsoft Docs Sign up for Azure DevOps tutorial. With an Azure DevOps, an organization and project will also be required. And again, instead of repeating these steps let's refer to the following documentation: Quickstart: Create an organization or project collection

 

We will also use a Container Registry and this can be created in the Azure Portal in the Container Registry section:

 

clipboard_image_0.png

 

One thing to note when creating the container registry, is the Admin user will be used in the example so the admin user should be enabled:

 

clipboard_image_1.png

That is the basic setup so let's move to running the application in the local dev environment.

Running the application in Docker

With the source download navigate to the src folder using bash or powershell. The Dockerfile that we will use to build the project is indicated in the screenshot below:

2019-10-03 15_15_43-Windows PowerShell.png

 

The container can be built using the following command:

 

docker build -t helloazuredev -f Dockerfile .

 

 

Take a moment to make sure the docker image runs using the following command: 

 

docker run -it --rm helloazuredev

 

 

You should see the following output indicating the container is running and use ctrl-c to quit:

2019-10-03 15_24_48-Windows PowerShell.png

 

With the container running let's create the Azure DevOps pipeline.

Adding to DevOps:

For this example we will be using an external source, a GitHub repo, to push a new docker container to an Azure Container Registry (ACR).

Let's start by creating a new pipeline in the Azure DevOps project by first clicking on the Builds menu:

clipboard_image_0.png

 

For a blank project, you will see the New pipeline button available:

clipboard_image_1.png

This starts a wizard, and the first step is to specify where the code will be located:

clipboard_image_2.png

 

Depending on what projects you have been involved with on GitHub, you will be able to select the project from a collection of repos returned by GitHub:

clipboard_image_3.png

 

If you are using a public repository, then you will need to take an additional step to approve the installation of Azure Pipelines:

clipboard_image_0.png

 

The next step is to configure the pipeline, we will pick thee Docker pipeline to start with:

 

clipboard_image_1.png

 

The only setting required is to identify the Dockerfile to use, and in this case, we are looking for any Dockerfile within the project:

clipboard_image_2.png

Go ahead and Save and run this pipeline:

clipboard_image_3.png

 

If all goes well the the pipeline should complete without any errors:

clipboard_image_0.png

 

Next let's make a connection between the Azure DevOps project and the Azure Container Registry.

Pushing to an Azure Container Registry

The image is getting built without error but for this scenario we want to push the image to ACR. In order to do this we need to connect our ACR with the Azure DevOps project. This is done by adding a new Service connection. 

 

Under project settings (lower left corner), select Service connections:

clipboard_image_0.png

The in the New service connection drop down, select Docker Registry:

clipboard_image_1.png

This will allow us to specify container registries in Docker Hub, Azure Container Registry and others. We will use it to connect to our ACR:

clipboard_image_2.png

Build and Push to ACR

Once that has been setup, let's go back to our pipeline and edit it so it pushes to our new service connection. There are many ways to do this so let's illustrate an interesting feature.

 

If we navigate to our source in GitHub, we will see a new file has been added: 

clipboard_image_3.png

 

The azure-pipelines.yml file can be selected and edited. In our situation, let's modify the task to instead perform a build and push operation. The source is shown below and take special care with indentation as indentation is significant in YAML:

 

 

 

    - task: Docker@2
      displayName: Push HelloAzureDev
      inputs:
        containerRegistry: 'TechCommunityRegistry'
        repository: 'HelloAzureDev'
        command: 'buildAndPush'
        dockerfile: '**/Dockerfile'
        tags: |
          $(tag)

 

 

 

 

Once the file is save, a new build will be automatically started as by default a trigger is created to start whenever a commit is performed against the master branch. This is shown in the YAML file:

 

 

trigger:
- master

 

 

 

Checking the Registry

The final step is to confirm that a new image has been pushed to ACR. In the Azure Portal, select the Azure Container Registry and select the Repositories section:

clipboard_image_1.png

 

If all completed without error, then there will be a new helloazuredev repository with a tagged image as illustrated below:

clipboard_image_2.png

Note the tag corresponds to the build id from the Azure DevOps pipeline.

Summary

This article provides an example of using Azure DevOps to build and push a docker image to an Azure Container Registry. This provides many advantages including a consistent approach to producing container images and automating the build process.