Skip to content

Deploy on Kubernetes

Example manifests for running Bookhoarder in a Kubernetes cluster.

Updated View as Markdown

There’s no packaged Helm chart yet, but Bookhoarder 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:

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

Deployment

bookhoard-deployment.yamlyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: bookhoard
spec:
  replicas: 1
  selector:
    matchLabels:
      app: bookhoard
  template:
    metadata:
      labels:
        app: bookhoard
    spec:
      containers:
        - name: bookhoard
          image: ghcr.io/bookhoard/bookhoarder:latest
          ports:
            - containerPort: 3000
          env:
            - name: STORAGE_DRIVER
              value: s3
            - name: S3_BUCKET
              value: bookhoard
            - name: S3_ENDPOINT
              value: https://<ACCOUNT_ID>.r2.cloudflarestorage.com
            - name: S3_ACCESS_KEY
              valueFrom:
                secretKeyRef:
                  name: bookhoard-storage
                  key: S3_ACCESS_KEY
            - name: S3_SECRET_KEY
              valueFrom:
                secretKeyRef:
                  name: bookhoard-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

bookhoard-service.yamlyaml
apiVersion: v1
kind: Service
metadata:
  name: bookhoard
spec:
  selector:
    app: bookhoard
  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 Bookhoarder requires a specific one.

Apply

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

Scaling to multiple replicas

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

Navigation

Type to search…

↑↓ navigate↵ selectEsc close