Windows GitHub Self Hosted Runner inside a Linux Container
Tags: github, devops, windows, vagrant
Published: 2024-05-18 15:00:30

With ever-increasing advancements in the world of CI/CD pipelines, innovation is inevitable. Welcome to the exploration of an efficient, cost-effective, and innovative approach to deploying self hosted GitHub Runner. This runner operates in a containerized Windows OS (x64) environment on a Linux system.

The approach leverages the strengths of Vagrant VM, libvirt, and Docker Compose, allowing seamless management of a Windows instance just like any Docker container. The takeaway is the creation of a plug-and-play solution, significantly enhancing convenience, optimizing resource allocation, and integrating flawlessly with existing workflows.

For those working in various dev-ops environments, this strategy provides a smooth and comprehensive solution that does not require prior knowledge of VM creation.

This guide is built upon the [https://github.com/vaggeliskls/windows-github-custom-runner](https://github.com/vaggeliskls/windows-github-custom-runner)

## 📋 Prerequisites

- Docker version 24 or higher
- Docker-compose version 1.18 or higher

## 🚥 Authentication Methods for Self-Hosted

To authenticate your custom self-hosted runners, two methods are available:

1. Personal Access Token (`PAT`): A static, manually created token that provides long-term and secure access to GitHub. This token requires Read and Write access to the GitHub organization’s self-hosted runners.

2. Registration Token (`TOKEN`): A dynamic, short-lived token that is automatically generated by GitHub when creating a new self-hosted runner. This method offers a temporary but immediate solution for authentication.

**⚠ Note:** Only one of these authentication methods is needed. Choose the one that best suits your requirements.

## 🚀 Deployment Guide
**1)** Create/Update the environmental file .env

- `PAT`: Personal access token from GitHub
- `TOKEN`: Short lived Github token
- `RUNNER_URL`: The URL of the GitHub that the runner connects to
- `RUNNERS`: Number of runners
- `MEMORY`: Amount of memory for the Vagrant image (in MB)
- `CPU`: Number of CPUs for the Vagrant image
- `DISK_SIZE`: Disk size for the Vagrant image (in GB)

**Example with PAT**

```
# Runner settings
PAT=<Your Personal access token>
RUNNER_URL=<runner url>
RUNNERS=1
# Vagrant image settings
MEMORY=8000 # 8GB
CPU=4
DISK_SIZE=100

```

**Example with TOKEN**

```
# Runner settings
TOKEN=<Your short lived acess token>
RUNNER_URL=<runner url>
RUNNERS=1
# Vagrant image settings
MEMORY=8000 # 8GB
CPU=4
DISK_SIZE=100
```

**2)** Create `docker-compose.yml`

```
version: "3.9"

services:
  windows-github-runner-vm:
    image: ghcr.io/vaggeliskls/windows-github-custom-runner:latest
    env_file: .env
    stdin_open: true
    tty: true
    privileged: true
    ports:
      - 3389:3389
```

**3)** Run: `docker-compose up -d`

## 🌐 Access via Remote Desktop

For debugging purposes or testing you can always connect to the VM with remote desktop softwares.

Some software that used when developed was

1. Linux: `rdesktop rdesktop <ip>:3389` or [remina](https://remmina.org/)
2. MacOS: [Windows remote desktop](https://apps.apple.com/us/app/microsoft-remote-desktop/id1295203466?mt=12)
3. Windows: buildin `Remote Windows Connection`

## 🔑 User Login

The default users based on vagrant image are

1) Administrator

- Username: Administrator
- Password: vagrant

2) User

- Username: vagrant
- Password: vagrant

## 📚 Further Reading and Resources

- [Windows in docker container](https://github.com/vaggeliskls/windows-in-docker-container)
- [Windows Vagrant Tutorial](https://github.com/SecurityWeekly/vulhub-lab)
- [Vagrant image: peru/windows-server-2022-standard-x64-eval](https://app.vagrantup.com/peru/boxes/windows-server-2022-standard-x64-eval)
- [Vagrant by HashiCorp](https://www.vagrantup.com/)
- [Windows Virtual Machine in a Linux Docker Container](https://medium.com/axon-technologies/installing-a-windows-virtual-machine-in-a-linux-docker-container-c78e4c3f9ba1)