Initial commit
This commit is contained in:
102
.claude/skills/pocketbase-best-practices/rules/deploy-scaling.md
Normal file
102
.claude/skills/pocketbase-best-practices/rules/deploy-scaling.md
Normal file
@@ -0,0 +1,102 @@
|
||||
---
|
||||
title: Tune OS and Runtime for PocketBase Scale
|
||||
impact: MEDIUM
|
||||
impactDescription: Prevents file descriptor exhaustion, OOM kills, and exposes secure config for production deployments
|
||||
tags: production, scaling, ulimit, gomemlimit, docker, encryption, deployment
|
||||
---
|
||||
|
||||
## Tune OS and Runtime for PocketBase Scale
|
||||
|
||||
Three low-effort OS/runtime knobs have outsized impact on production stability: open-file limits for realtime connections, Go memory limits for constrained hosts, and settings encryption for shared or externally-backed infrastructure. None of these are set automatically.
|
||||
|
||||
**Incorrect (default OS limits, no memory governor, plain-text settings):**
|
||||
|
||||
```bash
|
||||
# Start without raising the file descriptor limit
|
||||
/root/pb/pocketbase serve yourdomain.com
|
||||
# → "Too many open files" once concurrent realtime connections exceed ~1024
|
||||
|
||||
# Start in a container that has a 512 MB RAM cap without GOMEMLIMIT
|
||||
docker run -m 512m pocketbase serve ...
|
||||
# → OOM kill during large file upload because Go GC doesn't respect cgroup limits
|
||||
|
||||
# Store SMTP password and S3 secret as plain JSON in pb_data/data.db
|
||||
pocketbase serve # no --encryptionEnv
|
||||
# → Anyone who obtains the database backup can read all credentials
|
||||
```
|
||||
|
||||
**Correct:**
|
||||
|
||||
```bash
|
||||
# 1. Raise the open-file limit before starting (Linux/macOS)
|
||||
# Check current limit first:
|
||||
ulimit -a | grep "open files"
|
||||
# Temporarily raise to 4096 for the current session:
|
||||
ulimit -n 4096
|
||||
/root/pb/pocketbase serve yourdomain.com
|
||||
|
||||
# Or persist it via systemd (recommended for production):
|
||||
# /lib/systemd/system/pocketbase.service
|
||||
# [Service]
|
||||
# LimitNOFILE = 4096
|
||||
# ...
|
||||
|
||||
# 2. Cap Go's soft memory target on memory-constrained hosts
|
||||
# (instructs the GC to be more aggressive before the kernel OOM-kills the process)
|
||||
GOMEMLIMIT=512MiB /root/pb/pocketbase serve yourdomain.com
|
||||
|
||||
# 3. Encrypt application settings at rest
|
||||
# Generate a random 32-character key once:
|
||||
export PB_ENCRYPTION_KEY="z76NX9WWiB05UmQGxw367B6zM39T11fF"
|
||||
# Start with the env-var name (not the value) as the flag argument:
|
||||
pocketbase serve --encryptionEnv=PB_ENCRYPTION_KEY
|
||||
```
|
||||
|
||||
**Docker deployment pattern (v0.36.8):**
|
||||
|
||||
```dockerfile
|
||||
FROM alpine:latest
|
||||
ARG PB_VERSION=0.36.8
|
||||
|
||||
RUN apk add --no-cache unzip ca-certificates
|
||||
|
||||
ADD https://github.com/pocketbase/pocketbase/releases/download/v${PB_VERSION}/pocketbase_${PB_VERSION}_linux_amd64.zip /tmp/pb.zip
|
||||
RUN unzip /tmp/pb.zip -d /pb/
|
||||
|
||||
# Uncomment to bundle pre-written migrations or hooks:
|
||||
# COPY ./pb_migrations /pb/pb_migrations
|
||||
# COPY ./pb_hooks /pb/pb_hooks
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
# Mount a volume at /pb/pb_data to persist data across container restarts
|
||||
CMD ["/pb/pocketbase", "serve", "--http=0.0.0.0:8080"]
|
||||
```
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
pocketbase:
|
||||
build: .
|
||||
ports:
|
||||
- "8080:8080"
|
||||
volumes:
|
||||
- pb_data:/pb/pb_data
|
||||
environment:
|
||||
GOMEMLIMIT: "512MiB"
|
||||
PB_ENCRYPTION_KEY: "${PB_ENCRYPTION_KEY}"
|
||||
command: ["/pb/pocketbase", "serve", "--http=0.0.0.0:8080", "--encryptionEnv=PB_ENCRYPTION_KEY"]
|
||||
volumes:
|
||||
pb_data:
|
||||
```
|
||||
|
||||
**Quick-reference checklist:**
|
||||
|
||||
| Concern | Fix |
|
||||
|---------|-----|
|
||||
| `Too many open files` errors | `ulimit -n 4096` (or `LimitNOFILE=4096` in systemd) |
|
||||
| OOM kill on constrained host | `GOMEMLIMIT=512MiB` env var |
|
||||
| Credentials visible in DB backup | `--encryptionEnv=YOUR_VAR` with a 32-char random key |
|
||||
| Persistent data in Docker | Mount volume at `/pb/pb_data` |
|
||||
|
||||
Reference: [Going to production](https://pocketbase.io/docs/going-to-production/)
|
||||
Reference in New Issue
Block a user