Create Container Image Interactively - egnomerator/misc GitHub Wiki
Note on Environment
- This documentation assumes that Docker for Windows (Stable channel) is already installed and running
- This documentation was created with Docker CE version 17.12.0-ce-win47 (15139) intalled
- if any operations below fail, it could be due do different Docker versions
This guide assumes some level of familiarity with relevant terminology.
This guide is not about Dockerfiles but briefly discusses them here for context.
Most commonly, Docker container images are created with Dockerfiles that contain a script to automate the creation of the image
- These Dockerfiles begin with a command that indicates to start with a base image (e.g. Windows Server Core) and continue with commands to customize the image
- Then a
docker build
command is used to run this Dockerfile's script producing a new image
As a learning tool and for academic interest, this is a guide for creating an image interactively, meaning
- The base image will run interactively when using the
-it
flags - Changes to the image will be made while the container is running
- After exiting the container, the changes will be committed resulting in a new image
While performing the following steps (which will include running commands in CMD), keep a separate instance of CMD open, and at any point through these steps, run either of these commands:
# to view existing images
docker images
# to view all container image layers (running or inactive)
docker ps -a
This procedure will start with downloading a base image that already has the Windows Server 2016 OS and also .NET Framework 4.6.2 installed.
- Get base image (significant download size/time)
- The Windows Server 2016 base container image and .NET Framework layers and ASP.NET layers
- The below command gets the Windows Server 2016 base container image and .NET Framework version layers (located in this official Microsoft Docker Hub Repository)
docker pull microsoft/dotnet-framework
- The below command gets the ASP.NET version layers (located in this official Microsoft Docker Hub Repository)
- This is not the base image we will build on, but is worth looking at for comparison
docker pull microsoft/aspnet
- Add ASP.NET 4.6.2
- The below command
- gets and runs, in interactive mode, the Windows Server 2016 base image (from local now) with the .NET Framework 4.6.2 layer
- This may download the latest version, but will not take as long as the base image download from step one
- gets and runs, in interactive mode, the Windows Server 2016 base image (from local now) with the .NET Framework 4.6.2 layer
docker run -it microsoft/dotnet-framework:4.6.2-windowsservercore-ltsc2016 cmd
- Start PowerShell and get list of currently enabled Windows Services
C:\> powershell PS C:\> get-windowsfeature
- scroll down and see that .NET 4.6 is installed and not ASP.NET 4.6
- Add ASP.NET 4.6 and see success message
PS C:\> add-windowsfeature net-framework-45-aspnet Success Restart Needed Exit Code Feature Result ------- -------------- --------- -------------- True No Success {ASP.NET 4.6}
- optionally, get list of currently enabled Windows Services again to verify the success
- Exit PowerShell, and then exit CMD
PS C:\> exit C:\> exit
- After exiting CMD, nothing will be running in the container anymore, so the container will automatically stop running
NOTE on container stopping automatically:
- Without the
-it
flags for interactive mode- The container would have
- Started
- Opened CMD
- CMD would have
- Ran any given command arguments (none in this case)
- Exited
- CMD would have
- Exited
- The container would have
- Running the container in CMD without the
-it
flags only accomplishes something if command arguments are passed to that Docker run command-
This is actually how Dockerfiles work:
- They are a series of commands that run a container, edit it, allow it to exit, and repeat, until all desired changes are completed
-
This is actually how Dockerfiles work:
- Without the
- The below command
- Create a new image layer with the recent change
- view existing container layers
- (values in "NAMES" column are added automatically unless the name was specified earlier in the run command)
- in the below screenshot, 2 are "Up", and one is "Exited" (inactive)
- the exited container layer is the one that was updated with ASP.NET 4.6
- copy this container's value in the "CONTAINER ID" column
- commit the recent change using the copied container Id, and giving the resulting image a name
# command format: docker commit <containerid> <image name> docker commit 76027c26233e ms-windowsservercore-dotnet4.6.2-plus-aspnet-4.6.2
- view new image in image list
docker images
- Sanity check: run an interactive container based on the recently created image
- this time use the
--rm
flag to remove the new container layer after exiting this container
- this time use the
docker run -it --rm ms-windowsservercore-dotnet4.6.2-plus-aspnet-4.6.2 cmd
- repeat the earlier commands to get into PowerShell, view the enabled Windows features, and scroll to verify that ASP.NET 4.6 is enabled, then exit
- note that while this container is running,
docker ps -a
will show an "Up" container with the name of this image, and after exiting the container,docker ps -a
will show this container layer no longer exists (because of the--rm
flag)
This process was very interesting and gives a little scratching-the-surface peak at the automation that Dockerfiles provide.
note: Windows Server Core does not have UAC
- UAC is not available in Server Core
- This is just an FYI in case issues arise during any operations - it's not a permissions issue