Kubernetes環境におけるPenpotのスケーラブルな本番運用:Auto Scalingと永続ボリューム設定の完全設計図
プロダクト開発において、デザインとコードの乖離をなくし、デザインシステムの単一の真実のソース(Single Source of Truth)を確立することは、現代のプロダクトチームにおける至上命題だ。オープンソースの本格的デザイン・プロトタイピングツールであるPenpotは、その強力な武器となる。
しかし、Docker Composeによる「ローカルのお手軽セルフホスト」のままでは、数十人規模のデザイナー・エンジニアが同時にキャンバスを開いた瞬間、バックエンドは崩壊する。リアルタイムコラボレーションの要であるWebSocketの維持、アセット(SVG/画像)の永続化、そして水平スケーリング(Horizontal Scaling)——。
本稿では、テックリードである君が、全社規模の開発基盤としてPenpotをKubernetes(K8s)上に堅牢に構築し、チーム全体の生産性を極限まで引き上げるための「完全設計図」を授ける。
—
1. プロダクションアーキテクチャの全体像
PenpotをK8s上でスケールさせるにあたり、最大のボトルネックとなるのは「ステートの共有」と「リアルタイム同期(WebSocket)」だ。
Penpotのバックエンドは、大きく分けて以下のコンポーネントで構成される。
1. frontend: Nginx + SPA(静的アセット)
2. backend: Clojure製のコアロジック&APIサーバー(ステートレス化可能)
3. exporter: SVG/PDFエクスポート処理(CPUバウンドな重い処理)
4. postgresql: ユーザーデータ、キャンバスのJSON構造の永続化
5. redis: セッション管理およびWebSocketのメッセージブローカー(Pub/Sub)
複数ポッドへスケールアウトさせるためには、バックエンドがRedisを介してセッションとリアルタイムイベントを完全に共有していることが絶対条件となる。
—
2. 実用的なKubernetesマニフェスト(ベストプラクティス構成)
以下に、K8s(EKS, GKE, AKS, 自社オンプレ同等)環境でそのまま適用できるプロダクションクオリティのマニフェスト構成を示す。セキュリティコンテキスト、リソース制限、ヘルスチェック(Liveness/Readiness Probe)を完備している。
命名規則と名前空間
すべてのリソースは `penpot` 名前空間にデプロイし、Ingressを通じて安全に外部公開する。
apiVersion: v1
kind: Namespace
metadata:
name: penpot
labels:
app.kubernetes.io/name: penpot
—
==========================================
ConfigMap: アプリケーション環境変数
==========================================
apiVersion: v1
kind: ConfigMap
metadata:
name: penpot-config
namespace: penpot
data:
PENPOT_PUBLIC_URI: “https://penpot.internal.company.com”
PENPOT_FLAGS: “enable-registration,enable-teams”
# Redis接続設定(クラスタ内のRedisサービスを指定)
PENPOT_REDIS_URI: “redis://penpot-redis:6379”
# PostgreSQL接続設定(Secretから参照されない公開変数のみ)
PENPOT_DATABASE_URI: “postgresql://penpot:secure_password@penpot-postgres:5432/penpot”
—
==========================================
Deployment: Penpot Backend
==========================================
apiVersion: apps/v1
kind: Deployment
metadata:
name: penpot-backend
namespace: penpot
labels:
app.kubernetes.io/component: backend
spec:
replicas: 3 # 複数ポッド構成による可用性の確保
selector:
matchLabels:
app.kubernetes.io/component: backend
template:
metadata:
labels:
app.kubernetes.io/component: backend
spec:
containers:
- name: backend
image: penpotapp/backend:latest
imagePullPolicy: IfNotPresent
envFrom:
- configMapRef:
name: penpot-config
env:
- name: PENPOT_DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: penpot-secret
key: database-password
ports:
- containerPort: 6060
name: http
resources:
requests:
cpu: “500m”
memory: “1Gi”
limits:
cpu: “2000m”
memory: “4Gi”
# リアルタイム共同編集のため、コネクション切れを防ぐプローブ設定
livenessProbe:
httpGet:
path: /api/health
port: 6060
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health
port: 6060
initialDelaySeconds: 10
periodSeconds: 5
—
==========================================
HorizontalPodAutoscaler (HPA)
==========================================
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: penpot-backend-hpa
namespace: penpot
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: penpot-backend
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 75
—
3. 永続ボリューム(PV/PVC)とオブジェクトストレージの設計
デザインツールであるPenpotは、ユーザーがアップロードする高解像度画像やSVG、生成されたファイルデータの保管が極めて重要だ。
アセットの永続化戦略
デフォルトではローカルファイルシステムに保存されるアセットだが、K8sでのPod再起動やAuto Scalingに対応するため、NFS(ReadWriteMany)またはAWS S3などのオブジェクトストレージ(S3互換ストレージ)へ逃がす設定が必須となる。
環境変数に以下を追加することで、S3互換ストレージ(MinIOやAWS S3)へシームレスにダイレクトアップロードさせることができる。
PENPOT_STORAGE_BACKEND: “penpot.storage.s3”
PENPOT_S3_BUCKET: “company-penpot-assets”
PENPOT_S3_REGION: “ap-northeast-1”
# IAMロール(IRSA)を利用する場合はキーの設定を省略可能
—
4. IngressとCert-ManagerによるTLS終端・WebSocket最適化
Penpotの命であるリアルタイム通信(WebSocket)を安定させるためには、Ingressコントローラー(Nginx Ingressなど)のタイムアウト設定を明示的にチューニングする必要がある。これが漏れると、数分放置しただけでキャンバスの同期が切断される。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: penpot-ingress
namespace: penpot
annotations:
kubernetes.io/ingress.class: “nginx”
cert-manager.io/cluster-issuer: “letsencrypt-prod”
# WebSocketのタイムアウトを延長(重要)
nginx.ingress.kubernetes.io/proxy-read-timeout: “3600”
nginx.ingress.kubernetes.io/proxy-send-timeout: “3600”
nginx.ingress.kubernetes.io/websocket-services: “penpot-backend,penpot-frontend”
# アップロードサイズ制限の緩和(大容量アセット対策)
nginx.ingress.kubernetes.io/proxy-body-size: “100M”
spec:
tls:
- hosts:
- penpot.internal.company.com
secretName: penpot-tls-cert
rules:
- host: penpot.internal.company.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: penpot-frontend
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: penpot-backend
port:
number: 6060
- path: /ws
pathType: Prefix
backend:
service:
name: penpot-backend
port:
number: 6060
—
5. 開発スピードを劇的に高めるプロの実践テクニック
ここからは、インフラの上に立つアプリケーション層において、チーム全体の開発・デザインスピードを限界突破させるための実践知見を共有する。
1. 開発効率を爆発させる隠れたキーボードショートカット
PenpotはFigma等の主要ツールからの移行組が直感的に動かせるよう設計されているが、以下のショートカットをチーム標準として暗記させると、マウス操作のロスが消え、モック作成速度が3倍になる。
- `Shift + A`: オートレイアウト(Flexbox構造)の即時適用。エンジニアのCSSメンタルモデルと完全に一致する。
- `Alt + Drag`: 厳密なピクセル単位のスペーシング確認(Figmaと同様のインスペクト挙動)。
- `Ctrl/Cmd + /`: クイックサーチ(コマンドパレット)。メニューを探す時間をゼロにする。
- `V` / `H`: コンポーネント内の要素の垂直・水平分散配置。
2. 絶対入れるべき神プラグイン・拡張機能
Penpotのプラグインエコシステム、あるいは開発者が自作すべき拡張の方向性として、チーム開発で導入必須なアプローチを挙げる。
- Design Tokens Importer (JSON Sync):
エンジニアリング側の `tokens.json` (Style Dictionary等で管理される変数) をPenpotに同期し、カラーパレットやタイポグラフィの「ソースの二重管理」を根絶する。
- Accessibility (a11y) Contrast Checker:
コントラスト比をリアルタイムで検証し、WCAG 2.1の基準を満たしているかをデザイン段階で担保する。リリース前の手戻りを劇的に削減できる。
3. チーム開発で役立つ設定の共有化ルール(ガバナンス)
大規模チームでPenpotを運用する場合、野良デザインが乱立することが最大の敵となる。
1. 「Shared Libraries(共有ライブラリ)」の強制:
個人スペースでの作成を原則禁止し、チームスペース配下に「Company Design System」としてマスターライブラリを配置。コンポーネントの改変はプルリクエスト文化に準じた「デザインレビュープロセス」を経る。
2. ネーミング規則のコード同期(BEM/Tailwind準拠):
レイヤー名やコンポーネント名を、エンジニアが実装で使用するクラス名やコンポーネント名(例: `Button/Primary/Large` → ``)と完全に一致させる命名規則をドキュメント化し、オンボーディングの必須科目とする。
—
結び:インフラとプロセスの両立がもたらすもの
KubernetesによるPenpotの堅牢なスケーラブル運用の構築は、単に「ツールが落ちない」というインフラストラクチャ上の安心感にとどまらない。
それは、「デザイナーのアイデアが、数秒後にKubernetes上で動く本番環境のプレビューやコードへとシームレスに結びつく」という、究極のプロダクト開発パイプラインの実現に他ならない。
テックリードであるあなたがこの基盤を築きあげることで、チームの心理的安全性が高まり、開発速度とプロダクト品質は新たな次元へと到達するはずだ。さあ、今すぐYAMLを適用し、チームを次のステージへ導こう。