Back to Guides

Deploy AnythingMCP on Google Kubernetes Engine (GKE)

Deploy AnythingMCP on GKE with Kubernetes manifests, Ingress for HTTPS, and Cloud SQL for PostgreSQL. Enterprise-grade scalable deployment.

Overview

This is the most advanced deployment option, intended for teams that need enterprise-grade scalability and managed infrastructure. You will create Kubernetes manifests and use Cloud SQL or an in-cluster PostgreSQL.

Prerequisites

  • A GCP account with billing enabled
  • gcloud and kubectl installed
  • Docker installed locally
  • A domain name
gcloud services enable container.googleapis.com \
  artifactregistry.googleapis.com \
  sqladmin.googleapis.com

Create a GKE Cluster

gcloud container clusters create anythingmcp-cluster \
  --region us-central1 \
  --num-nodes 2 \
  --machine-type e2-standard-2 \
  --enable-autoscaling --min-nodes 1 --max-nodes 5

gcloud container clusters get-credentials anythingmcp-cluster \
  --region us-central1

Build and Push the Image

gcloud artifacts repositories create anythingmcp \
  --repository-format docker \
  --location us-central1

gcloud auth configure-docker us-central1-docker.pkg.dev

git clone https://github.com/HelpCode-ai/anythingmcp.git
cd anythingmcp

docker build -t us-central1-docker.pkg.dev/YOUR_PROJECT_ID/anythingmcp/app:latest .
docker push us-central1-docker.pkg.dev/YOUR_PROJECT_ID/anythingmcp/app:latest

Create Kubernetes Secrets

kubectl create secret generic anythingmcp-secrets \
  --from-literal=JWT_SECRET=$(openssl rand -hex 32) \
  --from-literal=ENCRYPTION_KEY=$(openssl rand -hex 16) \
  --from-literal=NEXTAUTH_SECRET=$(openssl rand -hex 32) \
  --from-literal=POSTGRES_PASSWORD=$(openssl rand -hex 16)

Deploy PostgreSQL

Simple in-cluster StatefulSet (for production, consider Cloud SQL instead):

# postgres.yaml
apiVersion: v1
kind: Service
metadata:
  name: postgres
spec:
  clusterIP: None
  selector:
    app: postgres
  ports:
    - port: 5432
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: postgres
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
        - name: postgres
          image: postgres:17-alpine
          ports:
            - containerPort: 5432
          env:
            - name: POSTGRES_DB
              value: anythingmcp
            - name: POSTGRES_USER
              value: amcp
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: anythingmcp-secrets
                  key: POSTGRES_PASSWORD
          volumeMounts:
            - name: data
              mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
    - metadata:
        name: data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 10Gi
kubectl apply -f postgres.yaml

Deploy AnythingMCP

# anythingmcp.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: anythingmcp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: anythingmcp
  template:
    metadata:
      labels:
        app: anythingmcp
    spec:
      containers:
        - name: anythingmcp
          image: us-central1-docker.pkg.dev/YOUR_PROJECT_ID/anythingmcp/app:latest
          ports:
            - containerPort: 3000
            - containerPort: 4000
          env:
            - name: NODE_ENV
              value: production
            - name: PORT
              value: "4000"
            - name: MCP_AUTH_MODE
              value: oauth2
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: anythingmcp-secrets
                  key: POSTGRES_PASSWORD
            - name: DATABASE_URL
              value: postgresql://amcp:$(POSTGRES_PASSWORD)@postgres:5432/anythingmcp
            - name: JWT_SECRET
              valueFrom:
                secretKeyRef:
                  name: anythingmcp-secrets
                  key: JWT_SECRET
            - name: ENCRYPTION_KEY
              valueFrom:
                secretKeyRef:
                  name: anythingmcp-secrets
                  key: ENCRYPTION_KEY
            - name: NEXTAUTH_SECRET
              valueFrom:
                secretKeyRef:
                  name: anythingmcp-secrets
                  key: NEXTAUTH_SECRET
          readinessProbe:
            httpGet:
              path: /health
              port: 4000
            initialDelaySeconds: 10
            periodSeconds: 5
          livenessProbe:
            httpGet:
              path: /health
              port: 4000
            initialDelaySeconds: 30
            periodSeconds: 10
          resources:
            requests:
              cpu: 250m
              memory: 256Mi
            limits:
              cpu: "1"
              memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: anythingmcp
spec:
  selector:
    app: anythingmcp
  ports:
    - name: frontend
      port: 3000
      targetPort: 3000
    - name: backend
      port: 4000
      targetPort: 4000
  type: ClusterIP
kubectl apply -f anythingmcp.yaml

Expose with Ingress (HTTPS)

# ingress.yaml
apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
  name: anythingmcp-cert
spec:
  domains:
    - mcp.example.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: anythingmcp-ingress
  annotations:
    networking.gke.io/managed-certificates: anythingmcp-cert
    kubernetes.io/ingress.class: gce
spec:
  rules:
    - host: mcp.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: anythingmcp
                port:
                  number: 3000
kubectl apply -f ingress.yaml

# Get external IP (may take a few minutes)
kubectl get ingress anythingmcp-ingress

Point your domain A record to the external IP. The managed certificate provisions automatically once DNS propagates.

Verify & Next Steps

kubectl get pods
curl https://mcp.example.com/health

The first user to register becomes administrator.

Production recommendations:

  • Use Cloud SQL instead of the in-cluster StatefulSet for backups and HA
  • Enable Horizontal Pod Autoscaler: kubectl autoscale deployment anythingmcp --min=2 --max=10 --cpu-percent=70
  • Use Workload Identity for Cloud SQL access