Using image tags for deploying different versions of container - artisticcheese/artisticcheesecontainer GitHub Wiki

##How to use image tags for running different versions of container side by side Container images in additional to having names also support "tag" properties which allows you to use those for versioning during both Dev and Production rollout. Tags can be added during image creation or later with Add-ContainerImageTag cmdlet. Sample application in artisticcheese\iis image has a bug in it which is showing PI number with series of digits with no "." in it as you can see at the end of last post.

PS D:\docker> Invoke-WebRequest http://172.24.232.204/pi/service.svc/pi/400 | select Content
Content
-------
"31415926535897932384626433832795028841971693993751058209...

Let's add tag to this image version1 and launch it. This will launch version1 of artisticcheese\iis container and map port 8081 to it.

Import-module docker
$config = [Docker.DotNet.Models.Config]::new()
($config.ExposedPorts  = [System.Collections.Generic.Dictionary[string,object]]::new()).Add("80/tcp", $null)
$hostConfig = [Docker.DotNet.Models.HostConfig]::new()
$pb = new-object Docker.DotNet.Models.PortBinding
$pb.HostPort = "8081"
$hostConfig.PortBindings = [System.Collections.Generic.Dictionary[string, System.Collections.Generic.iList[Docker.DotNet.Models.PortBinding]]]::new()
$hostConfig.PortBindings.Add("80/tcp",[System.Collections.Generic.List[Docker.DotNet.Models.PortBinding]]::new([Docker.DotNet.Models.PortBinding[]]@($pb)))
Run-ContainerImage -ImageIdOrName "artisticcheese/iis:Version1" -Configuration $config -Detach -name "version1"  -HostConfiguration $hostConfig

You can issue request and inspect response (containing bug) below

PS C:\Windows\system32> Invoke-WebRequest 192.168.1.231:8081/pi/service.svc/pi/40 | select Content
Content
-------
"31415926535897932384626433832795028841971"

You developer at this point being informed about the bug issues a code fix. You can fix the code by going to your content folder and uncomment code on line 16 which reads as return (CalculatePi(Int32.Parse(value)).Insert(1, ".")). Your resulting code shall look like

public string GetPI(string value)
{
 return (CalculatePi(Int32.Parse(value)).Insert(1, "."));
}

Your developer at this point have to rebuild the image so latest version of the code is baked into container image and assign it Version2 tag

new-containerImage -Path D:\docker\ -Repository artisticcheese/iis -Tag "Version2" -Isolation HyperV -Verbose 

If you pull container images now you will see one image artisticcheese\iis with 2 different tags Version1 and Version2

PS D:\docker> get-containerimage

RepoTags                                 ID                   Created                        Size(MB)
--------                                 --                   -------                        --------
artisticcheese/iis:Version2              sha256:32fc95c43c... 1/24/2017 3:25:20 PM           9,910.04
artisticcheese/iis:Version1              sha256:a9d358ec90... 1/24/2017 1:40:49 AM           9,911.13
artisticcheese/base:latest               sha256:2bf963f532... 1/23/2017 5:40:09 PM           9,662.00
microsoft/iis:latest                     sha256:7d4c79e586... 1/11/2017 8:03:09 PM           9,383.55

Also you can see that you still have running image based off Version1. Y

PS D:\docker> get-container | select -ExpandProperty Image
artisticcheese/iis:Version1

Launch a Version2 of container and map it to port 8082

Import-module docker
$config = [Docker.DotNet.Models.Config]::new()
($config.ExposedPorts  = [System.Collections.Generic.Dictionary[string,object]]::new()).Add("80/tcp", $null)
$hostConfig = [Docker.DotNet.Models.HostConfig]::new()
$pb = new-object Docker.DotNet.Models.PortBinding
$pb.HostPort = "8082"
$hostConfig.PortBindings = [System.Collections.Generic.Dictionary[string, System.Collections.Generic.iList[Docker.DotNet.Models.PortBinding]]]::new()
$hostConfig.PortBindings.Add("80/tcp",[System.Collections.Generic.List[Docker.DotNet.Models.PortBinding]]::new([Docker.DotNet.Models.PortBinding[]]@($pb)))
Run-ContainerImage -ImageIdOrName "artisticcheese/iis:Version2" -Configuration $config -Detach -name "version2"  -HostConfiguration $hostConfig

Check that both containers are running. docker ps provides better view of running containers outlining both image container is based off as well as port mapping.

PS D:\docker> docker ps
                    CONTAINER ID        IMAGE                         COMMAND                  CREATED              STATUS              PORTS                  NAMES
8b8c4d2d99d0        artisticcheese/iis:Version2   "cmd /S /C 'powers..."   About a minute ago   Up 47 seconds       0.0.0.0:8082->80/tcp   version2
bb8e58bfeeba        artisticcheese/iis:Version1   "cmd /S /C 'powers..."   32 minutes ago       Up 31 minutes       0.0.0.0:8081->80/tcp   version1

Issue the same request to verify you in fact have corrected version running on port 8082.

PS C:\Windows\system32> Invoke-WebRequest 192.168.1.231:8082/pi/service.svc/pi/40 | select Content
Content
-------
"3.1415926535897932384626433832795028841971"

As you can see you can perfectly happy running containers side by side just using different image tags. This is obviously helpfull both for development and rollout in production since you mix and match versions of applications and switch between them at will.