Asynx Pvt Ltd logo
Deployment Guide

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.

Asynx Pvt. Ltd
Share:
Deploying a Turborepo into Kubernetes

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
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
#Replace your image URL here
ports:
- containerPort: 3000
resources:
requests:
memory: "512Mi"
#Adjust Minimum guaranteed memory for your web deployment
cpu: "500m"
#Adjust Minimum guaranteed CPU for your web deployment
limits:
memory: "1Gi"
#Adjust maximum memory that can be availed for your web deployment
cpu: "1000m"
#Adjust maximum CPU that can be availed for your web deployment

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
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
#Replace your image URL here
ports:
- containerPort: 3001
resources:
requests:
memory: "512Mi"
#Adjust Minimum guaranteed memory for your api deployment
cpu: "500m"
#Adjust Minimum guaranteed CPU for your api deployment
limits:
memory: "1Gi"
#Adjust maximum memory that can be availed for your api deployment
cpu: "1000m"
#Adjust maximum CPU that can be availed for your api deployment

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 and api.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

About the Author

Vijayaraghavan

Vijayaraghavan

Founder & Director - Asynx Pvt. Ltd.

[@portabletext/react] Unknown block type "undefined", specify a component for it in the `components.types` prop