【入門編】Kubernetes環境におけるPenpotのスケーラブルな本番運用:Auto Scalingと永続ボリューム設定の完全設計図 – UI/UX・デザインツール活用バイブル

こんにちは!プロダクトデザインとフロントエンドの境界線を溶かし、デザイナーとエンジニアを真に同期させるオープンソースのプロトタイピングツール「Penpot」の世界へようこそ。

「Figmaの強力なオープンソース代替としてPenpotを触ってみたけれど、ローカルのDocker Compose環境から抜け出して、チーム全員で使える本番環境をどう作ればいいか悩んでいる……」
そんな壁にぶつかっていませんか?

今日は、ただ動くだけのチュートリアルではありません。Kubernetes(K8s)という強固な土台の上で、数分で落ちたりデータが消えたりしない、スケールするPenpotの本番環境を構築するための「完全設計図」をあなたに授けます。

これをマスターすれば、インフラの不安から解放され、チームは最高のプロダクトづくりに全集中できるようになりますよ。さあ、一緒に最高のインフラストラクチャを組み上げましょう!

—

1. なぜ「K8sでのPenpot運用」がプロダクト開発のゲームチェンジャーなのか?

まず、Penpotがチーム開発においてどれほど強力なツールか、そしてなぜそれをKubernetesで動かすべきなのかを整理しておきましょう。

Penpotの正体と、なぜセルフホストなのか

Penpotは、SVGをネイティブフォーマットとして採用し、CSS GridやFlexboxの概念をそのままデザインツールに持ち込んだ、エンジニアにとって最高に「話が通じる」デザインツールです。
企業でこれを導入する際、SaaS版ではなくセルフホスト(オンプレミス・プライベートクラウド)を選ぶ最大の理由は「セキュリティ」と「データ主権」です。機密性の高いデザインアセットやプロダクトの設計図を外部に出さず、社内の厳格なガバナンス下で安全に運用できます。

Docker ComposeからK8sへステップアップする理由

「最初はDocker Composeで立ち上げたけれど、チームが50人、100人と増えるにつれて重くなってきた」「マルチノードで負荷分散させたい」「DBのバックアップやスケーリングを自動化したい」。
そんなスケールの壁に直面したとき、Kubernetesへの移行は必然の選択となります。K8sであれば、トラフィックの増減に応じたAuto Scalingや、セッションの分散、高可用性(High Availability)をコード(マニフェスト)として美しく管理できます。

—

2. 全体アーキテクチャの俯瞰

今回構築するKubernetes環境の全体像は以下の通りです。

[Users / Browsers]
│
▼ (HTTPS / TLS)
[Ingress Controller (Nginx)]
│
├─────────────────────────┐
▼ ▼
[Penpot Frontend Pods] [Penpot Backend (Rpc/Export) Pods]
│ │
└───────────┬─────────────┘
│
┌─────────┴─────────カーネル間通信
▼ ▼
[Managed PostgreSQL] [Managed Redis]
(永続ボリューム) (セッション管理・ジョブ)

Penpotは主に、フロントエンド(Nginx + SPA)、バックエンド(Clojure製のRPCサーバー等)、非同期処理用のバックグラウンドワーカー、そしてデータベース(PostgreSQL)とキャッシュ/メッセージブローカー(Redis)で構成されています。

—

3. 本番構築のステップバイステップ・レシピ

ここからが本題です。プロダクションレベルで耐えうるマニフェストをひとつずつ丁寧に組み立てていきましょう。

Step 1: 永続化とステートフル層の最適化(PostgreSQL & Redis)

本番運用において、データの消失は絶対に許されない大罪です。PostgreSQLとRedisは、それぞれ適切なストレージクラスとリソース制限を設定します。

今回はKubernetesクラスタ外のマネージドサービス(AWS RDSやCloud SQLなど)を使う想定、あるいはクラスタ内にStatefulSetとして立てる想定の共通設定として、まずはアプリ層(Penpot Backend/Frontend)から接続するための Secret を定義します。

penpot-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: penpot-secret
namespace: penpot
type: Ostring
stringData:
# 本番環境では必ず強固なランダム文字列に変更してください
PENPOT_SECRET_KEY: “your-super-secret-and-long-random-key-here”

# データベース接続情報
PENPOT_DATABASE_URI: “postgresql://penpot_user:your_secure_password@postgres-service.penpot.svc.cluster.local:5432/penpot”

# Redis接続情報
PENPOT_REDIS_URI: “redis://:your_redis_password@redis-service.penpot.svc.cluster.local:6379”

> 先輩の知恵: `PENPOT_SECRET_KEY` はセッションの暗号化などに使われます。ここが漏洩すると全セッションが乗っ取られるリスクがあるため、K8sのネイティブなSealed SecretsやExternal Secrets Operatorを使って安全にインジェクションすることをお勧めします。

—

Step 2: Penpot Backend (API/RPC) のデプロイと複数ポッド運用のキモ

Penpotのバックエンドは、ユーザーからの操作を処理する心臓部です。複数ポッドで水平スケール(Horizontal Pod Autoscaling)させるために、セッション管理とジョブキューがRedisによって適切に共有されていることが前提となります。

以下は、スケーラブルなバックエンドのDeploymentマニフェストです。

penpot-backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: penpot-backend
namespace: penpot
labels:
app.kubernetes.io/name: penpot-backend
spec:
replicas: 3 # 最初から3ポッド構成にし、可用性を担保する
selector:
matchLabels:
app: penpot-backend
template:
metadata:
labels:
app: penpot-backend
spec:
containers:

  • name: backend

image: penpotapp/backend:latest
ports:

  • containerPort: 6060

envFrom:

  • secretRef:

name: penpot-secret
env:

  • name: PENPOT_PUBLIC_URI

value: “https://design.yourcompany.com”

  • name: PENPOT_TELEMETRY_ENABLED

value: “false” # 本番環境ではテレメトリーをオフに
resources:
requests:
cpu: “500m”
memory: “1Gi”
limits:
cpu: “2000m”
memory: “4Gi”
readinessProbe:
httpGet:
path: /api/healthz
port: 6060
initialDelaySeconds: 15
periodSeconds: 10
livenessProbe:
httpGet:
path: /api/healthz
port: 6060
initialDelaySeconds: 30
periodSeconds: 15

—

Step 3: Penpot Frontend のデプロイ

フロントエンドは静的なアセット(HTML/JS/CSS)の配信がメインですが、APIリクエストをバックエンドへプロキシする役割も持っています。

penpot-frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: penpot-frontend
namespace: penpot
labels:
app.kubernetes.io/name: penpot-frontend
spec:
replicas: 2
selector:
matchLabels:
app: penpot-frontend
template:
metadata:
labels:
app: penpot-frontend
spec:
containers:

  • name: frontend

image: penpotapp/frontend:latest
ports:

  • containerPort: 8080

env:

  • name: PENPOT_BACKEND_URI

value: “http://penpot-backend-service.penpot.svc.cluster.local:6060”
resources:
requests:
cpu: “100m”
memory: “256Mi”
limits:
cpu: “500m”
memory: “512Mi”

そして、それぞれのサービス(Service)オブジェクトも作成しておきます(省略しますが、ClusterIPタイプでポートを適切につないでください)。

—

Step 4: Ingress と Cert-Manager による堅牢なTLS終端

本番運用においてHTTPS(TLS)は必須です。`ingress-nginx` と `cert-manager`(Let’s Encrypt)を組み合わせることで、証明書の自動発行・更新までを完全に自動化します。

penpot-ingress.yaml
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を多用するPenpotのためにタイムアウトを長めに設定するのがプロの技
nginx.ingress.kubernetes.io/proxy-read-timeout: “3600”
nginx.ingress.kubernetes.io/proxy-send-timeout: “3600”
nginx.ingress.kubernetes.io/websocket-services: “penpot-backend”
# 大きなデザインファイルをアップロードできるようにサイズ制限を緩和
nginx.ingress.kubernetes.io/proxy-body-size: “100M”
spec:
tls:

  • hosts:
  • design.yourcompany.com

secretName: penpot-tls-cert
rules:

  • host: design.yourcompany.com

http:
paths:
# APIへのルーティング

  • path: /api

pathType: Prefix
backend:
service:
name: penpot-backend-service
port:
number: 6060
# RPC (Websocket等) へのルーティング

  • path: /rpc

pathType: Prefix
backend:
service:
name: penpot-backend-service
port:
number: 6060
# その他全てはフロントエンドへ

  • path: /

pathType: Prefix
backend:
service:
name: penpot-frontend-service
port:
number: 8080

> ここが極限の知見!: Penpotはリアルタイム共同編集を行うため、WebSocketの維持とプロキシのタイムアウト時間(`proxy-read-timeout`)の延長が極めて重要です。ここを設定し忘れると、数分おきにコネクションが切れて「あれ、保存されない?」という悲劇が起きます。必ず上記のアノテーションを付与してください。

—

Step 5: Auto Scaling (HPA) の設定でスパイクに備える

朝会直後や、デザインレビューのタイミングで一斉にデザイナーやエンジニアがアクセスしてきても、CPU使用率に応じて自動でポッドを増やしてくれるHPA(Horizontal Pod Autoscaler)を設定しておきましょう。

penpot-backend-hpa.yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: penpot-backend-hpa
namespace: penpot
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: penpot-backend
minReplicas: 2
maxReplicas: 10
metrics:

  • type: Resource

resource:
name: cpu
target:
type: Utilization
averageUtilization: 70

これで、CPU使用率が平均70%を超えた瞬間に自動スケールアウトし、負荷が下がればリソースを自動回収してくれます。クラウドのコスト最適化にも直結する重要な設定です。

—

4. 精度高い「HelloWorld」的 動作確認チェックリスト

マニフェストを適用(`kubectl apply -f`)したら、以下の手順でシステムが正常に稼働しているか、プロの視点でスモークテストを行いましょう。

1. ポッドの起動確認

kubectl get pods -n penpot

すべてのポッドが `Running` かつ `1/1 Ready` になっていることを確認します。
2. ログのエラーチェック

kubectl logs -l app=penpot-backend -n penpot –tail=50

Clojureのランタイムエラーや、DB接続失敗(Connection Refused)が出ていないかをチェック。
3. ブラウザからの疎通 & ログインテスト
`https://design.yourcompany.com` にアクセスし、Penpotの美しいログイン画面が表示されるか確認します。
4. リアルタイム共同編集ストレステスト(超重要)

  • ブラウザの別タブ(または別ブラウザ)で同じプロジェクトを開き、図形を動かしてみてください。
  • ラグなくリアルタイムに同期するか?
  • WebSocketが切断されずに維持されるか?(F12の開発者ツールでNetworkタブを確認)

これらすべてをクリアしていれば、あなたのKubernetes上のPenpot本番環境は、数人から数百人のチーム規模まで耐えうる「完全無欠のステージ」へと仕上がっています!

—

おわりに

今回は、Docker Composeの枠を飛び出し、Kubernetes環境においてPenpotをスケーラブルかつ堅牢に本番運用するための設計図を解説しました。

インフラの構築は最初は難しく感じるかもしれませんが、一度この宣言的なマニフェスト(Infrastructure as Code)を組み上げてしまえば、あとはK8sが自動であなたのシステムを守り、スケールさせてくれます。

これをマスターすれば、毎日のチーム開発やデザインのフローが劇的に、そして圧倒的にスムーズになりますよ。さあ、今すぐあなたのクラスタにこの設計図をデプロイし、チームメンバーを驚かせましょう!

タイトルとURLをコピーしました