Building a Windows container image

When you generate artifacts for Windows workloads, the artifacts are zipped and copied into a Cloud Storage bucket as an intermediate location that you can download. This zip file contains a Dockerfile, the deployment_spec.yaml file, and several directories and files that are extracted from the source that you then use to build the Windows container.

Before you begin

Before building the Windows container, you should have first:

Download the migration's artifacts zip file

The migration artifacts are contained in a single zip file named that you must download as part of building the container image.


  1. When the migration completes, you should see a message such as the following when you request status:

    migctl migration status my-migration
    NAME            CURRENT-OPERATION       PROGRESS        STEP            STATUS    AGE
    my-migration    GenerateArtifacts       [1/1]           ExtractImage    Completed 14m23s
  2. After the migration has completed, use migctl migration get-artifacts to obtain the generated file:

    migctl migration get-artifacts my-migration
    Downloaded artifacts for Migration my-migration. The artifacts are located in "PATH"`


When the migration completes, you see Artifacts generated in the Status column of the migration. To download all migration artifacts:

  1. Open the Migrate to Containers page in the Google Cloud console.

    Go to the Migrate to Containers page

  2. Click the Migrations tab to display a table containing the available migrations.

  3. Choose the migration row with a Name matching the desired migration.

  4. Select the Artifacts link.

Building the container image

The procedure shown below builds a Windows container multi-arch image from the migration artifacts.

The build process is done using the Windows Cloud Builder, documented here:

The build process is done using Windows Cloud builder. Ensure you complete all tasks in this section:

You can deploy a container running the resulting image on any cluster with a Windows node-pool, as described in Deploying Windows workloads.

Buildling the image

  1. Create a workspace directory on your work machine, for example: ~/gke-windows-builder/migrated-image.

  2. Unzip the file from the path you downloaded them to in Download the migration's artifacts zip file:

    unzip PATH/ -d ~/gke-windows-builder/migrated-image
  3. Cd into the directory belonging to the image you wish you build. For example:

    cd  migrated-image-ax_eq

  4. In the same directory, create a cloudbuild.yaml file. It will contain the build's configuration.

    Copy the following example to the file, and replace <REGISTRY_REGION> and <REPOSITORY> with the Artifact Registry repository region and name, respectively. At build time, Cloud Build automatically replaces $PROJECT_ID with your project ID.

    # Copyright 2020 Google LLC
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
    timeout: 3600s
    - name: ''
      - --container-image-name
      # Replace <REGISTRY_REGION> and <REPOSITORY>.
      - '<REGISTRY_REGION>$PROJECT_ID/<REPOSITORY>/multiarch-helloworld:latest'
      # Specify specific variants of images to be built. Or, remove the following 2 lines to default to all available variants.
      - --versions
      - '20H2,ltsc2019'
  5. To build the image, run the following command:

    gcloud builds submit --config=cloudbuild.yaml .
  6. You'll see logs similar to the following example. The last line in the log shows that the build succeeded:

    Creating temporary tarball archive of 2 file(s) totalling 492 bytes before compression.
    Uploading tarball of [.] to [gs://PROJECT_ID_cloudbuild/source/1600082502.509759-b949721a922d462c94a75da9be9f1181.tgz]
    Created [].
    Logs are available at [].
    ------------------------ REMOTE BUILD OUTPUT---------------------------------------
    Created manifest list
    2020/09/14 11:34:25 Instance: shut down successfully
    ID                                    CREATE_TIME                DURATION  SOURCE                                                                                      IMAGES  STATUS
    ec333452-1301-47e8-90e2-716aeb2f5650  2020-09-14T11:21:43+00:00  12M43S    gs://PROJECT_ID_cloudbuild/source/1600082502.509759-b949721a922d462c94a75da9be9f1181.tgz  -                 SUCCESS

You've just built the image using the build config file and pushed the image to Artifact Registry at

Configuring logging to Cloud Logging

Migrate to Containers uses the LogMonitor tool to extract logs from a Windows container and forward them to your GKE cluster. These logs are then automatically forwarded to Cloud Logging, which provides a suite of tools to monitor your containers.

By default Migrate to Containers enables IIS logging to monitor the IIS logs, and also forwards the Application/System event logs to Cloud Logging.

Configuring logging

Expanding the generated file creates several directories, including the m4a directory. Included in the m4a directory is the LogMonitorConfig.json file that you can edit to control logging.

For more on editing LogMonitorConfig.json, see Authoring a Config File.

Setting ACLs

Some IIS applications require that you set specific access control lists (ACL) permissions on files and folders in order for the applications to perform correctly. Migrate to Containers automatically scans all migrated IIS applications and adds any specific permissions defined in the source VM that apply to IIS accounts (the IUSR account and the IIS_IUSRS group) and applies them to the copied files and directories in the generated container image.

Because Windows container images do not support setting ACLs as part of the Docker COPY command, the ACLs are set in a script called set_acls.bat. Migrate to Containers automatically creates set_acls.bat in the root directory of expanded file. Migrate to Containers then calls set_acls.bat when you execute the docker build command.

Edit set_acls.bat to add or remove custom permissions, or edit permissions that are not related to specific IIS users and therefore were not detected by Migrate to Containers.

The script uses the Windows built-in icacls tool to set permissions.

About the .NET Global Assembly Cache

Migrate to Containers scans the source image .NET Global Assembly Cache (GAC) for .NET resources that are installed on the source machine and not available as part of the official images. Any discovered DLL is copied into the Docker context and installed as part of the building of the target image by a utility script install_gac.ps1.

All .NET assemblies are copied into the Docker context under the m4a\gac directory. To remove assemblies from the image, delete them from the m4a\gac directory.

Next Steps