Build real life custom container - artisticcheese/artisticcheesecontainer GitHub Wiki

Content below is pretty close to production ready content which will involve having real IIS content on server, create web application, configuring username/password for remote administration via IIS Manager etc. In last article I have shown how to build custom image with some prerequisites for this container image. Image was called artisticcheese\base. We are going to build an image on top of it with desired customization including content etc.

  1. Include content in image and configure application dockerfile for this images is below
#We are basing off not Microsoft but our own image built in last step
FROM artisticcheese/base
#Adding 2 scripts to image, contents of each will be shown below
ADD startup.ps1 ./startup.ps1
ADD iisconfig.ps1 ./iisconfig.ps1
#Copying website content which is available at https://github.com/artisticcheese/artisticcheesecontainer/tree/master/content
COPY /content/ c:/inetpub/wwwroot/content/
#Creating website and application pool
RUN powershell.exe .\iisconfig.ps1
#Entry point is modified to perform some provisioning at startup (creating local administrator account)
ENTRYPOINT powershell.exe c:\startup.ps1; del c:\startup.ps1; C:\ServiceMonitor.exe w3svc
EXPOSE 80

Content of iisconfig.ps1 is below

Configuration IIS
{
    Import-DscResource -ModuleName "PSDesiredStateConfiguration" 
    Import-DSCResource -moduleName "xWebAdministration"
    node localhost
    {
        xWebApplication PI
        {
            Name = "PI"
            Website = "Default Web Site"
            WebAppPool = "DefaultAppPool"
            PhysicalPath = "c:\inetpub\wwwroot\content\"
            Ensure = "Present"
        }
    }
}
IIS -Outputpath .\BasicIIS
Start-DscConfiguration -Wait -Verbose -Path .\BasicIIS -Force
  1. Create local administrator username/password Content of startup.ps1 is below which requires additional explanation. Microsoft does not provide a way to remotely connect to server for administer it through any tools. The only way to administer containers currently is to use powershell console on containerhost via Enter-PSSession or docker exec command. Startup.ps1 script creates local username and password and adds it to container "Administrators" group, which in turn allows you to remotely use Server Manager as well as IIS Manager. As you can see from script username/password is being pulled from environment variable which is passed during instantiation time.
$VerbosePreference = "Continue"
$ErrorActionPreference =  "Continue"
$ContainerAdmin = $env:ContainerAdmin
$ContainerPassword = $env:ContainerPassword
if ((Get-LocalUser -Name $ContainerAdmin ).Count -eq 1) {
    Write-Verbose "Admin container user already exists, updating password to $ContainerPassword"
    Set-localuser -Name $ContainerAdmin -Password (ConvertTo-SecureString  $ContainerPassword -AsPlainText -Force) 
}
else {
    Write-Verbose "Admin container does not exist, creating user"
    new-LocalUser -Name $ContainerAdmin -Password  (ConvertTo-SecureString  $ContainerPassword -AsPlainText -Force) 
}
if (((Get-LocalGroupMember administrators) -notmatch  $ContainerAdmin)) {
    Write-Verbose "$containeradmin is not part of local Administrator's group, adding it"
    Add-LocalGroupMember -Group Administrators -Member $ContainerAdmin 
}

Build this image

new-containerImage -Path D:\docker\ -Repository artisticcheese/iis -Tag "newversion" -Isolation HyperV -Verbose | Add-ContainerImageTag -Repository artisticcheese/iis  -Tag "latest" 

If everything worked as expected you shall be able to launch this image passing environment variables and connect to it remotely using IIS Manager or server manager. As you can see my containeradmin and containerpassword environment variables are being read from my containerhost during start up. If you don't have those setup then create them first via $env:Containeradmin = "myadmin" and $env:containerpassword = "myPassword!" and restart powershell session. Run your image

Import-module docker
$config = [Docker.DotNet.Models.Config]::new()
($config.Env = [System.Collections.Generic.List[string]]::new()).Add("containeradmin=$($env:ContainerAdmin)")
$config.Env.Add("containerpassword=$($env:ContainerPassword)")
Run-ContainerImage -ImageIdOrName "artisticcheese/iis:latest" -Configuration $config -Detach -name "iis"

This shall launch and image which on start up will be provided username/password via environment variables and startup.ps1 EntryPoint statement will perform tasks to precreate this user and assign it to Administrator's group. 3. Connect to running container via IIS Manager and Server Manage

  • Find IP address of your new container via (Get-ContainerDetail iis).NetworkSettings.Networks["nat"].IPAddress
  • Open IIS manager on your workstation. Click "File/Connect To a Server", put IP address and username/password you specified. You shall be able to see IIS Management console as expected as well as PI application which was created via DSC.

If everything is successful you shall be able to see event viewer entries as well services tab etc.

  • You can test web application as well. It shall show you value of PI to certain number (last parameter). Example below calculating of PI to 400s digit
PS D:\docker> Invoke-WebRequest http://172.24.232.204/pi/service.svc/pi/400 | select Content

Content
-------
"31415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756...