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.