Deploying a Turborepo into Kubernetes
Thinking of Heroku or Render? This isn't that blog. This guide is for developers and DevOps engineers looking to deploy their Turborepo into custom Kubernetes environments like k8s or k3s.

So, you've built a TurboRepo with Next.js for the frontend and NestJS for the backend, and now you're wondering:
"How the heck do I get this thing running on Kubernetes?"
Don’t worry you’re not alone.
Deploying microservices (or even monorepos) into Kubernetes can feel intimidating when you're just starting. Between YAML files, Docker images, namespaces, pods, services… it's easy to get lost.
In this blog, we're going to walk through exactly how to deploy your TurboRepo to Kubernetes, step by step without the fluff, without the overwhelm.
We'll cover everything you need - creating Docker images, defining Kubernetes deployments, setting up services, and applying them all to your cluster. If you're serious about taking control of your infrastructure or passionate about custom server deployment, this guide is for you.
🛠️Prerequisites
✔️A running Kubernetes cluster (k8s) or a lightweight alternative like k3s
✔️Docker images built and pushed for frontend and backend:
apps/web
(Next.js frontend)apps/api
(NestJS backend)
If not already build, refer to: How to deploy a Turborepo (Next.js + NestJS) on Any Server using Docker
📂TurboRepo Structure
apps/
web/ ← Next.js 15.2.1 (Frontend)
api/ ← NestJS 11.1.2 (Backend)
packages/ ← Shared libraries
Step 1: Create a Namespace for your app
Think of a namespace like a folder where your application and it's related stuffs lives. Let create one.
File: namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: asynx-turborepo-tutorial
labels:
name: asynx-turborepo-tutorial
Step 2: Create Deployment for web
(frontend)
File: web-deployment.yaml
apiVersion: apps/v1
#Replace your image URL here
kind: Deployment
metadata:
name: web-deployment
namespace: asynx-turborepo-tutorial
spec:
replicas: 2
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: 192.168.0.103:5000/asynx-web-stage:latest
#Adjust Minimum guaranteed memory for your web deployment
ports:
- containerPort: 3000
resources:
requests:
memory: "512Mi"
#Adjust Minimum guaranteed CPU for your web deployment
cpu: "500m"
#Adjust maximum memory that can be availed for your web deployment
limits:
memory: "1Gi"
#Adjust maximum CPU that can be availed for your web deployment
cpu: "1000m"
Tested and working - feel free to copy paste, but always strive to understand the concept.
Step 3: Create deployment for api
(Backend)
File: api-deployment.yaml
apiVersion: apps/v1
#Replace your image URL here
kind: Deployment
metadata:
name: api-deployment
namespace: asynx-turborepo-tutorial
spec:
replicas: 2
selector:
matchLabels:
app: api
template:
metadata:
labels:
app: api
spec:
containers:
- name: api
image: 192.168.0.103:5000/asynx-api-stage:latest
#Adjust Minimum guaranteed memory for your api deployment
ports:
- containerPort: 3001
resources:
requests:
memory: "512Mi"
#Adjust Minimum guaranteed CPU for your api deployment
cpu: "500m"
#Adjust maximum memory that can be availed for your api deployment
limits:
memory: "1Gi"
#Adjust maximum CPU that can be availed for your api deployment
cpu: "1000m"
Tested and working - feel free to copy paste, but always strive to understand the concept.
Step 4: Create Services to Expose Deployment
Kubernetes deployments are like houses without doors. Let's give them entrances.
Web service (web-service.yaml
)
apiVersion: v1
kind: Service
metadata:
name: web-service
namespace: asynx-turborepo-tutorial
spec:
selector:
app: web
ports:
- port: 3000
targetPort: 3000
nodePort: 30019
type: NodePort
API service (api-service.yaml
)
apiVersion: v1
kind: Service
metadata:
name: api-service
namespace: asynx-turborepo-tutorial
spec:
selector:
app: api
ports:
- port: 3001
targetPort: 3001
nodePort: 30020
type: NodePort
💡 Tip: You can change nodePort
values if you want different external ports, just make sure they’re within the 30000-32767 range.
Step 5: Apply Everything
kubectl apply -f namespace.yaml
kubectl apply -f web-deployment.yaml
kubectl apply -f api-deployment.yaml
kubectl apply -f web-service.yaml
kubectl apply -f api-service.yaml
Step 6: Visit your App
If everything went well, go to:
- Frontend (Next.js):
http://<your-server-ip>:30019
- Backend (NestJS):
http://<your-server-ip>:30020
And just like that your TurboRepo monorepo is running in a kubernetes cluster.
✨Bonus Ideas
if you're feeling confident, here's what you could do next:
- Set up an Ingress controller for cleaner URLs like
web.myapp.local
andapi.myapp.local
- Add ConfigMaps and Secrets for environment variables
- Hook it up with CI/CD (GitHub Actions +
kubectl
FTW)
Finally
Let's be real, Kubernetes is not easy. It's powerful and complex, but it comes with a learning curve that feel like a mountain at first. You'll spend hours debugging YAML, wondering why the deployment is not starting pods. figuring why the app is not reachable. That's normal.
So if you’re reading this and thinking “this is too much” don’t give up. Take breaks. Come back. Tinker. Try again.
This guide is intentionally basic and beginner-friendly, designed to get your TurboRepo running on Kubernetes with just the essentials
Tags
#how to deploy nextjs nestjs on kubernetes
#turborepo deployment kubernetes
#next.js 15 kubernetes deployment
#nestjs kubernetes example
#deploy turborepo with docker and kubernetes
#k3s deploy fullstack app
#create deployment and service kubernetes