Penpot 私有化部署:从容器启动到生产加固的完整 Docker 部署路径
【免费下载链接】penpotPenpot: The open-source design platform for Product teams that need scalable collaboration.项目地址: https://gitcode.com/GitHub_Trending/pe/penpot
团队想把设计文件放到自己的服务器上,Penpot 私有化部署要做的并不复杂:用 docker compose 拉起 6 个容器,改几个环境变量。
照本文操作,你大约 30 分钟内能拿到一个可对外服务的 Penpot 实例:密钥已替换、真实邮件可用、HTTPS 就绪,并留下一套日常备份和升级命令。
🧩 Penpot 私有化部署能解决什么
- 自托管设计协作:设计文件与团队数据存在自己的服务器
- 设计转代码:画布上直接查看 CSS 与 SVG 代码
- 自动化集成:Webhooks 与访问令牌支持导出、对接
- 多种认证方式:邮箱密码、Google、GitHub、LDAP、OIDC
⏱️ 五分钟跑通最小可用环境
环境要求:
- Docker 20.10+ 与 Compose v2
- 内存 4GB 起步,推荐 8GB
- 磁盘空闲 10GB 以上
- 端口 9001 可被你的代理或浏览器访问
把 compose 文件放到仓库外的目录运行,仓库本身保持只读:
git clone https://gitcode.com/GitHub_Trending/pe/penpot # 只为取 docker-compose.yaml mkdir -p ~/penpot-run cp penpot/docker/images/docker-compose.yaml ~/penpot-run/ # 拷到工作目录,不动仓库 cd ~/penpot-run PENPOT_VERSION=2.16 docker compose -p penpot up -d # 锁定版本启动,省略则用 latest默认配置已开启disable-email-verification,打开http://localhost:9001注册即可登录。各服务端口与完整说明见 docs/technical-guide/getting-started/docker.md。
⚙️ 按需配置
替换默认主密钥并设置公网地址
compose 文件里的PENPOT_SECRET_KEY默认值是公开示例,会话和邀请密钥都由它派生,不替换则每次重启后全员掉线。PENPOT_PUBLIC_URI决定前端生成的资源路径与邮件链接,对外服务必须填真实域名。
先生成一个随机串,再填回文件顶部的两处锚点定义:
python3 -c "import secrets; print(secrets.token_urlsafe(64))" # 生成 512 位密钥x-secret-key: &penpot-secret-key PENPOT_SECRET_KEY: <上一步输出的随机串> x-uri: &penpot-public-uri PENPOT_PUBLIC_URI: https://penpot.example.com # ...其余服务段省略,锚点已自动注入各服务...资产存储切换到 S3
默认fs后端把图片与素材存进penpot_assets卷,单节点够用;一旦前端多副本或要异地容灾,就必须换成对象存储,否则各节点资产不一致。
environment: PENPOT_OBJECTS_STORAGE_BACKEND: s3 PENPOT_OBJECTS_STORAGE_S3_ENDPOINT: https://s3.your-provider.com PENPOT_OBJECTS_STORAGE_S3_BUCKET: penpot-assets AWS_ACCESS_KEY_ID: <key-id> AWS_SECRET_ACCESS_KEY: <secret> # ...其余省略...配置真实 SMTP 邮件发送
注册验证和团队邀请都靠邮件。默认 compose 指向 mailcatch 容器,邮件只落在本地网页上,对外服务必须换成真实 SMTP 服务,并去掉disable-email-verification。
PENPOT_FLAGS: enable-smtp enable-prepl-server enable-mcp PENPOT_SMTP_HOST: smtp.your-provider.com PENPOT_SMTP_PORT: 587 PENPOT_SMTP_USERNAME: <账号> PENPOT_SMTP_PASSWORD: <密码> PENPOT_SMTP_TLS: "true" # ...其余省略...第三方登录同理:在PENPOT_FLAGS加enable-login-with-google,backend 段填PENPOT_GOOGLE_CLIENT_ID和PENPOT_GOOGLE_CLIENT_SECRET。团队级自动化用 Webhook,在团队设置页添加回调地址:
访问令牌用于脚本化操作,个人设置页生成即可:
设置 HTTPS 反向代理
浏览器剪贴板等 API 在非 HTTPS 环境直接不可用,对外域名必须上 TLS,同时代理要转发两条 WebSocket 路径。
把下面配置放进你的 nginx,证书路径按实际填写:
server { listen 443 ssl; server_name penpot.example.com; client_max_body_size 350M; # 与 PENPOT_HTTP_SERVER_MAX_BODY_SIZE 保持一致 ssl_certificate /path/to/fullchain.pem; ssl_certificate_key /path/to/privkey.pem; location /ws/notifications { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_pass http://localhost:9001/ws/notifications; } location /mcp/ws { proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_pass http://localhost:9001/mcp/ws; } location / { proxy_set_header Host $http_host; proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://localhost:9001/; # ...其余省略... } }🛡️ 上线前加固清单
| 检查项 | 操作要点 |
|---|---|
| HTTPS | 证书 + 反向代理到 9001,非 localhost 域名不用 HTTP |
| 主密钥 | PENPOT_SECRET_KEY换成本文生成的随机串 |
| 默认 flags | 从PENPOT_FLAGS移除disable-email-verification、disable-secure-session-cookies |
| 数据库密码 | 改POSTGRES_PASSWORD,并同步PENPOT_DATABASE_PASSWORD |
| 注册范围 | 加PENPOT_REGISTRATION_DOMAIN_WHITELIST限定可注册域名 |
| 密码存放 | SMTP 密码、OAuth 密钥放.env引用,不写明文进 compose |
🔄 日常运维
备份:数据库一条命令导出,用户上传的素材另存于penpot_assets卷,用docker volume ls | grep penpot确认名称后同样归档,两者都要保留:
docker compose -p penpot exec penpot-postgres pg_dump -U penpot penpot > penpot-db-$(date +%F).sql # 导出数据库升级:官方建议小步升级,不跨大版本。
- 执行上面的备份命令
PENPOT_VERSION=<新版本> docker compose -p penpot pulldocker compose -p penpot downPENPOT_VERSION=<新版本> docker compose -p penpot up -ddocker compose -p penpot ps确认全部 healthy,并翻看 backend 日志
监控:盯四个指标就够——容器重启次数、Postgres 磁盘用量与慢查询、Valkey 内存(默认上限 128MB)、HTTP 5xx 比例。
🐛 常见卡点
- backend 容器反复重启→
docker compose -p penpot logs penpot-postgres→ Postgres 未通过健康检查,backend 会一直等待 - 前端打开是空白页→
docker compose -p penpot ps→ 容器未就绪,或PENPOT_PUBLIC_URI与实际访问域名不一致导致资源路径错误 - 邀请邮件一直收不到→
docker compose -p penpot logs penpot-backend | grep -i smtp→ 仍指向 mailcatch 容器,只本地收信不真正外发 - 大文件上传中断→
nginx -T | grep client_max_body_size→ 代理层的上传上限小于 compose 中的 367001600(约 350MB)
📌 写在最后
部署完成只是开始,密钥轮换和备份是长期任务。全部配置项查 docs/technical-guide/configuration.md,升级前先看 CHANGES.md 的版本说明。
【免费下载链接】penpotPenpot: The open-source design platform for Product teams that need scalable collaboration.项目地址: https://gitcode.com/GitHub_Trending/pe/penpot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考