agentsclimarketplace

K8s nextjs deploy

Skill andreab67/agent-skills/k8s-nextjs-deploy

Personal collection of agent skills for use with Claude Code and other LLM agents.

Install
npx -y skills add andreab67/agent-skills --skill k8s-nextjs-deploy

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Kubernetes deployment patterns for Next.js applications — Deployment/Service/Ingress manifests, Harbor image pull secrets, Traefik ingress with cert-manager TLS, Linkerd service mesh, multi-app namespaces, and K8s secret rotation. Use this skill whenever the user mentions deploying a Next.js app to Kubernetes, ImagePullBackOff, CrashLoopBackOff, Harbor pull secret, Traefik ingress, cert-manager, a missing secretKeyRef, or namespace recovery — even if they just say "the pod won't start" or "deploy this to k8s" without further detail.

SKILL.md

8.4 KB, as published. Nobody here has run it

k8s-nextjs-deploy

Kubernetes deployment patterns for containerized Next.js apps: Harbor registry auth, Traefik ingress with automatic TLS, Linkerd sidecar injection, and multi-app namespace management.

When to use

  • Deploying a new Next.js app (Deployment + Service + Ingress rule)
  • Diagnosing ImagePullBackOff, ErrImagePull, CreateContainerConfigError
  • Rotating Harbor pull secret credentials
  • Adding a subdomain to an existing Traefik ingress with cert-manager
  • Applying K8s manifests after a namespace was deleted
  • Troubleshooting pods stuck because of missing secretKeyRef secrets

Do NOT use for:

  • Non-Kubernetes deployments (Docker Compose, bare-metal, Vercel)
  • Database deployments (stateful sets require separate skill)

Deploying a new Next.js app — step by step

  1. Create the namespace (if it doesn't exist yet): kubectl create namespace <ns>. Success: kubectl get ns <ns> shows Active.
  2. Create the Harbor pull secret using the single-quoted docker-registry command below. Success: kubectl -n <ns> get secret harbor-pull-secret exists and describe shows type kubernetes.io/dockerconfigjson.
  3. Apply the Deployment manifest (with imagePullSecrets, resource requests/limits, and readiness/liveness probes set). Success: kubectl -n <ns> get pods shows the pod Running and 1/1 Ready.
  4. Apply the Service. Success: kubectl -n <ns> get svc <name> shows a ClusterIP with the expected port mapping.
  5. Apply/extend the Ingress, adding the new host to both tls.hosts and rules. Success: kubectl -n <ns> get ingress lists the host, and kubectl -n <ns> get certificate reaches READY: True within a couple of minutes as cert-manager issues the cert.
  6. Verify end-to-end: curl -I https://<host> returns 200/3xx with a trusted TLS chain (no cert warning). If it doesn't, work through Common failure diagnosis below.

Deployment manifest

apiVersion: apps/v1
kind: Deployment
metadata:
  name: cloudreviewer-web
  namespace: cloudreviewer
spec:
  replicas: 1
  selector:
    matchLabels:
      app: cloudreviewer-web
  template:
    metadata:
      labels:
        app: cloudreviewer-web
    spec:
      imagePullSecrets:
        - name: harbor-pull-secret
      containers:
        - name: web
          image: harbor.example.com/project/app:latest
          imagePullPolicy: Always
          securityContext:
            allowPrivilegeEscalation: false
          ports:
            - containerPort: 3000
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          env:
            - name: HOSTNAME
              value: "0.0.0.0"
            - name: NODE_ENV
              value: "production"
            - name: NEXT_TELEMETRY_DISABLED
              value: "1"
            - name: OTEL_SERVICE_NAME
              value: "my-app"
            - name: OTEL_EXPORTER_OTLP_ENDPOINT
              value: "http://tempo.tempo.svc.cluster.local:4318"
          readinessProbe:
            httpGet:
              path: /
              port: 3000
          livenessProbe:
            httpGet:
              path: /
              port: 3000

Service

apiVersion: v1
kind: Service
metadata:
  name: cloudreviewer-web
  namespace: cloudreviewer
spec:
  selector:
    app: cloudreviewer-web
  ports:
    - name: http
      port: 80
      targetPort: 3000

Ingress (Traefik + cert-manager)

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: cloudreviewer
  namespace: cloudreviewer
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
  ingressClassName: traefik
  tls:
    - hosts:
        - www.example.com
        - buy.example.com
        - kb.example.com
      secretName: cloudreviewer-tls
  rules:
    - host: www.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: cloudreviewer-web
                port:
                  number: 80

Add new subdomains to both tls.hosts and rules.

Harbor pull secret

kubectl -n <namespace> create secret docker-registry harbor-pull-secret \
  --docker-server=harbor.example.com \
  --docker-username='robot$project+robot' \
  --docker-password='TOKEN'

Single quotes are mandatory — robot account usernames contain $ which the shell would expand. Never use double quotes.

Rotating credentials

kubectl -n <namespace> delete secret harbor-pull-secret
kubectl -n <namespace> create secret docker-registry harbor-pull-secret \
  --docker-server=harbor.example.com \
  --docker-username='robot$project+robot' \
  --docker-password='NEW_TOKEN'
kubectl -n <namespace> rollout restart deployment/<name>

Pods scheduled before the secret existed cache the auth failure. Always rollout restart after recreating the secret.

Common failure diagnosis

ImagePullBackOff / ErrImagePull

kubectl -n <ns> describe pod <pod> | grep -A 10 "Events:"
Error messageCauseFix
401 UnauthorizedStale or missing pull secretRotate pull secret → rollout restart
repository does not existWrong image name or projectCheck Harbor project name matches image path
no basic auth credentialsPod scheduled before secret createdrollout restart after creating secret

CreateContainerConfigError

Pod image pulled successfully but container won't start — usually a missing secretKeyRef:

kubectl -n <ns> describe pod <pod> | grep -i "secret\|error" | head -20

The referenced secret (e.g., cloudreviewer-buy-secrets) was lost when the namespace was deleted. Recreate it:

kubectl -n <ns> create secret generic my-app-secrets \
  --from-literal=key1=value1 \
  --from-literal=key2=value2

Namespace deleted — full apply order

kubectl apply -f k8s/namespace.yaml
kubectl apply -f k8s/web-deployment.yaml -f k8s/web-service.yaml
kubectl apply -f k8s/buy-deployment.yaml -f k8s/buy-service.yaml
kubectl apply -f k8s/kb-deployment.yaml  -f k8s/kb-service.yaml
kubectl apply -f k8s/ingress.yaml
# Then recreate pull secret and app secrets

Environment variables for Next.js

Required env vars for a standalone Next.js container:

VariableValuePurpose
HOSTNAME0.0.0.0Bind to all interfaces
NODE_ENVproductionEnables prod optimisations
NEXT_TELEMETRY_DISABLED1Disable Next.js telemetry
OTEL_SERVICE_NAMEapp nameOTel trace attribution
OTEL_EXPORTER_OTLP_ENDPOINTTempo/Grafana URLTrace export
NEXT_PUBLIC_SITE_URLhttps://www.example.comMetadata base URL

Multiple kubectl contexts

When managing multiple clusters:

kubectl config get-contexts          # list
kubectl config use-context sr-k8s   # switch
kubectl config current-context      # verify

Always verify context before applying manifests or rotating secrets.

Example prompts

  • "Our pods are stuck in ImagePullBackOff. How do I diagnose and fix this?"
  • "I rotated the Harbor robot account token. How do I update the pull secret without downtime?"
  • "Add subdomain kb.example.com to the existing Traefik ingress."
  • "The namespace got accidentally deleted. Walk me through restoring everything in order."
  • "A pod is in CreateContainerConfigError. What does that mean and how do I fix it?"
  • "Show me a production-ready Next.js Deployment manifest with resource limits and probes."

Related skills

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.