PocketBase容器化部署:Docker Compose与Kubernetes

【免费下载链接】pocketbase 开源的实时后端,仅用1个文件实现。 【免费下载链接】pocketbase 项目地址: https://gitcode.com/GitHub_Trending/po/pocketbase

概述

PocketBase是一个开源的Go语言后端框架,集成了嵌入式SQLite数据库、实时订阅、文件管理、用户管理和RESTful API等功能。本文将详细介绍如何将PocketBase应用容器化部署,涵盖Docker Compose和Kubernetes两种主流方案。

容器化部署的优势

mermaid

通过容器化部署,您可以获得以下好处:

  • 环境一致性:确保开发、测试、生产环境一致
  • 快速部署:一键启动完整的PocketBase服务
  • 资源隔离:避免环境冲突和依赖问题
  • 易于扩展:支持水平扩展和高可用部署

Docker Compose部署方案

基础Dockerfile

首先创建Dockerfile来构建PocketBase镜像:

# 使用多阶段构建减少镜像大小
FROM golang:1.23-alpine AS builder

# 安装必要的构建工具
RUN apk add --no-cache git make

# 设置工作目录
WORKDIR /app

# 复制go.mod和go.sum文件
COPY go.mod go.sum ./

# 下载依赖
RUN go mod download

# 复制源代码
COPY . .

# 构建PocketBase可执行文件
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o pocketbase ./examples/base

# 使用轻量级基础镜像
FROM alpine:3.18

# 安装必要的运行时依赖
RUN apk add --no-cache ca-certificates tzdata

# 创建非root用户
RUN addgroup -g 1000 pocketbase && \
    adduser -u 1000 -G pocketbase -D pocketbase

# 设置工作目录
WORKDIR /app

# 从构建阶段复制可执行文件
COPY --from=builder --chown=pocketbase:pocketbase /app/pocketbase .

# 创建数据目录
RUN mkdir -p /app/pb_data && \
    chown pocketbase:pocketbase /app/pb_data

# 切换到非root用户
USER pocketbase

# 暴露端口
EXPOSE 8090

# 启动命令
ENTRYPOINT ["./pocketbase", "serve", "--http=0.0.0.0:8090"]

Docker Compose配置

创建docker-compose.yml文件:

version: '3.8'

services:
  pocketbase:
    build: .
    container_name: pocketbase
    ports:
      - "8090:8090"
    volumes:
      - pocketbase_data:/app/pb_data
      - ./pb_public:/app/pb_public:ro
    environment:
      - TZ=Asia/Shanghai
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "wget", "--spider", "-q", "http://localhost:8090/api/health"]
      interval: 30s
      timeout: 10s
      retries: 3

volumes:
  pocketbase_data:
    driver: local

高级Docker Compose配置

对于生产环境,可以使用更完整的配置:

version: '3.8'

services:
  pocketbase:
    build:
      context: .
      dockerfile: Dockerfile
    image: myapp/pocketbase:latest
    container_name: pocketbase-prod
    ports:
      - "8090:8090"
    volumes:
      - pocketbase_data:/app/pb_data
      - ./pb_public:/app/pb_public:ro
      - ./pb_hooks:/app/pb_hooks:ro
      - ./pb_migrations:/app/pb_migrations:ro
    environment:
      - TZ=Asia/Shanghai
      - PB_HOOKS_DIR=/app/pb_hooks
      - PB_MIGRATIONS_DIR=/app/pb_migrations
      - PB_PUBLIC_DIR=/app/pb_public
    restart: always
    deploy:
      resources:
        limits:
          memory: 512M
          cpus: '1'
        reservations:
          memory: 256M
          cpus: '0.5'
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8090/api/health"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 40s

volumes:
  pocketbase_data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: ./data

部署和管理命令

# 构建并启动服务
docker-compose up -d

# 查看服务状态
docker-compose ps

# 查看日志
docker-compose logs -f pocketbase

# 停止服务
docker-compose down

# 备份数据
docker-compose exec pocketbase ./pocketbase backup create

# 恢复数据
docker-compose exec pocketbase ./pocketbase backup restore <backup-file>

Kubernetes部署方案

命名空间配置

创建namespace.yaml:

apiVersion: v1
kind: Namespace
metadata:
  name: pocketbase
  labels:
    name: pocketbase

配置映射

创建configmap.yaml用于环境配置:

apiVersion: v1
kind: ConfigMap
metadata:
  name: pocketbase-config
  namespace: pocketbase
data:
  TZ: Asia/Shanghai
  PB_PUBLIC_DIR: /app/pb_public

持久化存储

创建pvc.yaml用于数据持久化:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pocketbase-data-pvc
  namespace: pocketbase
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi
  storageClassName: standard

部署配置

创建deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pocketbase
  namespace: pocketbase
  labels:
    app: pocketbase
spec:
  replicas: 2
  selector:
    matchLabels:
      app: pocketbase
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: pocketbase
    spec:
      containers:
      - name: pocketbase
        image: myapp/pocketbase:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8090
        env:
        - name: TZ
          valueFrom:
            configMapKeyRef:
              name: pocketbase-config
              key: TZ
        - name: PB_PUBLIC_DIR
          valueFrom:
            configMapKeyRef:
              name: pocketbase-config
              key: PB_PUBLIC_DIR
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        volumeMounts:
        - name: pocketbase-data
          mountPath: /app/pb_data
        - name: public-data
          mountPath: /app/pb_public
          readOnly: true
        livenessProbe:
          httpGet:
            path: /api/health
            port: 8090
          initialDelaySeconds: 30
          periodSeconds: 10
          timeoutSeconds: 5
          failureThreshold: 3
        readinessProbe:
          httpGet:
            path: /api/health
            port: 8090
          initialDelaySeconds: 5
          periodSeconds: 5
          timeoutSeconds: 3
          failureThreshold: 1
      volumes:
      - name: pocketbase-data
        persistentVolumeClaim:
          claimName: pocketbase-data-pvc
      - name: public-data
        configMap:
          name: pocketbase-public-files

服务暴露

创建service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: pocketbase-service
  namespace: pocketbase
spec:
  selector:
    app: pocketbase
  ports:
  - port: 8090
    targetPort: 8090
  type: ClusterIP

Ingress配置

创建ingress.yaml用于外部访问:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: pocketbase-ingress
  namespace: pocketbase
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  ingressClassName: nginx
  rules:
  - host: pocketbase.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: pocketbase-service
            port:
              number: 8090
  tls:
  - hosts:
    - pocketbase.example.com
    secretName: pocketbase-tls

Kubernetes部署流程

mermaid

数据备份与恢复策略

自动化备份方案

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: pocketbase-backup
  namespace: pocketbase
spec:
  schedule: "0 2 * * *"  # 每天凌晨2点执行
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: backup
            image: bitnami/kubectl:latest
            command:
            - /bin/sh
            - -c
            - |
              # 执行备份命令
              kubectl exec deployment/pocketbase -- ./pocketbase backup create \
                --output /app/pb_data/backups/backup-$(date +%Y%m%d-%H%M%S).zip
              
              # 清理旧备份(保留最近7天)
              find /app/pb_data/backups -name "*.zip" -mtime +7 -delete
            volumeMounts:
            - name: pocketbase-data
              mountPath: /app/pb_data
          restartPolicy: OnFailure
          volumes:
          - name: pocketbase-data
            persistentVolumeClaim:
              claimName: pocketbase-data-pvc

监控与日志

Prometheus监控配置

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: pocketbase-monitor
  namespace: pocketbase
  labels:
    app: pocketbase
spec:
  selector:
    matchLabels:
      app: pocketbase
  endpoints:
  - port: http
    interval: 30s
    path: /metrics

日志收集配置

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluent-bit
  namespace: kube-system
spec:
  template:
    spec:
      containers:
      - name: fluent-bit
        image: fluent/fluent-bit:latest
        volumeMounts:
        - name: varlog
          mountPath: /var/log
        - name: pocketbase-logs
          mountPath: /var/log/pocketbase
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: pocketbase-logs
        persistentVolumeClaim:
          claimName: pocketbase-data-pvc

安全最佳实践

安全上下文配置

securityContext:
  runAsNonRoot: true
  runAsUser: 1000
  runAsGroup: 1000
  fsGroup: 1000
  capabilities:
    drop:
    - ALL
  readOnlyRootFilesystem: true
  allowPrivilegeEscalation: false

网络策略

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: pocketbase-network-policy
  namespace: pocketbase
spec:
  podSelector:
    matchLabels:
      app: pocketbase
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: monitoring
    ports:
    - protocol: TCP
      port: 8090
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 169.254.169.254/32
    ports:
    - protocol: TCP
      port: 53
    - protocol: UDP
      port: 53

性能优化建议

资源配额管理

环境 CPU请求 CPU限制 内存请求 内存限制 副本数
开发 100m 200m 128Mi 256Mi 1
测试 200m 500m 256Mi 512Mi 2
生产 500m 1000m 512Mi 1Gi 3

数据库性能优化

-- PocketBase使用的SQLite性能优化参数
PRAGMA journal_mode = WAL;
PRAGMA synchronous = NORMAL;
PRAGMA cache_size = -2000; -- 2MB cache
PRAGMA temp_store = MEMORY;

故障排除指南

常见问题及解决方案

问题现象 可能原因 解决方案
容器启动失败 端口冲突 检查8090端口是否被占用
数据持久化失败 权限问题 确保数据目录有写权限
健康检查失败 服务未就绪 增加initialDelaySeconds
内存不足 资源限制过低 调整resources limits
备份失败 存储空间不足 清理旧备份或扩容存储

诊断命令

# 查看Pod状态
kubectl get pods -n pocketbase

# 查看日志
kubectl logs -f deployment/pocketbase -n pocketbase

# 进入容器调试
kubectl exec -it deployment/pocketbase -n pocketbase -- sh

# 检查资源使用
kubectl top pods -n pocketbase

# 检查事件
kubectl get events -n pocketbase --sort-by=.lastTimestamp

总结

通过本文介绍的Docker Compose和Kubernetes部署方案,您可以轻松地将PocketBase应用容器化部署到各种环境中。Docker Compose适合开发和测试环境,提供快速部署和简单管理;Kubernetes适合生产环境,提供高可用性、弹性伸缩和完整的运维能力。

关键要点总结:

  1. 数据持久化:确保pb_data目录的持久化存储
  2. 资源管理:合理配置CPU和内存资源限制
  3. 健康检查:配置完善的存活性和就绪性探针
  4. 备份策略:建立定期备份和恢复机制
  5. 安全加固:使用非root用户运行,限制容器权限
  6. 监控告警:集成Prometheus和日志收集系统

选择合适的部署方案,根据实际业务需求调整配置参数,即可构建稳定可靠的PocketBase容器化部署环境。

【免费下载链接】pocketbase 开源的实时后端,仅用1个文件实现。 【免费下载链接】pocketbase 项目地址: https://gitcode.com/GitHub_Trending/po/pocketbase

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐