Skip to content

Deploy on Kubernetes

Example manifests for running Recipery in a Kubernetes cluster.

Updated View as Markdown

There’s no packaged Helm chart yet, but Recipery is a stateless container with no database, so it drops into a cluster with a plain Deployment and Service. The manifests below are a starting point — adapt names, namespace, and resource limits to your cluster.

Create a Secret

Holds your S3 or R2 access key and secret key.

Apply the Deployment and Service

kubectl apply -f the manifests below — the image needs no volume when using object storage.

Expose the Service

Point your cluster’s Ingress, Gateway, or LoadBalancer at it.

Secret

Keep storage credentials out of the Deployment spec:

recipery-secret.yamlyaml
apiVersion: v1
kind: Secret
metadata:
  name: recipery-storage
type: Opaque
stringData:
  S3_ACCESS_KEY: <YOUR_ACCESS_KEY>
  S3_SECRET_KEY: <YOUR_SECRET_KEY>

Deployment

recipery-deployment.yamlyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: recipery
spec:
  replicas: 1
  selector:
    matchLabels:
      app: recipery
  template:
    metadata:
      labels:
        app: recipery
    spec:
      containers:
        - name: recipery
          image: ghcr.io/recipery-dev/recipery:latest
          ports:
            - containerPort: 3000
          env:
            - name: STORAGE_DRIVER
              value: s3
            - name: S3_BUCKET
              value: recipery
            - name: S3_ENDPOINT
              value: https://<ACCOUNT_ID>.r2.cloudflarestorage.com
            - name: S3_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: recipery-storage
                  key: S3_ACCESS_KEY
            - name: S3_SECRET_KEY
              valueFrom:
                secretKeyRef:
                  name: recipery-storage
                  key: S3_SECRET_KEY
          readinessProbe:
            httpGet:
              path: /api/health
              port: 3000
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /api/health
              port: 3000
            initialDelaySeconds: 10
            periodSeconds: 30

/api/health checks connectivity to the configured storage backend and returns 200 when it’s reachable, 503 otherwise — it’s what both probes above use. See Storage for the full set of env vars per backend (the example uses R2 over the S3-compatible driver; swap in your own bucket’s values, or S3’s for AWS/MinIO/B2).

Service

recipery-service.yamlyaml
apiVersion: v1
kind: Service
metadata:
  name: recipery
spec:
  selector:
    app: recipery
  ports:
    - port: 80
      targetPort: 3000

Front it with whatever your cluster already uses for ingress (an Ingress resource, a Gateway, or a cloud LoadBalancer) — nothing about Recipery requires a specific one.

Apply

kubectl apply -f recipery-secret.yaml -f recipery-deployment.yaml -f recipery-service.yaml

Scaling to multiple replicas

With an S3 or R2 backend, Recipery is stateless across pods — set replicas above 1 freely; every pod reads and writes the same bucket.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close