How to Build Windows Docker Images with GitHub Actions
Have you ever needed to build a Windows Docker image but don't have access to a Windows machine? In this guide, I'll show you how to leverage GitHub Actions to build Windows container images without needing a local Windows environment. Why Build Windows Docker Images? While Linux containers are more common, Windows containers are essential for: .NET Framework applications Windows-specific applications Legacy Windows applications that need containerization Applications that require Windows-specific features Prerequisites Before we start, you'll need: A GitHub account A Docker Hub account A repository with your Dockerfile and application code Docker Hub credentials configured as GitHub secrets You can take a look at my example repository for reference. The Dockerfile Let's look at a sample Dockerfile that sets up a Python environment on Windows: # Use a more recent Windows Server Core image FROM mcr.microsoft.com/windows/servercore:ltsc2022 # Set shell to PowerShell SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"] # Download and install Python RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \ Invoke-WebRequest -Uri https://www.python.org/ftp/python/3.9.5/python-3.9.5-amd64.exe -OutFile python-3.9.5-amd64.exe ; \ Start-Process python-3.9.5-amd64.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; \ Remove-Item python-3.9.5-amd64.exe # Verify Python installation RUN python --version # Set the working directory WORKDIR /app # Copy application files COPY . /app # Set the startup command CMD ["python", "app.py"] This Dockerfile: Uses the mcr.microsoft.com/windows/servercore:ltsc2022 base image Installs Python 3.9.5 Sets the working directory to /app Copies the application files to the container Specifies the startup command as python app.py Setting Up GitHub Actions Create a .github/workflows/build.yml file in your repository: name: Build Windows Docker Image on: push: branches: [ main ] workflow_dispatch: jobs: build: runs-on: windows-latest environment: prod steps: - name: Checkout code uses: actions/checkout@v4 - name: Login to Docker Hub uses: docker/login-action@v3 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and Push shell: powershell run: | docker build . -t ${{ secrets.DOCKERHUB_USERNAME }}/windows-python:latest docker push ${{ secrets.DOCKERHUB_USERNAME }}/windows-python:latest How It Works The workflow runs on windows-latest runner provided by GitHub Actions It checks out your code Logs into Docker Hub using your credentials Builds the Windows Docker image Pushes the image to Docker Hub Displays the image digest for verification Note that in this example, for simplicity, we're using the latest tag. In a production environment, you should use versioned tags and instead of hardcoding the image name, you can use environment variables. Important Considerations Image Size: Windows containers are typically larger than Linux containers. Plan your registry storage accordingly. Build Time: Windows container builds usually take longer than Linux builds. Compatibility: Ensure your base image version matches your deployment environment. Resources Want to learn more about Docker? Check out these resources: How to Create Multi-Platform Docker Images Free Docker eBook Example Repository Conclusion GitHub Actions makes it possible to build Windows Docker images without a local Windows environment. This approach is particularly useful for cross-platform teams or developers primarily working on non-Windows systems. If you're new to Docker and want to learn more, I've written a comprehensive free Docker eBook that covers all the basics and more. Want to try this out but don't have a server? You can use my DigitalOcean referral link to get a free $200 credit! Have questions or want to share your experience? Feel free to reach out to me on Twitter @bobbyiliev_.

Have you ever needed to build a Windows Docker image but don't have access to a Windows machine? In this guide, I'll show you how to leverage GitHub Actions to build Windows container images without needing a local Windows environment.
Why Build Windows Docker Images?
While Linux containers are more common, Windows containers are essential for:
- .NET Framework applications
- Windows-specific applications
- Legacy Windows applications that need containerization
- Applications that require Windows-specific features
Prerequisites
Before we start, you'll need:
- A GitHub account
- A Docker Hub account
- A repository with your Dockerfile and application code
- Docker Hub credentials configured as GitHub secrets
You can take a look at my example repository for reference.
The Dockerfile
Let's look at a sample Dockerfile that sets up a Python environment on Windows:
# Use a more recent Windows Server Core image
FROM mcr.microsoft.com/windows/servercore:ltsc2022
# Set shell to PowerShell
SHELL ["powershell", "-Command", "$ErrorActionPreference = 'Stop'; $ProgressPreference = 'SilentlyContinue';"]
# Download and install Python
RUN [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; \
Invoke-WebRequest -Uri https://www.python.org/ftp/python/3.9.5/python-3.9.5-amd64.exe -OutFile python-3.9.5-amd64.exe ; \
Start-Process python-3.9.5-amd64.exe -ArgumentList '/quiet InstallAllUsers=1 PrependPath=1' -Wait ; \
Remove-Item python-3.9.5-amd64.exe
# Verify Python installation
RUN python --version
# Set the working directory
WORKDIR /app
# Copy application files
COPY . /app
# Set the startup command
CMD ["python", "app.py"]
This Dockerfile:
- Uses the
mcr.microsoft.com/windows/servercore:ltsc2022
base image - Installs Python 3.9.5
- Sets the working directory to
/app
- Copies the application files to the container
- Specifies the startup command as
python app.py
Setting Up GitHub Actions
Create a .github/workflows/build.yml
file in your repository:
name: Build Windows Docker Image
on:
push:
branches: [ main ]
workflow_dispatch:
jobs:
build:
runs-on: windows-latest
environment: prod
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and Push
shell: powershell
run: |
docker build . -t ${{ secrets.DOCKERHUB_USERNAME }}/windows-python:latest
docker push ${{ secrets.DOCKERHUB_USERNAME }}/windows-python:latest
How It Works
- The workflow runs on
windows-latest
runner provided by GitHub Actions - It checks out your code
- Logs into Docker Hub using your credentials
- Builds the Windows Docker image
- Pushes the image to Docker Hub
- Displays the image digest for verification
Note that in this example, for simplicity, we're using the latest
tag. In a production environment, you should use versioned tags and instead of hardcoding the image name, you can use environment variables.
Important Considerations
- Image Size: Windows containers are typically larger than Linux containers. Plan your registry storage accordingly.
- Build Time: Windows container builds usually take longer than Linux builds.
- Compatibility: Ensure your base image version matches your deployment environment.
Resources
Want to learn more about Docker? Check out these resources:
Conclusion
GitHub Actions makes it possible to build Windows Docker images without a local Windows environment. This approach is particularly useful for cross-platform teams or developers primarily working on non-Windows systems.
If you're new to Docker and want to learn more, I've written a comprehensive free Docker eBook that covers all the basics and more.
Want to try this out but don't have a server? You can use my DigitalOcean referral link to get a free $200 credit!
Have questions or want to share your experience? Feel free to reach out to me on Twitter @bobbyiliev_.