Initialize a Windows container with an entrypoint script

A popular Docker article describes a pattern to initialize stateful container data at runtime. The example uses a Shell script to run the initialization and then pass control to the container’s main command. We can use the same pattern to initialize a Docker Windows container.

My example

In keeping with the original example, we’ll initialize data into a database container. This pattern will work for any container though. As we’re using Windows containers, I’ll use the SQL Server (Express) image.

As a side note, it’s not as easy as it should be to initialize a SQL Server container. I’ve followed Tometchy’s excellent Initialize MS SQL in Docker container – create database at startup article. My changes are:

  1. I’m using Windows containers
  2. To demonstrate a point, I want to initialize the database and then run the regular start command

How to initialize a Windows container

First, create a Powershell script that runs the initialization code and then passes control back to a long running process:

What’s happening here is:

  • Line 1: Capture arguments to this script’s invocation. We expect this to be the command we want to run after initialization
  • Line 3-23: Initialization code. In this case we start SQL Server, set an sa password so we can login to it, run the create-database.sql and then stop SQL Server. You can populate this section with any initialization code you need.
  • Line 27: Invoke the script argument as a Powershell command. I’ve shown the equivalent for cmd.exe in line 29.

To execute this code on container startup, simply set the script as the ENTRYPOINT and the original command as the CMD. Here’s what it looks like as Docker Compose:

Note that the command here is the default CMD of the microsoft/mssql-server-windows-express image. Just watch the escaping of $ and \ characters here.

When this container starts, its command is the ENTRYPOINT with the CMD as command line arguments to it. That is:

What actually happens is run-initialization.ps1 does the database initialization work and then invokes everything afterwards as a new Powershell command. That is, it starts the database.

Try it!

Pull the example code from GitHub. I ran it on my Windows 10 (1903) laptop. It should also work in Windows Server 2019.

Leave a Reply

Your email address will not be published. Required fields are marked *