前言

本篇文章讲解如何在Linux系统使用Docker部署一款开源的设计和原型创作平台Penpot,并结合Cpolar内网穿透软件配置公网地址,轻松实现异地远程访问本地设计平台。

Penpot是一个强大且免费的在线设计和原型工具,专为团队协作而构建。它允许设计师、开发者和产品经理在同一平台上无缝地创建、分享和迭代设计项目。基于 Web 的 PenPot 能够在任何操作系统上运行,并提供丰富的功能,帮助您提高工作效率并简化工作流程。

Penpot 使用现代化的技术栈构建,包括Web 技术、Puppeteer、Node.js、MongoDB、GraphQL API,内置矢量绘图工具,支持形状、文本、图像操作,以及自定义颜色和样式,创建交互式原型,设置页面间跳转,预览并分享给团队或客户。

本例中,我们在Linux系统使用Docker快速进行本地部署。

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图1

1. 安装Docker

本教程操作环境为Linux Ubuntu系统,在开始之前,我们需要先安装Docker与docker-compose。

在终端中执行下方命令安装docker:

  1. sudo curl -fsSL https://github.com/tech-shrimp/docker_installer/releases/download/latest/linux.sh| bash -s docker --mirror Aliyun

如果上边命令中访问不了Github,可以使用Gitee的链接:

  1. sudo curl -fsSL https://gitee.com/tech-shrimp/docker_installer/releases/download/latest/linux.sh| bash -s docker --mirror Aliyun

然后启动Docker

  1. sudo systemctl start docker

2. Docker镜像源添加方法

如因网络问题拉取不到镜像,

可尝试在终端执行 sudo nano /etc/docker/daemon.json

输入:

  1. {
  2. "registry-mirrors": [
  3. "https://do.nark.eu.org",
  4. "https://dc.j8.work",
  5. "https://docker.m.daocloud.io",
  6. "https://dockerproxy.com",
  7. "https://docker.mirrors.ustc.edu.cn",
  8. "https://docker.nju.edu.cn"
  9. ]
  10. }

保存退出

然后执行:sudo systemctl restart docker

3. 创建并启动Penpot容器

成功拉取 Penpot 镜像后,我们在Home目录下的docker路径新增该项目目录

  1. mkdir penpot
  1. cd penpot

然后在该项目中创建docker-compose.yml

  1. nano docker-compose.yml

输入下方代码并保存退出:

  1. version: "3.8"
  2. networks:
  3. penpot:
  4. volumes:
  5. penpot_postgres_v15:
  6. penpot_assets:
  7. # penpot_traefik:
  8. # penpot_minio:
  9. services:
  10. ## Traefik service declaration example. Consider using it if you are going to expose
  11. ## penpot to the internet or different host than `localhost`.
  12. # traefik:
  13. # image: traefik:v2.9
  14. # networks:
  15. # - penpot
  16. # command:
  17. # - "--api.insecure=true"
  18. # - "--entryPoints.web.address=:80"
  19. # - "--providers.docker=true"
  20. # - "--providers.docker.exposedbydefault=false"
  21. # - "--entryPoints.websecure.address=:443"
  22. # - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
  23. # - "--certificatesresolvers.letsencrypt.acme.email=<EMAIL_ADDRESS>"
  24. # - "--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json"
  25. # volumes:
  26. # - "penpot_traefik:/traefik"
  27. # - "/var/run/docker.sock:/var/run/docker.sock"
  28. # ports:
  29. # - "80:80"
  30. # - "443:443"
  31. penpot-frontend:
  32. image: "penpotapp/frontend:latest"
  33. restart: always
  34. ports:
  35. - 9001:80
  36. volumes:
  37. - penpot_assets:/opt/data/assets
  38. depends_on:
  39. - penpot-backend
  40. - penpot-exporter
  41. networks:
  42. - penpot
  43. labels:
  44. - "traefik.enable=true"
  45. ## HTTP: example of labels for the case if you are going to expose penpot to the
  46. ## internet using only HTTP (without HTTPS) with traefik
  47. # - "traefik.http.routers.penpot-http.entrypoints=web"
  48. # - "traefik.http.routers.penpot-http.rule=Host(`<DOMAIN_NAME>`)"
  49. # - "traefik.http.services.penpot-http.loadbalancer.server.port=80"
  50. ## HTTPS: example of labels for the case if you are going to expose penpot to the
  51. ## internet using with HTTPS using traefik
  52. # - "traefik.http.middlewares.http-redirect.redirectscheme.scheme=https"
  53. # - "traefik.http.middlewares.http-redirect.redirectscheme.permanent=true"
  54. # - "traefik.http.routers.penpot-http.entrypoints=web"
  55. # - "traefik.http.routers.penpot-http.rule=Host(`<DOMAIN_NAME>`)"
  56. # - "traefik.http.routers.penpot-http.middlewares=http-redirect"
  57. # - "traefik.http.routers.penpot-https.entrypoints=websecure"
  58. # - "traefik.http.routers.penpot-https.rule=Host(`<DOMAIN_NAME>`)"
  59. # - "traefik.http.services.penpot-https.loadbalancer.server.port=80"
  60. # - "traefik.http.routers.penpot-https.tls=true"
  61. # - "traefik.http.routers.penpot-https.tls.certresolver=letsencrypt"
  62. ## Configuration envronment variables for frontend the container. In this case this
  63. ## container only needs the `PENPOT_FLAGS`. This environment variable is shared with
  64. ## other services but not all flags are relevant to all services.
  65. environment:
  66. ## Relevant flags for frontend:
  67. ## - demo-users
  68. ## - login-with-github
  69. ## - login-with-gitlab
  70. ## - login-with-google
  71. ## - login-with-ldap
  72. ## - login-with-oidc
  73. ## - login-with-password
  74. ## - registration
  75. ## - webhooks
  76. ##
  77. ## You can read more about all available flags on:
  78. ## https://help.penpot.app/technical-guide/configuration/#advanced-configuration
  79. - PENPOT_FLAGS=enable-registration enable-login-with-password
  80. penpot-backend:
  81. image: "penpotapp/backend:latest"
  82. restart: always
  83. volumes:
  84. - penpot_assets:/opt/data/assets
  85. depends_on:
  86. - penpot-postgres
  87. - penpot-redis
  88. networks:
  89. - penpot
  90. ## Configuration envronment variables for backend the
  91. ## container.
  92. environment:
  93. ## Relevant flags for backend:
  94. ## - demo-users
  95. ## - email-verification
  96. ## - log-emails
  97. ## - log-invitation-tokens
  98. ## - login-with-github
  99. ## - login-with-gitlab
  100. ## - login-with-google
  101. ## - login-with-ldap
  102. ## - login-with-oidc
  103. ## - login-with-password
  104. ## - registration
  105. ## - secure-session-cookies
  106. ## - smtp
  107. ## - smtp-debug
  108. ## - telemetry
  109. ## - webhooks
  110. ## - prepl-server
  111. ##
  112. ## You can read more about all available flags and other
  113. ## environment variables for the backend here:
  114. ## https://help.penpot.app/technical-guide/configuration/#advanced-configuration
  115. - PENPOT_FLAGS=enable-registration enable-login-with-password disable-email-verification enable-smtp enable-prepl-server
  116. ## Penpot SECRET KEY. It serves as a master key from which other keys for subsystems
  117. ## (eg http sessions, or invitations) are derived.
  118. ##
  119. ## If you leve it commented, all created sessions and invitations will
  120. ## become invalid on container restart.
  121. ##
  122. ## If you going to uncomment this, we recommend use here a trully randomly generated
  123. ## 512 bits base64 encoded string. You can generate one with:
  124. ##
  125. ## python3 -c "import secrets; print(secrets.token_urlsafe(64))"
  126. # - PENPOT_SECRET_KEY=my-insecure-key
  127. ## The PREPL host. Mainly used for external programatic access to penpot backend
  128. ## (example: admin). By default it listen on `localhost` but if you are going to use
  129. ## the `admin`, you will need to uncomment this and set the host to `0.0.0.0`.
  130. # - PENPOT_PREPL_HOST=0.0.0.0
  131. ## Public URI. If you are going to expose this instance to the internet and use it
  132. ## under different domain than 'localhost', you will need to adjust it to the final
  133. ## domain.
  134. ##
  135. ## Consider using traefik and set the 'disable-secure-session-cookies' if you are
  136. ## not going to serve penpot under HTTPS.
  137. - PENPOT_PUBLIC_URI=http://localhost:9001
  138. ## Database connection parameters. Don't touch them unless you are using custom
  139. ## postgresql connection parameters.
  140. - PENPOT_DATABASE_URI=postgresql://penpot-postgres/penpot
  141. - PENPOT_DATABASE_USERNAME=penpot
  142. - PENPOT_DATABASE_PASSWORD=penpot
  143. ## Redis is used for the websockets notifications. Don't touch unless the redis
  144. ## container has different parameters or different name.
  145. - PENPOT_REDIS_URI=redis://penpot-redis/0
  146. ## Default configuration for assets storage: using filesystem based with all files
  147. ## stored in a docker volume.
  148. - PENPOT_ASSETS_STORAGE_BACKEND=assets-fs
  149. - PENPOT_STORAGE_ASSETS_FS_DIRECTORY=/opt/data/assets
  150. ## Also can be configured to to use a S3 compatible storage
  151. ## service like MiniIO. Look below for minio service setup.
  152. # - AWS_ACCESS_KEY_ID=<KEY_ID>
  153. # - AWS_SECRET_ACCESS_KEY=<ACCESS_KEY>
  154. # - PENPOT_ASSETS_STORAGE_BACKEND=assets-s3
  155. # - PENPOT_STORAGE_ASSETS_S3_ENDPOINT=http://penpot-minio:9000
  156. # - PENPOT_STORAGE_ASSETS_S3_BUCKET=<BUKET_NAME>
  157. ## Telemetry. When enabled, a periodical process will send anonymous data about this
  158. ## instance. Telemetry data will enable us to learn on how the application is used,
  159. ## based on real scenarios. If you want to help us, please leave it enabled. You can
  160. ## audit what data we send with the code available on github
  161. - PENPOT_TELEMETRY_ENABLED=true
  162. ## Example SMTP/Email configuration. By default, emails are sent to the mailcatch
  163. ## service, but for production usage is recommended to setup a real SMTP
  164. ## provider. Emails are used to confirm user registrations & invitations. Look below
  165. ## how mailcatch service is configured.
  166. - PENPOT_SMTP_DEFAULT_FROM=no-reply@example.com
  167. - PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
  168. - PENPOT_SMTP_HOST=penpot-mailcatch
  169. - PENPOT_SMTP_PORT=1025
  170. - PENPOT_SMTP_USERNAME=
  171. - PENPOT_SMTP_PASSWORD=
  172. - PENPOT_SMTP_TLS=false
  173. - PENPOT_SMTP_SSL=false
  174. penpot-exporter:
  175. image: "penpotapp/exporter:latest"
  176. restart: always
  177. networks:
  178. - penpot
  179. environment:
  180. # Don't touch it; this uses internal docker network to
  181. # communicate with the frontend.
  182. - PENPOT_PUBLIC_URI=http://penpot-frontend
  183. ## Redis is used for the websockets notifications.
  184. - PENPOT_REDIS_URI=redis://penpot-redis/0
  185. penpot-postgres:
  186. image: "postgres:15"
  187. restart: always
  188. stop_signal: SIGINT
  189. volumes:
  190. - penpot_postgres_v15:/var/lib/postgresql/data
  191. networks:
  192. - penpot
  193. environment:
  194. - POSTGRES_INITDB_ARGS=--data-checksums
  195. - POSTGRES_DB=penpot
  196. - POSTGRES_USER=penpot
  197. - POSTGRES_PASSWORD=penpot
  198. penpot-redis:
  199. image: redis:7
  200. restart: always
  201. networks:
  202. - penpot
  203. ## A mailcatch service, used as temporal SMTP server. You can access via HTTP to the
  204. ## port 1080 for read all emails the penpot platform has sent. Should be only used as a
  205. ## temporal solution meanwhile you don't have a real SMTP provider configured.
  206. penpot-mailcatch:
  207. image: sj26/mailcatcher:latest
  208. restart: always
  209. expose:
  210. - '1025'
  211. ports:
  212. - "1080:1080"
  213. networks:
  214. - penpot
  215. ## Example configuration of MiniIO (S3 compatible object storage service); If you don't
  216. ## have preference, then just use filesystem, this is here just for the completeness.
  217. # minio:
  218. # image: "minio/minio:latest"
  219. # command: minio server /mnt/data --console-address ":9001"
  220. # restart: always
  221. #
  222. # volumes:
  223. # - "penpot_minio:/mnt/data"
  224. #
  225. # environment:
  226. # - MINIO_ROOT_USER=minioadmin
  227. # - MINIO_ROOT_PASSWORD=minioadmin
  228. #
  229. # ports:
  230. # - 9000:9000
  231. # - 9001:9001

然后执行下方命令启动容器运行镜像:

  1. sudo docker compose up -d

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图2 开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图3 如需停止可以执行:

  1. sudo docker compose down

3. 本地使用Penpot进行创作

接下来我们就可以通过任意浏览器进行访问测试,打开一个浏览器输入localhost:9001,可以看到进入到了Penpot的登录界面,注册一个用户名和密码。

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图4

选择使用用途

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图5

然后进入到设计界面,可以自由创作了!

画板跟同类设计软件的画布功能差不多,并具有固定的边缘。你可以根据你的需要,选择一个特定的屏幕或打印用的尺寸。

  1. 创建画板:点击工具栏中 “移动” 箭头正下方的第一个方形图标。点击并拖动箭头来创建一个自定义尺寸的画板。你也可以在 “设计属性” 边栏选择包揽设备最常用分辨率和标准打印尺寸的预设模板。
  2. 选择和移动画板:点击画板的名称或没有图层的区域。当边框变成绿色时,代表着你选择成功了。一旦选择了,按住 “Shift” 键,然后点击并拖动画板来移动它。
  3. 设置画板为缩略图:选择一个画板并点击右键。在菜单上,选择 “设置为缩略图”。选定的画板将作为文件缩略图显示在仪表板的卡片上。

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图6

目前我们在本机部署了 Penpot ,如果想团队协作多人使用,或者在异地其他设备使用的话就需要结合Cpolar内网穿透实现公网访问,免去了复杂得本地部署过程,只需要一个公网地址直接就可以进入到Penpot中。

接下来教大家如何安装Cpolar并且将 Penpot 实现公网访问。

4. 公网远程访问本地Penpot

4.1 内网穿透工具安装

下面是安装cpolar步骤:

Cpolar官网地址: https://www.cpolar.com

使用一键脚本安装命令

  1. curl https://get.cpolar.sh | sudo sh

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图7

安装完成后,执行下方命令查看cpolar服务状态:(如图所示即为正常启动)

  1. sudo systemctl status cpolar

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图8

Cpolar安装和成功启动服务后,在浏览器上输入ubuntu主机IP加9200端口即:【http://localhost:9200】访问Cpolar管理界面,使用Cpolar官网注册的账号登录,登录后即可看到cpolar web 配置界面,接下来在web 界面配置即可:

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图9

4.2 创建远程连接公网地址

登录cpolar web UI管理界面后,点击左侧仪表盘的隧道管理——创建隧道:

  • 隧道名称:可自定义,本例使用了: Penpot 注意不要与已有的隧道名称重复
  • 协议:http
  • 本地地址:9001
  • 域名类型:随机域名
  • 地区:选择China Top

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图10

创建成功后,打开左侧在线隧道列表,可以看到刚刚通过创建隧道生成了两个公网地址,接下来就可以在其他电脑(异地)上,使用任意一个地址在浏览器中访问即可。

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图11

如下图所示,成功实现使用公网地址异地远程访问本地部署的Penpot设计创作平台!

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图12

小结

为了方便演示,我们在上边的操作过程中使用了cpolar生成的HTTP公网地址隧道,其公网地址是随机生成的。

这种随机地址的优势在于建立速度快,可以立即使用。然而,它的缺点是网址是随机生成,这个地址在24小时内会发生随机变化,更适合于临时使用。

如果有长期远程访问本地 Penpot设计创作平台或者其他本地部署的服务的需求,但又不想每天重新配置公网地址,还想地址好看又好记,那我推荐大家选择使用固定的二级子域名方式来远程访问。

5. 固定Penpot公网地址

由于以上使用cpolar所创建的隧道使用的是随机公网地址,24小时内会随机变化,不利于长期远程访问。因此我们可以为其配置二级子域名,该地址为固定地址,不会随机变化【ps:cpolar.cn已备案】

注意需要将cpolar套餐升级至基础套餐或以上,且每个套餐对应的带宽不一样。【cpolar.cn已备案】

登录cpolar官网,点击左侧的预留,选择保留二级子域名,地区选择china vip top,然后设置一个二级子域名名称,填写备注信息,点击保留。

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图13

保留成功后复制保留的二级子域名地址:

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图14

登录cpolar web UI管理界面,点击左侧仪表盘的隧道管理——隧道列表,找到所要配置的隧道,点击右侧的编辑

修改隧道信息,将保留成功的二级子域名配置到隧道中

  • 域名类型:选择二级子域名
  • Sub Domain:填写保留成功的二级子域名
  • 地区: China VIP

点击更新

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图15

更新完成后,打开在线隧道列表,此时可以看到随机的公网地址已经发生变化,地址名称也变成了保留和固定的二级子域名名称。

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图16

最后,我们使用固定的公网地址访问 Penpot 界面可以看到访问成功,一个永久不会变化的远程访问方式即设置好了。

开源设计和原型创作平台Penpot本地docker部署与远程在线协作 - 图17

接下来就可以随时随地进行异地公网来使用Penpot创作平台了,把固定的公网地址分享给身边的人,方便团队协作,同时也大大提高了工作效率!自己用的话,无需云服务器,还可以实现异地其他设备登录!以上就是如何在本地安装Penpot的全部过程。