生產部署指南
Docker 部署
Core + Spectrum(基礎映像)
# Dockerfile.nextpdf-core
FROM php:8.5-cli-bookworm
# 安裝 PHP 擴充套件
RUN docker-php-ext-install pcntl
RUN pecl install pcov && docker-php-ext-enable pcov
# 安裝 Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
# 複製應用程式
WORKDIR /app
COPY composer.json composer.lock ./
RUN composer install --no-dev --optimize-autoloader --no-interaction
# 安裝 Spectrum 加速引擎(可選)
COPY --from=ghcr.io/nextpdf-labs/spectrum:latest \
/usr/local/bin/nextpdf-spectrum \
/usr/local/bin/nextpdf-spectrum
RUN chmod +x /usr/local/bin/nextpdf-spectrum
COPY . .
CMD ["php", "artisan", "serve", "--host=0.0.0.0"]
Artisan(含 Chrome)
# Dockerfile.nextpdf-artisan
FROM php:8.5-cli-bookworm
# 安裝 Google Chrome
RUN apt-get update && apt-get install -y \
wget gnupg2 \
&& wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" \
>> /etc/apt/sources.list.d/google-chrome.list \
&& apt-get update && apt-get install -y google-chrome-stable \
&& rm -rf /var/lib/apt/lists/*
# 建立非 root 使用者
RUN useradd -m -u 1000 nextpdf
USER nextpdf
# ... 其餘步驟
docker-compose(完整堆疊)
# docker-compose.yml
version: '3.9'
services:
app:
build:
context: .
dockerfile: Dockerfile.nextpdf-artisan
environment:
SPECTRUM_BINARY: /usr/local/bin/nextpdf-spectrum
GOTENBERG_URL: http://gotenberg:3000
depends_on:
gotenberg:
condition: service_healthy
volumes:
- ./fonts:/fonts:ro
- ./output:/output
gotenberg:
image: gotenberg/gotenberg:8
command:
- "gotenberg"
- "--chromium-disable-javascript=true"
- "--api-timeout=30s"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 10s
timeout: 5s
retries: 3
ports:
- "3000:3000"
Kubernetes 部署
Deployment 設定
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nextpdf-app
namespace: production
spec:
replicas: 3
selector:
matchLabels:
app: nextpdf-app
template:
metadata:
labels:
app: nextpdf-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 1000
containers:
- name: app
image: ghcr.io/your-org/nextpdf-app:latest
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
env:
- name: GOTENBERG_URL
value: "http://gotenberg-service:3000"
- name: PDF_USER_PASSWORD
valueFrom:
secretKeyRef:
name: nextpdf-secrets
key: pdf-user-password
volumeMounts:
- name: fonts
mountPath: /fonts
readOnly: true
volumes:
- name: fonts
configMap:
name: nextpdf-fonts
水平自動擴展
# k8s/hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: nextpdf-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: nextpdf-app
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Cloudflare Workers
// wrangler.toml
[vars]
NEXTPDF_FONTS_URL = "https://assets.example.com/fonts"
[[rules]]
type = "ESModule"
globs = ["**/*.mjs"]
環境設定
# .env.production
APP_ENV=production
# NextPDF Core
NEXTPDF_FONT_PATH=/fonts
NEXTPDF_OUTPUT_PATH=/tmp/nextpdf
# Spectrum 加速引擎
SPECTRUM_BINARY=/usr/local/bin/nextpdf-spectrum
SPECTRUM_MAX_CONNECTIONS=4
SPECTRUM_CIRCUIT_BREAKER_THRESHOLD=3
# Gotenberg
GOTENBERG_URL=http://gotenberg:3000
GOTENBERG_TIMEOUT=30
# PDF 加密
PDF_USER_PASSWORD=${SECRET_FROM_VAULT}
PDF_OWNER_PASSWORD=${SECRET_FROM_VAULT}
# SonarQube(CI 用)
SONAR_TOKEN=${SONAR_TOKEN}
安全強化
健康檢查與監控
延伸閱讀