【実務・中級編】【エラー解決】Penpotのセルフホスト環境でよくあるトラブルとパフォーマンス改善の極意 – UI/UX・デザインツール活用バイブル

【エラー解決】Penpotのセルフホスト環境でよくあるトラブルとパフォーマンス改善の極意

テックリードの君なら、Figmaの料金改定やデータ主権(Data Sovereignty)、そしてベンダーロックインへの懸念から、オープンソースの最強デザインツール「Penpot」のセルフホスト(Docker基盤)へ舵を切ったはずだ。SVGネイティブ、CSS Grid / Flexbox完全準拠のレイアウトエンジン——開発者フレンドリーを極めたこのツールは、デザイナーとエンジニアの共通言語を作る上で唯一無二の存在となり得る。

しかし、いざ自社インフラやローカル開発環境にデプロイしてみると、「コンテナが起動しない」「DB接続が切れる」「描画が重い」といったインフラ起因の壁にぶぶつかる。

今回は、プロダクトの命運を握るデザイン基盤を安定稼働させ、開発チーム全体の生産性を極限まで引き上げるための「セルフホスト運用の極意」を授けよう。

—

1. 起動時・接続時のインフラトラブルシューティング

PenpotのDocker Compose構成は洗練されているが、コンテナ間の依存関係や環境変数のミスマッチによって、静かに沈黙することが多い。現場で頻発するエラーと、その秒速解決のレシピを公開する。

トラブルA: `docker compose up` 直後の無限再起動ループ

  • 症状: `penpot-backend` や `penpot-frontend` が `Exited (1)` を繰り返し、ログに `Waiting for database…` すら出ない。
  • 真因: PostgreSQLコンテナ(`penpot-postgres`)のヘルスチェックが完了する前に、バックエンドが接続を試みている。あるいは、Dockerボリュームのパーミッション競合。
  • 解決策: `docker-compose.yaml` において、`depends_on` の条件に `condition: service_healthy` を明示的に記述し、DBの完全な初期化を待たせる。

トラブルB: データベース接続エラーとマイグレーションのスタック

  • 症状: `org.postgresql.util.PSQLException: FATAL: database “penpot” does not exist` またはマイグレーション途中でコネクションが切断される。
  • 真因: 初回起動時に環境変数(`POSTGRES_DB`, `POSTGRES_USER`, `POSTGRES_PASSWORD`)の変更を行ったが、すでに古いボリュームデータが残存しており、PostgreSQLの初期化スクリプト(`/docker-entrypoint-initdb.d/`)がスキップされた。
  • 解決策: 一度完全に環境をパージし、ボリュームをクリーンアップする。

# 警告: すべてのローカルデータが消えます。本番では要バックアップ。
docker compose down -v
docker compose up -d

—

2. 実用的な設定ファイル(YAML)のベストプラクティス構成例

セルフホスト環境をプロダクションレベル(あるいは快適な開発環境)に引き上げるための、リソース制限と環境変数を最適化した `docker-compose.yaml` のベストプラクティス構成だ。

version: ‘3.8’

services:
penpot-frontend:
image: penpotapp/frontend:latest
restart: always
ports:

  • “8080:8080”

depends_on:

  • penpot-backend

environment:

  • PENPOT_BACKEND_URI=http://penpot-backend:6060
  • PENPOT_FLAGS=enable-registration,enable-teams

penpot-backend:
image: penpotapp/backend:latest
restart: always
depends_on:
penpot-postgres:
condition: service_healthy
penpot-redis:
condition: service_healthy
environment:

  • PENPOT_DATABASE_URI=postgresql://penpot:penpot_password@penpot-postgres:5432/penpot
  • PENPOT_DATABASE_USERNAME=penpot
  • PENPOT_DATABASE_PASSWORD=penpot_password
  • PENPOT_REDIS_URI=redis://penpot-redis:6379
  • PENPOT_SECRET_KEY=your-super-secure-secret-key-change-in-production
  • PENPOT_TELEMETRY_ENABLED=false # テレメトリを無効化し、社内プライバシーを保護

deploy:
resources:
limits:
memory: 2G # バックエンドのメモリリークや重いエクスポート処理に備える
reservations:
memory: 512M

penpot-exporter:
image: penpotapp/exporter:latest
restart: always
environment:

  • PENPOT_PUBLIC_URI=http://penpot-frontend:8080
  • PENPOT_REDIS_URI=redis://penpot-redis:6379

penpot-postgres:
image: postgres:15-alpine
restart: always
volumes:

  • penpot-postgres-data:/var/lib/postgresql/data

environment:

  • POSTGRES_DB=penpot
  • POSTGRES_USER=penpot
  • POSTGRES_PASSWORD=penpot_password

healthcheck:
test: [“CMD-SHELL”, “pg_isready -U penpot -d penpot”]
interval: 5s
timeout: 5s
retries: 5

penpot-redis:
image: redis:7-alpine
restart: always
healthcheck:
test: [“CMD”, “redis-cli”, “ping”]
interval: 5s
timeout: 3s
retries: 5

volumes:
penpot-postgres-data:

—

3. パフォーマンス改善の極意:メモリ割り当てとリバースプロキシ調整

「複数人で巨大なデザインファイル(数百のコンポーネント、複雑なネスト)を開くとブラウザがクラッシュする」「アセットのアップロードでタイムアウトする」といった課題は、インフラ層のチューニングで一発で解決できる。

A. バックエンド・JVM/Nodeのメモリ割り当て最適化

PenpotのバックエンドはClojure製(JVM上で動作)であり、大規模なSVGパースやエクスポート時に大量のヒープメモリを消費する。

  • デフォルトのままだとGC(ガベージコレクション)が頻発し、CPU使用率が跳ね上がる。
  • 上記のYAMLのように、Dockerホスト側で少なくとも 2GB以上のメモリリミット を確保し、ホストOS自体のスワップ領域(Swap)が有効になっていることを確認せよ。

B. Nginx / Caddy リバースプロキシのバッファサイズ調整

社内LANやクラウド上のK8s/VPS等でリバースプロキシ(Nginxなど)を挟む場合、大きなデザインファイルや画像のアップロード時に `413 Request Entity Too Large` や `504 Gateway Time-out` が発生する。
Nginxの場合は、必ず以下の設定を追加すること。

server {
listen 80;
server_name penpot.internal.domain;

client_max_body_size 100M; # 巨大な画像やコンポーネントライブラリのインポートに必須

location / {
proxy_pass http://localhost:8080;
proxy_http_version 1.1;

# WebSocket / SSE (Server-Sent Events) のためのタイムアウト・接続維持設定
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection “upgrade”;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;

proxy_read_timeout 600s;
proxy_send_timeout 600s;
}
}

—

4. チームの開発生産性を爆上げするプラクティス

インフラが安定したら、次は「デザインからコードへ」のフローを加速させるための実践知を注入する。

開発スピードを加速させるキーボードショートカット

Penpotはマウス操作を極力排した設計になっている。これらをチームメンバー全員に叩き込ませろ。

  • `V`: セレクトツール(要素の選択)
  • `R`: レクタングル(矩形)作成
  • `T`: テキスト入力
  • `Shift + A`: Flexbox(Auto Layout)の適用 / 解除
  • `Alt + 押下しながらホバー`: 要素間の正確なスペーシング(CSSのマージン/パディング)の計測
  • `Ctrl/Cmd + Shift + K`: コンポーネント化

組織全体でのデザインシステム共有ルール

セルフホスト環境の最大の強みは、「社内専用のプライベート・コンポーネントライブラリ」を全プロジェクトで強制共有できる点にある。
1. 「Core Design System」プロジェクトの作成: デザイナチームがボタン、入力フォーム、モーダルなどの原子(Atoms)をこのプロジェクトで一元管理する。
2. ライブラリとしての公開: セルフホストインスタンス内ですべてのチームにこのプロジェクトを「Shared Library」としてアタッチする。
3. エンジニアの参照: エンジニアはInspectモードから、自動生成されるCSSプロパティ(`display: flex; gap: 8px; border-radius: 4px;` 等)をそのままプロダクトのコードベース(Tailwind CSSやVanilla CSS)へマッピングする。デザインとコードの乖離が物理的に消滅する瞬間だ。

—

結び:ツールに振り回されるな、インフラを掌握せよ

セルフホストのPenpotは、正しく構築すればFigmaに匹敵する、いやそれ以上のプライバシーとカスタマイズ性を持った最強のコラボレーション基盤となる。
「重い」「動かない」と嘆く前に、Dockerのメモリ制限を見直し、リバースプロキシのタイムアウトを拡張し、データベースのヘルスチェックを正しく設定する。たったこれだけのエンジニアリングで、チームのデザイナーとエンジニアのワークフローは劇的に滑らかになるはずだ。

さあ、今すぐ `docker compose up -d` を叩き、真に自由なデザイン・開発エコシステムをその手で完成させよう。

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