> For the complete documentation index, see [llms.txt](https://docs.slingdata.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.slingdata.io/sling-platform/platform/self-hosting/kubernetes.md).

# Kubernetes

Deploy Sling Platform and agents on Kubernetes

This page has a full Kubernetes manifest for the platform and a single agent. For agent replicas that the platform provisions and scales, see [High-Availability Agents](/sling-platform/platform/self-hosting/shared-mode.md).

<details>

<summary>sling-platform.yaml (Kubernetes manifest)</summary>

```yaml
# Namespace
apiVersion: v1
kind: Namespace
metadata:
  name: sling-platform
---
# ConfigMap for environment variables
apiVersion: v1
kind: ConfigMap
metadata:
  name: sling-platform-config
  namespace: sling-platform
data:
  SLING_PLATFORM_HOST: "http://external.ip:8080"  # Update with your actual external IP/domain
---
# Secret for sensitive environment variables
apiVersion: v1
kind: Secret
metadata:
  name: sling-platform-secrets
  namespace: sling-platform
type: Opaque
stringData:
  SLING_PLATFORM_LICENSE: "your-license-key"
  SLING_PLATFORM_ENCRYPTION_KEY: "your-32-char-encryption-key"
  SLING_PLATFORM_ADMIN_CREDENTIALS: '{"email":"admin@example.com","password":"secure-password"}'
  SLING_PLATFORM_SMTP_CREDENTIALS: '{"host":"smtp.gmail.com","port":587,"user":"your-email","password":"your-password","from":"Sling <noreply@yourdomain.com>"}'
  # SLING_PLATFORM_SSO: '{"provider":"microsoft","tenant_id":"...","client_id":"...","client_secret":"..."}'
  # SLING_PLATFORM_MFA: "true"
  SLING_AGENT_KEY: "your-agent-key"
---
# PersistentVolumeClaim for platform data
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sling-platform-data
  namespace: sling-platform
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 25Gi
  # storageClassName: your-storage-class  # Uncomment and specify if needed
---
# PersistentVolumeClaim for agent data
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: sling-agent-data
  namespace: sling-platform
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 5Gi
  # storageClassName: your-storage-class  # Uncomment and specify if needed
---
# Sling Platform Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sling-platform
  namespace: sling-platform
  labels:
    app: sling-platform
spec:
  replicas: 1
  # Recreate: embedded postgres must never run in 2 pods on the same volume
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: sling-platform
  template:
    metadata:
      labels:
        app: sling-platform
    spec:
      # time for the embedded postgres to shut down cleanly
      terminationGracePeriodSeconds: 60
      securityContext:
        fsGroup: 999
        runAsUser: 999
      containers:
      - name: sling-platform
        image: slingdata/sling-platform:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 7878
          name: http
          protocol: TCP
        - containerPort: 4443
          name: nats
          protocol: TCP
        - containerPort: 9876
          name: postgres
          protocol: TCP
        env:
        - name: SLING_PLATFORM_HOST
          valueFrom:
            configMapKeyRef:
              name: sling-platform-config
              key: SLING_PLATFORM_HOST
        - name: SLING_PLATFORM_LICENSE
          valueFrom:
            secretKeyRef:
              name: sling-platform-secrets
              key: SLING_PLATFORM_LICENSE
        - name: SLING_PLATFORM_ENCRYPTION_KEY
          valueFrom:
            secretKeyRef:
              name: sling-platform-secrets
              key: SLING_PLATFORM_ENCRYPTION_KEY
        - name: SLING_PLATFORM_ADMIN_CREDENTIALS
          valueFrom:
            secretKeyRef:
              name: sling-platform-secrets
              key: SLING_PLATFORM_ADMIN_CREDENTIALS
        - name: SLING_PLATFORM_SMTP_CREDENTIALS
          valueFrom:
            secretKeyRef:
              name: sling-platform-secrets
              key: SLING_PLATFORM_SMTP_CREDENTIALS
              optional: true
        - name: SLING_PLATFORM_SSO
          valueFrom:
            secretKeyRef:
              name: sling-platform-secrets
              key: SLING_PLATFORM_SSO
              optional: true
        - name: SLING_PLATFORM_MFA
          valueFrom:
            secretKeyRef:
              name: sling-platform-secrets
              key: SLING_PLATFORM_MFA
              optional: true
        
        startupProbe:
          httpGet:
            path: /api/health
            port: 7878
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 30
        readinessProbe:
          httpGet:
            path: /api/health
            port: 7878
          initialDelaySeconds: 10
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        livenessProbe:
          httpGet:
            path: /api/health
            port: 7878
          periodSeconds: 20
          timeoutSeconds: 5
          failureThreshold: 3
        volumeMounts:
        - name: platform-data
          mountPath: /home/sling
        resources:
          requests:
            memory: "512Mi"
            cpu: "250m"
          limits:
            memory: "4Gi"
            cpu: "2"
      volumes:
      - name: platform-data
        persistentVolumeClaim:
          claimName: sling-platform-data
      restartPolicy: Always
---
# Sling Platform Service
apiVersion: v1
kind: Service
metadata:
  name: sling-platform
  namespace: sling-platform
  labels:
    app: sling-platform
spec:
  type: ClusterIP
  ports:
  - port: 7878
    targetPort: 7878
    protocol: TCP
    name: http
  - port: 4443
    targetPort: 4443
    protocol: TCP
    name: nats
  - port: 9876
    targetPort: 9876
    protocol: TCP
    name: postgres
  selector:
    app: sling-platform
---
# Sling Agent Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sling-agent
  namespace: sling-platform
  labels:
    app: sling-agent
spec:
  # A single-mode agent requires a unique SLING_AGENT_KEY, so this deployment must have replicas: 1
  # To deploy additional single-mode agents, duplicate this deployment with a new name and a different SLING_AGENT_KEY
  # Shared-mode agents CAN run replicas > 1 with one key — see "High-Availability Agents" below
  replicas: 1  
  selector:
    matchLabels:
      app: sling-agent
  template:
    metadata:
      labels:
        app: sling-agent
    spec:
      containers:
      - name: sling-agent
        image: slingdata/sling:latest
        imagePullPolicy: Always
        args: ["agent", "run"]
        env:
        - name: SLING_PLATFORM_HOST
          value: "http://sling-platform:7878"
        - name: SLING_AGENT_KEY
          valueFrom:
            secretKeyRef:
              name: sling-platform-secrets
              key: SLING_AGENT_KEY
        volumeMounts:
        - name: agent-data
          mountPath: /home/sling
        resources:
          requests:
            memory: "256Mi"
            cpu: "100m"
          limits:
            memory: "8Gi"
            cpu: "4"
      volumes:
      - name: agent-data
        persistentVolumeClaim:
          claimName: sling-agent-data
      restartPolicy: Always
```

</details>

{% hint style="warning" %}
**If you build the Secret from an env file** (`kubectl create secret generic ... --from-env-file=.env`), do not put quotes around the JSON values. Docker Compose removes the quotes, but `--from-env-file` keeps them, and the platform then stops with a JSON parse error such as `ReadMapCB: expect { or n, but found '`. Write `SLING_PLATFORM_ADMIN_CREDENTIALS={"email":"...","password":"..."}` with no quotes around it. Also make sure the file ends with a new line, or the last variable merges with the next one you add.
{% endhint %}

{% hint style="danger" %}
**Keep `strategy: Recreate` on the platform Deployment.** The platform keeps its data in an embedded PostgreSQL database on the `sling-platform-data` volume. With the default `RollingUpdate` strategy, Kubernetes starts the new pod before it stops the old pod. Then two PostgreSQL servers write to the same data directory, and the database can become corrupt. The platform then does not start, and its logs show `PANIC: could not locate a valid checkpoint record`. `Recreate` stops the old pod first. Also keep `terminationGracePeriodSeconds: 60`, so that PostgreSQL has time to stop cleanly. If you use an external database (`SLING_PLATFORM_POSTGRES_URL`), these settings are not necessary.
{% endhint %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.slingdata.io/sling-platform/platform/self-hosting/kubernetes.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
