---
title: "Docker Desktop for Windows + Jenkins + Kubernetes Deployment Notes"
description: "This guide explains how to enable Kubernetes in Windows Docker Desktop and integrate a Jenkins Pipeline to implement a complete, automated workflow for building Docker images and deploying them to a local K8s cluster."
canonical_url: "https://blog.markkulab.net/en/post/jenkins-deploy-kubernetes-with-docker-for-windows"
author: "Mark Ku"
author_url: "https://blog.markkulab.net/en/author/mark-ku"
site: "Mark Ku's Tech Notes"
date_published: "2024-03-06 01:01:35 +0800"
category: "DevOps"
tags: ["kubernetes", "docker", "windows", "jenkins", "pipeline", "ci/cd", "devops"]
language: "en"
license: "CC BY 4.0"
license_url: "https://creativecommons.org/licenses/by/4.0/"
attribution: "when reusing or quoting, credit the author and link back to the original"
---

# Docker Desktop for Windows + Jenkins + Kubernetes Deployment Notes

## Background
As the number of containers at my company grew, managing them across several Docker Desktop instances became difficult to orchestrate and scale horizontally. So, I spent some time researching how to install Jenkins and integrate it with Kubernetes within Docker Desktop for Windows.

## Why Use Kubernetes?
1. On-demand vertical scaling: easily add or remove new servers (nodes) and manage intra-cluster communication.
1. Automatic horizontal scaling and resource reduction based on demand.
1. Service and performance monitoring.
1. Auto Recovery
1. Server resource optimization.
1. Load balancing (traffic splitting).
1. Service circuit breaking.
1. Automated deployments and rollbacks, with automatic rollback if the application state is incorrect.
1. Hybrid cloud deployment.

## Why Use Kubernetes on Windows?
The company doesn't have Linux servers, and most team members are not proficient with Linux.

## Deployment Flow
![Kubernetes deployment flow](https://blog.markkulab.net/content/markku/posts/jenkins-deploy-kubernetes-with-docker-for-windows/images/windows-k8s-deployment.png)

## Prerequisites
### 1. Install Docker Desktop, and check the boxes for Kubernetes and Show system containers
![Setting up Windows Docker](https://blog.markkulab.net/content/markku/posts/jenkins-deploy-kubernetes-with-docker-for-windows/images/set-up-widnows-docker.png)
P.S. After you click Apply, the connection file at `%USERPROFILE%\.kube\config` will be created automatically.

### 2. Set up a Private Docker Registry Server
```
docker run -d -p 5000:5000 -e REGISTRY_STORAGE_DELETE_ENABLED=true --name registry registry:2
docker update --restart always registry
```
### 3. Configure Docker Engine to add the private IP
```
 "insecure-registries": [
    "192.168.50.49:5000"
  ]  
```
P.S. 192.168.50.49 is the IP of my test machine. You can visit http://192.168.50.49:5000/v2/_catalog to check which images are currently in the private Docker registry.

## Configure Kubernetes
### Dashboard
```
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

kubectl get pod -n kubernetes-dashboard

kubectl proxy

訪問此目錄
http://127.0.0.1:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#/login
```
### First, let's create a token (this token will be used by Jenkins)
```
kubectl describe secrets -n kube-system (kubectl get secrets -n kube-system | Select-String "dashboard" | ForEach-Object { $_ -split " " | Select-Object -First 1 })
```
### Query the Token
```
$TOKEN=((kubectl -n kube-system describe secret default | Select-String "token:") -split " +")[1]
kubectl config set-credentials docker-for-desktop --token="${TOKEN}"
echo $TOKEN
```
![Get token](https://blog.markkulab.net/content/markku/posts/jenkins-deploy-kubernetes-with-docker-for-windows/images/get-token.png)

You can also find the token in the config file.
```
kubectl config view // 同等於訪問 %USERPROFILE%\.kube\config
```
![kube config](https://blog.markkulab.net/content/markku/posts/jenkins-deploy-kubernetes-with-docker-for-windows/images/kube-config.png)

## Configure Kubernetes in Jenkins
### Install Jenkins
Refer to the previously written [article](https://blog.markkulab.net/docker-jenkins-build-docker-image-and-github-integration/).

### Install kubectl in the Jenkins container
```
docker exec -it -uroot jenkins bash // 進入jenkins 容器中
curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.29.1/bin/linux/amd64/kubectl // 下載 kubectl
chmod +x ./kubectl // 給予權限
mv ./kubectl /usr/local/bin/kubectl // 複製到系統環境資料夾
kubectl version --client // 查詢版本
```
P.S. It's best if the kubectl versions in Docker Desktop and the Jenkins container match.

### Copy kubectl configuration to the Jenkins container (execute line by line)
```
docker exec -it -uroot jenkins /bin/bash 
mkdir -p /.kube
exit 
docker cp C:/Users/Mark/.kube jenkins:/root/.kube // 複製檔案到 Jenkins 容器中
```

### Connect Jenkins to Kubernetes via the Kubernetes CLI
1. To connect Jenkins to Kubernetes, you need to install a few plugins. Go to **Manage Jenkins > Manage Plugins**.
* Kubernetes plugin
* Kubernetes CLI Plugin
![Install Kubernetes plugin](https://blog.markkulab.net/content/markku/posts/jenkins-deploy-kubernetes-with-docker-for-windows/images/install-kubernetes-plugin.png)
2. [Set up cloud](http://localhost:8080/configureClouds/)
![Set up cloud](https://blog.markkulab.net/content/markku/posts/jenkins-deploy-kubernetes-with-docker-for-windows/images/set-cloud.png)
3. Set Disable https certificate check => true
![Disable HTTPS certificate check](https://blog.markkulab.net/content/markku/posts/jenkins-deploy-kubernetes-with-docker-for-windows/images/disable-http-certificate-check.png)
4. Kubernetes URL => kubectl cluster-info
https://host.docker.internal:6443
5. Jenkins URL
Jenkins URL:http://host.docker.internal:8080/
Jenkins tunnel:host.docker.internal:50000
6. Credentials =>
![Add public key to Jenkins](https://blog.markkulab.net/content/markku/posts/jenkins-deploy-kubernetes-with-docker-for-windows/images/add-public-key-to-jenkins.png)
7. Copy dashboard token to here
![Copy dashboard token to here](https://blog.markkulab.net/content/markku/posts/jenkins-deploy-kubernetes-with-docker-for-windows/images/copy-dashboard-token-to-here.png)

### Write the Jenkins Pipeline
```
properties([pipelineTriggers([githubPush()])])
pipeline {
    agent any 

    environment {
        tag = ':latest'
        imageShortName = 'de-next-ap'
        imageName = "${imageShortName}${tag}"
        containerName = "${imageShortName}-1"
        containerUrl = "192.168.50.49:2376"
        dockerfile = "./Dockerfile"        
        registry = "192.168.50.49:5000/next-ec"				
		
    }   
   
    stages {
        stage("GitHub Pull") {
             steps {
                git branch: 'main', 
                credentialsId: '946a703f-dff7-4138-84b2-0aba700dedca', 
                url:  'git@github.com:markku636/ec.git/'
            }
            
        }
		
        stage("Building Docker Image") {
			steps {
				script {
					dockerImage = docker.build "$registry:latest"
				}
			}
		}
		
		stage("Deploying to Registry Server") {
			steps {
				script {
					docker.withRegistry("http://192.168.50.49:5000", "") {
						dockerImage.push()
					}
				}
			}
		}
		
		stage("Cleaning Up") {
			steps {
				sleep(time: 3, unit: "SECONDS")

				sh "docker rmi --force $registry:latest"
			}
		}
			
        stage("Deply") {
             steps {
                    withKubeConfig([credentialsId: 'k8s-secret', serverUrl: 'https://host.docker.internal:6443']) {                     
                     sh 'kubectl apply -f ./next-js-deployment.yaml'
                    }
                
             }
        }    			        
    }
}
```

## Create the Kubernetes YAML Deployment Config File (next-js-deployment.yaml) in the Github next-ec Project
```
apiVersion: v1
kind: Deployment
metadata:
  name: nextjs-deployment
  labels:
    app: nextjs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nextjs
  template:
    metadata:
      labels:
        app: nextjs
    spec:
      containers:
      - name: nextjs
        image: 192.168.50.49:5000/next-ec:latest
        ports:
        - containerPort: 80
        resources:
          limits:
            memory: "128Mi"
            cpu: "500m"

---

apiVersion: v1
kind: Service
metadata:
  name: nextjs-service
spec:
  type: NodePort
  selector:
    app: nextjs
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30099

```

At this point, running the Jenkins build should succeed.
![Jenkins execution result](https://blog.markkulab.net/content/markku/posts/jenkins-deploy-kubernetes-with-docker-for-windows/images/final.png)

## Conclusion
K8s features and configuration are quite complex. The setup alone took a significant amount of time, and many details still require further experimentation and testing.

## Other Issues Encountered
### 1. "no matcher for kind 'Deploy' in version 'v1'" issue
I had to change the `apiVersion` in the YAML file a few times. Make sure to write your YAML deployment file according to the latest [official documentation](https://kubernetes.io/docs/concepts/services-networking/service/#type-nodeport).
### 2. kubectl: command not found
[You need to install kubectl in the Jenkins container](https://blog.markkulab.net/jenkins-deploy-kubernetes-with-docker-for-windows/#%E5%9C%A8jenkins-%E5%AE%B9%E5%99%A8%E4%B8%AD%E4%B8%AD%E5%AE%89%E8%A3%9D-kubectl).



## References
* [Learning DevOps from Scratch and Deploying CI/CD to a Java Project](https://ithelp.ithome.com.tw/articles/10339029)
* [Delivering Microservices to Kubernetes via Jenkins](https://blog.csdn.net/m0_53758775/article/details/121157016?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170578082016800186589323%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fvipall.%2522%257D&request_id=170578082016800186589323&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~vipall~first_rank_ecpm_v1~rank_v31_ecpm-3-121157016-null-null&utm_term=windows%20%E5%AE%89%E8%A3%85kubernetes%20jenkins&spm=1018.2226.3001.4187)
* [Installing Jenkins and other software on Windows with Docker Desktop and K8s](https://blog.csdn.net/qq_40250122/article/details/120966650?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_utm_term~default-1-120966650-blog-121157016.235^v40^pc_relevant_anti_vip_base&spm=1001.2101.3001.4242.1&utm_relevant_index=4)
* [Jenkins shell script error: bash: kubectl: command not found](https://blog.csdn.net/m0_45806184/article/details/128190069)

---

## About this article and its author

Originally published on [Mark Ku's Tech Notes](https://blog.markkulab.net/en/post/jenkins-deploy-kubernetes-with-docker-for-windows)

License: [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — when reusing or quoting, credit the author and link back to the original

### About the author

**[Mark Ku](https://blog.markkulab.net/en/author/mark-ku)** — Software Solution Provider

- 10+ years senior software engineer, now an AI Builder
- Focused on large-platform architecture — North-American e-commerce, AI SaaS subscription billing
- Combining AI Agents and automation to build evolvable product foundations

### Free tools built by the author

All of these are free to use:

- [Free PDF Sign Tool](https://blog.markkulab.net/en/tools/pdf-sign): Online PDF sign tool — draw, type, or upload a signature, then drag, resize, and download. Everything runs in your browser; nothing is uploaded.
- [VS Code Refactory](https://blog.markkulab.net/en/tools/refactory): Refactory is a VS Code refactoring extension: 34 actions plus a 37-rule code-smell inspection layer with a Code Health dashboard, across 18 languages, backed by 534 tests. It learns your repo's conventions: where interfaces live, where DI is registered, whether 'use client' belongs. It ranks files by git churn × complexity so you know what to fix first, and hands any smell to the Claude Code already on your machine. Free to use, and your source never leaves your computer.
- [DB-Kit Database Manager](https://blog.markkulab.net/en/tools/db-kit): DB-Kit is a lightweight, cross-platform database manager built with Tauri + Rust + React. Manage MySQL, MariaDB, PostgreSQL, SQL Server, Oracle, SQLite, MongoDB, Redis, Kafka, Elasticsearch and RabbitMQ from one consistent interface: passwords encrypted in the OS keychain, SSH tunnels, full CRUD, a visual query builder, stacked multi-statement result sets, cross-connection data transfer and compare/sync, Excel / CSV import & export, visualized execution plans, ER diagrams, scheduled backups, SQL stress testing with p50–p99 latency percentiles, a 15-rule SQL review engine, Kafka message browsing with monitoring & alerts, a bilingual UI (Traditional Chinese / English), a built-in AI assistant (natural-language SQL, AI review and tuning advice) and the dbk CLI. Free and open source (MIT), with installers for Windows, macOS and Linux.
- [VS Code Super Mermaid](https://blog.markkulab.net/en/tools/super-mermaid): Super Mermaid is a VS Code extension for beautiful Mermaid diagrams out of the box: auto-colored live preview, mouse pan & zoom, high-res PNG / SVG export, 21 templates and multiple themes. Free and open source (MIT).
- [React Super Mermaid](https://blog.markkulab.net/en/tools/react-super-mermaid): react-super-mermaid is an open-source React component library: render beautiful Mermaid diagrams with a single <MermaidViewer>, with built-in colorful / sketch themes, pan & zoom, in-diagram search, and high-res SVG / PNG export. Lightweight, SSR-safe, fully typed. Free and open source (MIT).
- [Jira / Confluence Super Mermaid](https://blog.markkulab.net/en/tools/jira-super-mermaid): An Atlassian Forge app: write Mermaid syntax directly inside a Jira issue or a Confluence page and get flowcharts, sequence diagrams, state machines and Gantt charts. 11 diagram types, SVG / PNG export, light and dark themes, full CJK support. Runs on Atlassian: your diagrams live in your own site and the app calls no third-party service. Free, coming soon to the Atlassian Marketplace.
- [Mermaid Live Preview](https://blog.markkulab.net/en/tools/mermaid-preview): Write Mermaid in your browser, see it render instantly, and share the whole diagram as a single link. No sign-up, nothing uploaded to a server, and mermaid.live share links work as-is.
- [React Intl Phone Number](https://blog.markkulab.net/en/tools/react-intl-phone-number): react-intl-phone-number is an open-source React component: framework-agnostic and antd-free, with E.164 in/out, a searchable flag / country-code dropdown, configurable validation levels (strict / mobile-strict / loose), themeable CSS, and i18n — phone logic powered by google-libphonenumber. Lightweight and fully typed. Free and open source (MIT).
- [Uptime Kuma Cluster](https://blog.markkulab.net/en/tools/uptime-kuma-cluster): Turn single-node Uptime Kuma into a highly available cluster: OpenResty + Lua smart load balancing, shared MariaDB state, health checks and automatic failover, plus cluster-management REST APIs. One Docker Compose command to start. Free and open source (MIT).
- [Special Education](https://blog.markkulab.net/en/education): Learning materials crafted for special education students

### Daily podcasts

- [Mark's Tech Insights — Daily AI News](https://blog.markkulab.net/en/category/tech-news): Daily curated AI and tech trends. Catch the latest developments via audio summaries — covering AI applications, software architecture, DevOps, and engineering practice. — RSS: https://blog.markkulab.net/feed.xml
- [AI股市蝦聊](https://blog.markkulab.net/en/category/ai-stock-chat): Every trading day, an AI-analyzed take on the Taiwan stock market, delivered as a two-host conversation covering the session and the next-day outlook. — RSS: https://blog.markkulab.net/ai-stock-chat/feed.xml
- [開源好物週報](https://blog.markkulab.net/en/category/open-source-weekly): A weekly two-host pick of free open-source tools surfaced from real Hacker News, GitHub, and Reddit buzz — what pain they solve and the fastest way to get started. — RSS: https://blog.markkulab.net/open-source-weekly/feed.xml

### Newsletter

[Subscribe to the newsletter](https://blog.markkulab.net/en/subscribe) — Be the first to know about new posts. No spam, unsubscribe anytime.
