mirror of
https://github.com/penpot/penpot.git
synced 2026-01-16 18:29:54 -05:00
Compare commits
39 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fe04f3e45d | ||
|
|
363c1d5b56 | ||
|
|
3ee3df9b24 | ||
|
|
332657bd1b | ||
|
|
953f770fdd | ||
|
|
c83b9ea305 | ||
|
|
3007aa19a2 | ||
|
|
e20adda766 | ||
|
|
3d9fda7a21 | ||
|
|
7a5dea5cfe | ||
|
|
b47df2c230 | ||
|
|
b8b3cc641a | ||
|
|
09ff7372da | ||
|
|
f45fa95935 | ||
|
|
ce02cbc3f1 | ||
|
|
b386403fa8 | ||
|
|
0a6e884584 | ||
|
|
06f6a49bce | ||
|
|
afd309c62b | ||
|
|
214a89e20d | ||
|
|
e64cf9f283 | ||
|
|
3a34c51e43 | ||
|
|
0ff9c44246 | ||
|
|
5bfab454f5 | ||
|
|
5ebde405ea | ||
|
|
531b002a5c | ||
|
|
3eae3178a2 | ||
|
|
2cf3e37b7a | ||
|
|
e0b9751b16 | ||
|
|
ccea9b1564 | ||
|
|
5fcf889d3c | ||
|
|
7247db14b2 | ||
|
|
658e5dce22 | ||
|
|
f27cbfa0ec | ||
|
|
5754c393b9 | ||
|
|
c618efc29e | ||
|
|
3685f7b32b | ||
|
|
06b5304926 | ||
|
|
91efcd17a2 |
48
CHANGES.md
48
CHANGES.md
@@ -1,6 +1,52 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 2.5.0 (Unreleased)
|
||||
## 2.5.3
|
||||
|
||||
### :rocket: Epics and highlights
|
||||
|
||||
### :boom: Breaking changes & Deprecations
|
||||
|
||||
### :heart: Community contributions (Thank you!)
|
||||
|
||||
### :sparkles: New features
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Component sync issues with multiple tabs [Taiga #10471](https://tree.taiga.io/project/penpot/issue/10471)
|
||||
|
||||
## 2.5.2
|
||||
|
||||
### :rocket: Epics and highlights
|
||||
|
||||
### :boom: Breaking changes & Deprecations
|
||||
|
||||
### :heart: Community contributions (Thank you!)
|
||||
|
||||
### :sparkles: New features
|
||||
- When the workspace is empty, set default the board creation tool [Taiga #9425](https://tree.taiga.io/project/penpot/us/9425)
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Fix scroll on storybook docs [taiga #9962](https://tree.taiga.io/project/penpot/issue/9962)
|
||||
- Navigate tracking event firing multiple times [Taiga #10415](https://tree.taiga.io/project/penpot/issue/10415)
|
||||
- Fix problem with selection colors [Taiga #10376](https://tree.taiga.io/project/penpot/issue/10376)
|
||||
- Fix scroll on storybook icons list [taiga #9962](https://tree.taiga.io/project/penpot/issue/9962)
|
||||
|
||||
## 2.5.1
|
||||
|
||||
### :rocket: Epics and highlights
|
||||
|
||||
### :boom: Breaking changes & Deprecations
|
||||
|
||||
### :heart: Community contributions (Thank you!)
|
||||
|
||||
### :sparkles: New features
|
||||
|
||||
- Improve Nginx entryponit to get the resolvers dinamically by default
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
## 2.5.0
|
||||
|
||||
### :rocket: Epics and highlights
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
(let [data (::file-data (meta changes))]
|
||||
(dm/get-in data [:pages-index uuid/zero :objects])))
|
||||
|
||||
(defn- apply-changes-local
|
||||
(defn apply-changes-local
|
||||
[changes]
|
||||
(dm/assert!
|
||||
"expected valid changes"
|
||||
|
||||
@@ -747,42 +747,35 @@
|
||||
(let [omit-touched? (not reset?)
|
||||
clear-remote-synced? (and initial-root? reset?)
|
||||
set-remote-synced? (and (not initial-root?) reset?)
|
||||
changes (cond-> changes
|
||||
:always
|
||||
(update-attrs shape-inst
|
||||
shape-main
|
||||
root-inst
|
||||
root-main
|
||||
container
|
||||
omit-touched?)
|
||||
changes
|
||||
(cond-> changes
|
||||
:always
|
||||
(update-attrs shape-inst
|
||||
shape-main
|
||||
root-inst
|
||||
root-main
|
||||
container
|
||||
omit-touched?)
|
||||
|
||||
(ctl/flex-layout? shape-main)
|
||||
(update-flex-child-copy-attrs shape-main
|
||||
shape-inst
|
||||
library
|
||||
component
|
||||
container
|
||||
omit-touched?)
|
||||
(ctl/flex-layout? shape-main)
|
||||
(update-flex-child-copy-attrs shape-main
|
||||
shape-inst
|
||||
library
|
||||
component
|
||||
container
|
||||
omit-touched?)
|
||||
|
||||
(ctl/grid-layout? shape-main)
|
||||
(update-grid-copy-attrs shape-main
|
||||
shape-inst
|
||||
library
|
||||
component
|
||||
container
|
||||
omit-touched?)
|
||||
reset?
|
||||
(change-touched shape-inst
|
||||
shape-main
|
||||
container
|
||||
{:reset-touched? true})
|
||||
|
||||
reset?
|
||||
(change-touched shape-inst
|
||||
shape-main
|
||||
container
|
||||
{:reset-touched? true})
|
||||
clear-remote-synced?
|
||||
(change-remote-synced shape-inst container nil)
|
||||
|
||||
clear-remote-synced?
|
||||
(change-remote-synced shape-inst container nil)
|
||||
|
||||
set-remote-synced?
|
||||
(change-remote-synced shape-inst container true))
|
||||
set-remote-synced?
|
||||
(change-remote-synced shape-inst container true))
|
||||
|
||||
component-container (find-main-container container shape-inst shape-main library component)
|
||||
|
||||
@@ -859,23 +852,36 @@
|
||||
(d/index-of children-inst child-inst)
|
||||
(d/index-of children-main child-main)
|
||||
container
|
||||
omit-touched?))]
|
||||
omit-touched?))
|
||||
|
||||
(compare-children changes
|
||||
children-inst
|
||||
children-main
|
||||
container
|
||||
component-container
|
||||
file
|
||||
libraries
|
||||
only-inst
|
||||
only-main
|
||||
both
|
||||
swapped
|
||||
moved
|
||||
false
|
||||
reset?
|
||||
components-v2))))
|
||||
changes
|
||||
(compare-children changes
|
||||
children-inst
|
||||
children-main
|
||||
container
|
||||
component-container
|
||||
file
|
||||
libraries
|
||||
only-inst
|
||||
only-main
|
||||
both
|
||||
swapped
|
||||
moved
|
||||
false
|
||||
reset?
|
||||
components-v2)
|
||||
|
||||
changes
|
||||
(cond-> changes
|
||||
(ctl/grid-layout? shape-inst)
|
||||
(update-grid-copy-attrs
|
||||
(:id shape-inst)
|
||||
shape-main
|
||||
library
|
||||
component
|
||||
omit-touched?))]
|
||||
|
||||
changes)))
|
||||
|
||||
(defn generate-rename-component
|
||||
"Generate the changes for rename the component with the given id, in the current file library."
|
||||
@@ -1710,30 +1716,36 @@
|
||||
|
||||
(defn- update-grid-copy-attrs
|
||||
"Synchronizes the `layout-grid-cells` property from the main shape to the copies"
|
||||
[changes shape-main shape-copy main-container main-component copy-container omit-touched?]
|
||||
(let [ids-map
|
||||
(into {}
|
||||
(comp
|
||||
(map #(dm/get-in copy-container [:objects %]))
|
||||
(keep
|
||||
(fn [copy-shape]
|
||||
(let [main-shape (ctf/get-ref-shape main-container main-component copy-shape)]
|
||||
[(:id main-shape) (:id copy-shape)]))))
|
||||
(:shapes shape-copy))
|
||||
[changes shape-copy-id shape-main main-container main-component omit-touched?]
|
||||
(-> changes
|
||||
(pcb/apply-changes-local)
|
||||
(pcb/update-shapes
|
||||
[shape-copy-id]
|
||||
(fn [shape-copy objects]
|
||||
(let [ids-map
|
||||
(into {}
|
||||
(comp
|
||||
(map #(get objects %))
|
||||
(keep
|
||||
(fn [copy-shape]
|
||||
(let [main-shape (ctf/get-ref-shape main-container main-component copy-shape)]
|
||||
[(:id main-shape) (:id copy-shape)]))))
|
||||
(:shapes shape-copy))
|
||||
|
||||
new-changes
|
||||
(-> (pcb/empty-changes)
|
||||
(pcb/with-container copy-container)
|
||||
(pcb/with-objects (:objects copy-container))
|
||||
(pcb/update-shapes
|
||||
[(:id shape-copy)]
|
||||
(fn [shape-copy]
|
||||
remove-orphan-cells
|
||||
(fn [cells {:keys [shapes]}]
|
||||
(let [child? (set shapes)]
|
||||
(-> cells
|
||||
(update-vals
|
||||
(fn [cell]
|
||||
(update cell :shapes #(filterv child? %)))))))
|
||||
;; Take cells from main and remap the shapes to assign it to the copy
|
||||
(let [copy-cells (:layout-grid-cells shape-copy)
|
||||
main-cells (-> (ctl/remap-grid-cells shape-main ids-map) :layout-grid-cells)]
|
||||
(assoc shape-copy :layout-grid-cells (ctl/merge-cells copy-cells main-cells omit-touched?))))
|
||||
{:ignore-touched true}))]
|
||||
(pcb/concat-changes changes new-changes)))
|
||||
copy-cells (-> shape-copy :layout-grid-cells (remove-orphan-cells shape-copy))
|
||||
main-cells (-> shape-main (ctl/remap-grid-cells ids-map) :layout-grid-cells)]
|
||||
(-> shape-copy
|
||||
(assoc :layout-grid-cells
|
||||
(ctl/merge-cells copy-cells main-cells omit-touched?)))))
|
||||
{:ignore-touched true :with-objects? true})))
|
||||
|
||||
(defn- update-grid-main-attrs
|
||||
"Synchronizes the `layout-grid-cells` property from the copy to the main shape"
|
||||
|
||||
@@ -1642,11 +1642,16 @@
|
||||
"Given target cells update with source cells while trying to keep target as
|
||||
untouched as possible"
|
||||
[target-cells source-cells omit-touched?]
|
||||
(if (not omit-touched?)
|
||||
source-cells
|
||||
|
||||
(if omit-touched?
|
||||
(letfn [(get-data [cells id]
|
||||
(dissoc (get cells id) :shapes :row :column :row-span :column-span))]
|
||||
(dissoc (get cells id) :row :column :row-span :column-span))
|
||||
|
||||
(merge-cells [source-cell target-cell]
|
||||
(-> source-cell
|
||||
(d/patch-object
|
||||
(dissoc target-cell :shapes :row :column :row-span :column-span))
|
||||
(cond-> (d/not-empty? (:shapes target-cell))
|
||||
(assoc :shapes (:shapes target-cell)))))]
|
||||
(let [deleted-cells
|
||||
(into #{}
|
||||
(filter #(not (contains? source-cells %)))
|
||||
@@ -1664,5 +1669,6 @@
|
||||
(reduce
|
||||
(fn [cells id]
|
||||
(-> cells
|
||||
(d/update-when id d/patch-object (get-data target-cells id))))
|
||||
source-cells))))))
|
||||
(d/update-when id merge-cells (get target-cells id))))
|
||||
source-cells))))
|
||||
source-cells))
|
||||
|
||||
@@ -11,6 +11,7 @@ RUN set -ex; \
|
||||
ADD ./bundle-frontend/ /var/www/app/
|
||||
ADD ./files/config.js /var/www/app/js/config.js
|
||||
ADD ./files/nginx.conf /etc/nginx/nginx.conf.template
|
||||
ADD ./files/resolvers.conf /etc/nginx/overrides.d/resolvers.conf.template
|
||||
ADD ./files/nginx-mime.types /etc/nginx/mime.types
|
||||
ADD ./files/nginx-entrypoint.sh /entrypoint.sh
|
||||
|
||||
|
||||
@@ -21,10 +21,14 @@ update_flags /var/www/app/js/config.js
|
||||
|
||||
export PENPOT_BACKEND_URI=${PENPOT_BACKEND_URI:-http://penpot-backend:6060};
|
||||
export PENPOT_EXPORTER_URI=${PENPOT_EXPORTER_URI:-http://penpot-exporter:6061};
|
||||
export PENPOT_INTERNAL_RESOLVER=${PENPOT_INTERNAL_RESOLVER:-127.0.0.11};
|
||||
PENPOT_DEFAULT_INTERNAL_RESOLVER="$(awk 'BEGIN{ORS=" "} $1=="nameserver" { sub(/%.*$/,"",$2); print ($2 ~ ":")? "["$2"]": $2}' /etc/resolv.conf)";
|
||||
export PENPOT_INTERNAL_RESOLVER=${PENPOT_INTERNAL_RESOLVER:-$PENPOT_DEFAULT_INTERNAL_RESOLVER};
|
||||
export PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE=${PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE:-367001600}; # Default to 350MiB
|
||||
|
||||
envsubst "\$PENPOT_BACKEND_URI,\$PENPOT_EXPORTER_URI,\$PENPOT_INTERNAL_RESOLVER,\$PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE" \
|
||||
< /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf
|
||||
envsubst "\$PENPOT_BACKEND_URI,\$PENPOT_EXPORTER_URI,\$PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE" \
|
||||
< /etc/nginx/nginx.conf.template > /etc/nginx/nginx.conf;
|
||||
|
||||
envsubst "\$PENPOT_INTERNAL_RESOLVER" \
|
||||
< /etc/nginx/overrides.d/resolvers.conf.template > /etc/nginx/overrides.d/resolvers.conf;
|
||||
|
||||
exec "$@";
|
||||
|
||||
@@ -46,7 +46,6 @@ http {
|
||||
proxy_buffer_size 16k;
|
||||
proxy_busy_buffers_size 24k; # essentially, proxy_buffer_size + 2 small buffers of 4k
|
||||
proxy_buffers 32 4k;
|
||||
resolver $PENPOT_INTERNAL_RESOLVER ipv6=off;
|
||||
|
||||
map $http_upgrade $connection_upgrade {
|
||||
default upgrade;
|
||||
|
||||
1
docker/images/files/resolvers.conf
Normal file
1
docker/images/files/resolvers.conf
Normal file
@@ -0,0 +1 @@
|
||||
resolver $PENPOT_INTERNAL_RESOLVER ipv6=off valid=10s;
|
||||
@@ -12,7 +12,7 @@ templateClass: tmpl-contributing-guide
|
||||
{{ show_children(child) }}
|
||||
{%- endif -%}
|
||||
{%- if child.url == page.url -%}
|
||||
{{ content | toc(tags=['h2', 'h3']) | safe }}
|
||||
{{ content | toc(tags=['h2', 'h3']) | stripHash | safe }}
|
||||
{%- endif -%}
|
||||
</li>
|
||||
{%- if loop.last -%}</ul>{%- endif -%}
|
||||
|
||||
@@ -12,7 +12,7 @@ templateClass: tmpl-user-guide
|
||||
{{ show_children(child) }}
|
||||
{%- endif -%}
|
||||
{%- if child.url == page.url -%}
|
||||
{{ content | toc(tags=['h2', 'h3']) | safe }}
|
||||
{{ content | toc(tags=['h2', 'h3']) | stripHash | safe }}
|
||||
{%- endif -%}
|
||||
</li>
|
||||
{%- if loop.last -%}</ul>{%- endif -%}
|
||||
|
||||
BIN
docs/img/interface/youraccount-notifications.webp
Normal file
BIN
docs/img/interface/youraccount-notifications.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
BIN
docs/img/interface/youraccount-password.webp
Normal file
BIN
docs/img/interface/youraccount-password.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
docs/img/interface/youraccount-profile.webp
Normal file
BIN
docs/img/interface/youraccount-profile.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 13 KiB |
BIN
docs/img/interface/youraccount-settings.webp
Normal file
BIN
docs/img/interface/youraccount-settings.webp
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 10 KiB |
@@ -1,488 +0,0 @@
|
||||
---
|
||||
title: 1. Self-hosting Guide
|
||||
---
|
||||
|
||||
# Self-hosting Guide
|
||||
|
||||
This guide explains how to get your own Penpot instance, running on a machine you control,
|
||||
to test it, use it by you or your team, or even customize and extend it any way you like.
|
||||
|
||||
If you need more context you can look at the <a
|
||||
href="https://community.penpot.app/t/self-hosting-penpot-i/2336" target="_blank">post
|
||||
about self-hosting</a> in Penpot community.
|
||||
|
||||
**There is absolutely no difference between <a
|
||||
href="https://design.penpot.app">our SaaS offer</a> for Penpot and your
|
||||
self-hosted Penpot platform!**
|
||||
|
||||
There are three main options for creating a Penpot instance:
|
||||
|
||||
1. Using the platform of our partner <a href="https://elest.io/open-source/penpot" target="_blank">Elestio</a>.
|
||||
2. Using <a href="https://docker.com" target="_blank">Docker</a> tool.
|
||||
3. Using <a href="https://kubernetes.io/" target="_blank">Kubernetes</a>.
|
||||
|
||||
<p class="advice">
|
||||
The recommended way is to use Elestio, since it's simpler, fully automatic and still greatly flexible.
|
||||
Use Docker if you already know the tool, if need full control of the process or have extra requirements
|
||||
and do not want to depend on any external provider, or need to do any special customization.
|
||||
</p>
|
||||
|
||||
Or you can try <a href="#unofficial-self-host-options">other options</a>,
|
||||
offered by Penpot community.
|
||||
|
||||
## Recommended settings
|
||||
To self-host Penpot, you’ll need a server with the following specifications:
|
||||
|
||||
* **CPU:** 1-2 CPUs
|
||||
* **RAM:** 4 GiB of RAM
|
||||
* **Disk Space:** Disk requirements depend on your usage. Disk usage primarily involves the database and any files uploaded by users.
|
||||
|
||||
This setup should be sufficient for a smooth experience with typical usage (your mileage may vary).
|
||||
|
||||
## Install with Elestio
|
||||
|
||||
This section explains how to get Penpot up and running using <a href="https://elest.io/open-source/penpot"
|
||||
target="_blank">Elestio</a>.
|
||||
|
||||
This platform offers a fully managed service for on-premise instances of a selection of
|
||||
open-source software! This means you can deploy a dedicated instance of Penpot in just 3
|
||||
minutes. You’ll be relieved of the need to worry about DNS configuration, SMTP, backups,
|
||||
SSL certificates, OS & Penpot upgrades, and much more.
|
||||
|
||||
It uses the same Docker configuration as the other installation option, below, so all
|
||||
customization options are the same.
|
||||
|
||||
### Get an Elestio account
|
||||
|
||||
<p class="advice">
|
||||
Skip this section if you already have an Elestio account.
|
||||
</p>
|
||||
|
||||
To create your Elestio account <a href="https://dash.elest.io/deploy?soft=Penpot&id=121"
|
||||
target="_blank">click here</a>. You can choose to deploy on any one of five leading cloud
|
||||
providers or on-premise.
|
||||
|
||||
### Deploy Penpot using Elestio
|
||||
|
||||
Now you can Create your service in “Services”:
|
||||
1. Look for Penpot.
|
||||
2. Select a Service Cloud Provider.
|
||||
3. Select Service Cloud Region.
|
||||
4. Select Service Plan (for a team of 20 you should be fine with 2GB RAM).
|
||||
5. Select Elestio Service Support.
|
||||
6. Provide Service Name (this will show in the URL of your instance) & Admin email (used
|
||||
to create the admin account).
|
||||
7. Select Advanced Configuration options (you can also do this later).
|
||||
8. Hit “Create Service” on the bottom right.
|
||||
|
||||
It will take a couple of minutes to get the instance launched. When the status turns to
|
||||
“Service is running” you are ready to get started.
|
||||
|
||||
By clicking on the Service you go to all the details and configuration options.
|
||||
|
||||
In Network/CNAME you can find the URL of your instance. Copy and paste this into a browser
|
||||
and start using Penpot.
|
||||
|
||||
### Configure Penpot with Elestio
|
||||
|
||||
If you want to make changes to your Penpot setup click on the “Update config” button in
|
||||
Software. Here you can see the “Docker compose” used to create the instance. In “ENV” top
|
||||
middle left you can make configuration changes that will be reflected in the Docker
|
||||
compose.
|
||||
|
||||
In this file, a “#” at the start of the line means it is text and not considered part of
|
||||
the configuration. This means you will need to delete it to get some of the configuration
|
||||
options to work. Once you made all your changes hit “Update & restart”. After a couple of
|
||||
minutes, your changes will be active.
|
||||
|
||||
You can find all configuration options in the [Configuration][1] section.
|
||||
|
||||
Get in contact with us through <a href="mailto:support@penpot.app">support@penpot.app</a>
|
||||
if you have any questions or need help.
|
||||
|
||||
|
||||
### Update Penpot
|
||||
|
||||
Elestio will update your instance automatically to the latest release unless you don't
|
||||
want this. In that case you need to “Disable auto updates” in Software auto updates.
|
||||
|
||||
|
||||
## Install with Docker
|
||||
|
||||
This section details everything you need to know to get Penpot up and running in
|
||||
production environments using Docker. For this, we provide a series of *Dockerfiles* and a
|
||||
*docker-compose* file that orchestrate all.
|
||||
|
||||
### Install Docker
|
||||
|
||||
<p class="advice">
|
||||
Skip this section if you already have docker installed, up and running.
|
||||
</p>
|
||||
|
||||
Currently, Docker comes into two different flavours:
|
||||
|
||||
#### Docker Desktop
|
||||
|
||||
This is the only option to have Docker in a Windows or MacOS. Recently it's also available
|
||||
for Linux, in the most popular distributions (Debian, Ubuntu and Fedora).
|
||||
|
||||
You can install it following the <a href="https://docs.docker.com/desktop/"
|
||||
target="_blank">official guide</a>.
|
||||
|
||||
Docker Desktop has a graphical control panel (GUI) to manage the service and view the
|
||||
containers, images and volumes. But need the command line (Terminal in Linux and Mac, or
|
||||
PowerShell in Windows) to build and run the containers, and execute other operations.
|
||||
|
||||
It already includes **docker compose** utility, needed by Penpot.
|
||||
|
||||
#### Docker Engine
|
||||
|
||||
This is the classic and default Docker setup for Linux machines, and the only option for a
|
||||
Linux VPS without graphical interface.
|
||||
|
||||
You can install it following the <a href="https://docs.docker.com/engine/"
|
||||
target="_blank">official guide</a>.
|
||||
|
||||
And you also need the [docker
|
||||
compose](https://docs.docker.com/compose/cli-command/#installing-compose-v2) (V2)
|
||||
plugin. You can use the old **docker-compose** tool, but all the documentation supposes
|
||||
you are using the V2.
|
||||
|
||||
You can easily check which version of **docker compose** you have. If you can execute
|
||||
<code class="language-bash">docker compose</code> command, then you have V2. If you need to write <code class="language-bash">docker-compose</code> (with a
|
||||
<code class="language-bash">-</code>) for it to work, you have the old version.
|
||||
|
||||
### Start Penpot
|
||||
|
||||
As first step you will need to obtain the <code class="language-bash">docker-compose.yaml</code> file. You can download it
|
||||
<a
|
||||
href="https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml"
|
||||
target="_blank">from Penpot repository</a>.
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml
|
||||
```
|
||||
or
|
||||
```bash
|
||||
curl -o docker-compose.yaml https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml
|
||||
```
|
||||
|
||||
Then simply launch composer:
|
||||
|
||||
```bash
|
||||
docker compose -p penpot -f docker-compose.yaml up -d
|
||||
```
|
||||
|
||||
At the end it will start listening on http://localhost:9001
|
||||
|
||||
<p class="advice">
|
||||
If you don't change anything, by default this will use the latest image published in dockerhub.
|
||||
</p>
|
||||
|
||||
If you want to have more control over the version (which is recommended), you can use the PENPOT_VERSION envvar in the common ways:
|
||||
- setting the value in the .env file
|
||||
- or passing the envvar in the command line
|
||||
|
||||
```bash
|
||||
PENPOT_VERSION=2.4.3 docker compose -p penpot -f docker-compose.yaml up -d
|
||||
```
|
||||
|
||||
### Stop Penpot
|
||||
|
||||
If you want to stop running Penpot, just type
|
||||
|
||||
```bash
|
||||
docker compose -p penpot -f docker-compose.yaml down
|
||||
```
|
||||
|
||||
### Configure Penpot with Docker
|
||||
|
||||
The configuration is defined using flags and environment variables in the <code class="language-bash">docker-compose.yaml</code>
|
||||
file. The default downloaded file comes with the essential flags and variables already set,
|
||||
and other ones commented out with some explanations.
|
||||
|
||||
You can find all configuration options in the [Configuration][1] section.
|
||||
|
||||
### Using the CLI for administrative tasks
|
||||
|
||||
Penpot provides a script (`manage.py`) with some administrative tasks to perform in the server.
|
||||
|
||||
**NOTE**: this script will only work with the <code class="language-bash">enable-prepl-server</code>
|
||||
flag set in the docker-compose.yaml file. For older versions of docker-compose.yaml file,
|
||||
this flag is set in the backend service.
|
||||
|
||||
For instance, if the registration is disabled, the only way to create a new user is with this script:
|
||||
|
||||
```bash
|
||||
docker exec -ti penpot-penpot-backend-1 python3 manage.py create-profile
|
||||
```
|
||||
|
||||
**NOTE:** the exact container name depends on your docker version and platform.
|
||||
For example it could be <code class="language-bash">penpot-penpot-backend-1</code> or <code class="language-bash">penpot_penpot-backend-1</code>.
|
||||
You can check the correct name executing <code class="language-bash">docker ps</code>.
|
||||
|
||||
### Update Penpot
|
||||
|
||||
To get the latest version of Penpot in your local installation, you just need to
|
||||
execute:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.yaml pull
|
||||
```
|
||||
|
||||
This will fetch the latest images. When you do <code class="language-bash">docker compose up</code> again, the containers will be recreated with the latest version.
|
||||
|
||||
<p class="advice">
|
||||
It is strongly recommended to update the Penpot version in small increments, rather than updating between two distant versions.
|
||||
</p>
|
||||
|
||||
**Important: Upgrade from version 1.x to 2.0**
|
||||
|
||||
The migration to version 2.0, due to the incorporation of the new v2 components, includes
|
||||
an additional process that runs automatically as soon as the application starts. If your
|
||||
on-premises Penpot instance contains a significant amount of data (such as hundreds of
|
||||
penpot files, especially those utilizing SVG components and assets extensively), this
|
||||
process may take a few minutes.
|
||||
|
||||
In some cases, such as when the script encounters an error, it may be convenient to run
|
||||
the process manually. To do this, you can disable the automatic migration process using
|
||||
the <code class="language-bash">disable-v2-migration</code> flag in <code
|
||||
class="language-bash">PENPOT_FLAGS</code> environment variable. You can then execute the
|
||||
migration process manually with the following command:
|
||||
|
||||
```bash
|
||||
docker exec -ti <container-name-or-id> ./run.sh app.migrations.v2
|
||||
```
|
||||
|
||||
**IMPORTANT:** this script should be executed on passing from 1.19.x to 2.0.x. Executing
|
||||
it on versions greater or equal to 2.1 of penpot will not work correctly. It is known that
|
||||
this script is removed since 2.4.3
|
||||
|
||||
|
||||
### Backup Penpot
|
||||
|
||||
Penpot uses <a href="https://docs.docker.com/storage/volumes" target="_blank">Docker
|
||||
volumes</a> to store all persistent data. This allows you to delete and recreate
|
||||
containers whenever you want without losing information.
|
||||
|
||||
This also means you need to do regular backups of the contents of the volumes. You cannot
|
||||
directly copy the contents of the volume data folder. Docker provides you a <a
|
||||
href="https://docs.docker.com/storage/volumes/#back-up-restore-or-migrate-data-volumes"
|
||||
target="_blank">volume backup procedure</a>, that uses a temporary container to mount one
|
||||
or more volumes, and copy their data to an archive file stored outside of the container.
|
||||
|
||||
If you use Docker Desktop, <a
|
||||
href="https://www.docker.com/blog/back-up-and-share-docker-volumes-with-this-extension/"
|
||||
target="_blank">there is an extension</a> that may ease the backup process.
|
||||
|
||||
If you use the default **docker compose** file, there are two volumes used: one for the
|
||||
Postgres database and another one for the assets uploaded by your users (images and svg
|
||||
clips). There may be more volumes if you enable other features, as explained in the file
|
||||
itself.
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
Knowing how to do Penpot troubleshooting can be very useful; on the one hand, it helps to create issues easier to resolve, since they include relevant information from the beginning which also makes them get solved faster; on the other hand, many times troubleshooting gives the necessary information to resolve a problem autonomously, without even creating an issue.
|
||||
|
||||
Troubleshooting requires patience and practice; you have to read the stacktrace carefully, even if it looks like a mess at first. It takes some practice to learn how to read the traces properly and extract important information.
|
||||
|
||||
If your Penpot installation is not working as intended, there are several places to look up searching for hints:
|
||||
|
||||
**Docker logs**
|
||||
|
||||
Check if all containers are up and running:
|
||||
```bash
|
||||
docker compose -p penpot -f docker-compose.yaml ps
|
||||
```
|
||||
|
||||
Check logs of all Penpot:
|
||||
```bash
|
||||
docker compose -p penpot -f docker-compose.yaml logs -f
|
||||
```
|
||||
|
||||
If there is too much information and you'd like to check just one service at a time:
|
||||
```bash
|
||||
docker compose -p penpot -f docker-compose.yaml logs penpot-frontend -f
|
||||
```
|
||||
|
||||
You can always check the logs form a specific container:
|
||||
```bash
|
||||
docker logs -f penpot-penpot-postgres-1
|
||||
```
|
||||
|
||||
**Browser logs**
|
||||
|
||||
The browser provides as well useful information to corner the issue.
|
||||
|
||||
First, use the devtools to ensure which version and flags you're using. Go to your Penpot instance in the browser and press F12; you'll see the devtools. In the <code class="language-bash">Console</code>, you can see the exact version that's being used.
|
||||
|
||||
<figure>
|
||||
<a href="/img/dev-tools-1.png" target="_blank">
|
||||
<img src="/img/dev-tools-1.png" alt="Devtools > Console" />
|
||||
</a>
|
||||
</figure>
|
||||
|
||||
Other interesting tab in the devtools is the <code class="language-bash">Network</code> tab, to check if there is a request that throws errors.
|
||||
|
||||
<figure>
|
||||
<a href="/img/dev-tools-2.png" target="_blank">
|
||||
<img src="/img/dev-tools-2.png" alt="Devtools > Network" />
|
||||
</a>
|
||||
</figure>
|
||||
|
||||
**Penpot Report**
|
||||
|
||||
When Penpot crashes, it provides a report with very useful information. Don't miss it!
|
||||
|
||||
<figure>
|
||||
<a href="/img/penpot-report.png" target="_blank">
|
||||
<img src="/img/penpot-report.png" alt="Penpot report" />
|
||||
</a>
|
||||
</figure>
|
||||
|
||||
## Install with Kubernetes
|
||||
|
||||
This section details everything you need to know to get Penpot up and running in
|
||||
production environments using a Kubernetes cluster of your choice. To do this, we have
|
||||
created a <a href="https://helm.sh/" target="_blank">Helm</a> repository with everything
|
||||
you need.
|
||||
|
||||
Therefore, your prerequisite will be to have a Kubernetes cluster on which we can install
|
||||
Helm.
|
||||
|
||||
|
||||
### What is Helm
|
||||
|
||||
*Helm* is the package manager for Kubernetes. A *Chart* is a Helm package. It contains
|
||||
all of the resource definitions necessary to run an application, tool, or service inside
|
||||
of a Kubernetes cluster. Think of it like the Kubernetes equivalent of a Homebrew
|
||||
formula, an Apt dpkg, or a Yum RPM file.
|
||||
|
||||
A Repository is the place where charts can be collected and shared. It's like Perl's CPAN
|
||||
archive or the Fedora Package Database, but for Kubernetes packages.
|
||||
|
||||
A Release is an instance of a chart running in a Kubernetes cluster. One chart can often
|
||||
be installed many times into the same cluster. And each time it is installed, a new
|
||||
release is created. Consider a MySQL chart. If you want two databases running in your
|
||||
cluster, you can install that chart twice. Each one will have its own release, which will
|
||||
in turn have its own release name.
|
||||
|
||||
With these concepts in mind, we can now explain Helm like this:
|
||||
|
||||
> Helm installs charts into Kubernetes clusters, creating a new release for each
|
||||
> installation. To find new charts, you can search Helm chart repositories.
|
||||
|
||||
|
||||
### Install Helm
|
||||
|
||||
<p class="advice">
|
||||
Skip this section if you already have Helm installed in your system.
|
||||
</p>
|
||||
|
||||
You can install Helm by following the <a href="https://helm.sh/docs/intro/install/" target="_blank">official guide</a>.
|
||||
There are different ways to install Helm, depending on your infrastructure and operating
|
||||
system.
|
||||
|
||||
|
||||
### Add Penpot repository
|
||||
|
||||
To add the Penpot Helm repository, run the following command:
|
||||
|
||||
```bash
|
||||
helm repo add penpot http://helm.penpot.app
|
||||
```
|
||||
|
||||
This will add the Penpot repository to your Helm configuration, so you can install all
|
||||
the Penpot charts stored there.
|
||||
|
||||
|
||||
### Install Penpot Chart
|
||||
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
helm install my-release penpot/penpot
|
||||
```
|
||||
|
||||
You can customize the installation specify each parameter using the `--set key=value[,key=value]`
|
||||
argument to helm install. For example,
|
||||
|
||||
```bash
|
||||
helm install my-release \
|
||||
--set global.postgresqlEnabled=true \
|
||||
--set global.redisEnabled=true \
|
||||
--set persistence.assets.enabled=true \
|
||||
penpot/penpot
|
||||
```
|
||||
|
||||
Alternatively, a YAML file that specifies the values for the above parameters can be
|
||||
provided while installing the chart. For example,
|
||||
|
||||
```bash
|
||||
helm install my-release -f values.yaml penpot/penpot
|
||||
```
|
||||
|
||||
|
||||
### Configure Penpot with Helm Chart
|
||||
|
||||
In the previous section we have shown how to configure penpot during installation by
|
||||
using parameters or by using a yaml file.
|
||||
|
||||
The default values are defined in the
|
||||
<a href="https://github.com/penpot/penpot-helm/blob/main/charts/penpot/values.yaml" target="_blank">`values.yml`</a>
|
||||
file itself, which you can use as a basis for creating your own settings.
|
||||
|
||||
You can also consult the list of parameters on the
|
||||
<a href="https://artifacthub.io/packages/helm/penpot/penpot#parameters" target="_blank">ArtifactHub page of the project</a>.
|
||||
|
||||
|
||||
### Upgrade Penpot
|
||||
|
||||
When a new version of Penpot's chart is released, or when you want to change the
|
||||
configuration of your release, you can use the helm upgrade command.
|
||||
|
||||
```bash
|
||||
helm upgrade my-release -f values.yaml penpot/penpot
|
||||
```
|
||||
|
||||
An upgrade takes an existing release and upgrades it according to the information you
|
||||
provide. Because Kubernetes charts can be large and complex, Helm tries to perform the
|
||||
least invasive upgrade. It will only update things that have changed since the last
|
||||
release.
|
||||
|
||||
After each upgrade, a new *revision* will be generated. You can check the revision
|
||||
history of a release with `helm history my-release` and go back to the previous revision
|
||||
if something went wrong with `helm rollback my-release 1` (`1` is the revision number of
|
||||
the previous release revision).
|
||||
|
||||
|
||||
### Backup Penpot
|
||||
|
||||
The Penpot's Helm Chart uses different Persistent Volumes to store all persistent data.
|
||||
This allows you to delete and recreate the instance whenever you want without losing
|
||||
information.
|
||||
|
||||
You back up data from a Persistent Volume via snapshots, so you will want to ensure that
|
||||
your container storage interface (CSI) supports volume snapshots. There are a couple of
|
||||
different options for the CSI driver that you choose. All of the major cloud providers
|
||||
have their respective CSI drivers.
|
||||
|
||||
At last, there are two Persistent Volumes used: one for the Postgres database and another
|
||||
one for the assets uploaded by your users (images and svg clips). There may be more
|
||||
volumes if you enable other features, as explained in the file itself.
|
||||
|
||||
You have to back up your custom settings too (the yaml file or the list of parameters you
|
||||
are using during you setup).
|
||||
|
||||
|
||||
## Unofficial self-host options
|
||||
|
||||
There are some other options, **NOT SUPPORTED BY PENPOT**:
|
||||
|
||||
* Install with <a href="https://community.penpot.app/t/how-to-develop-penpot-with-podman-penpotman/2113" target="_blank">Podman</a> instead of Docker.
|
||||
* Try the under development <a href="https://github.com/author-more/penpot-desktop/releases/latest" target="_blank">Penpot Desktop app</a>.
|
||||
* Try a simple Kubernetes Deployment option <a href="https://github.com/degola/penpot-kubernetes" target="_blank">penpot-kubernetes</a>.
|
||||
* Or try a fully manual installation if you have a really specific use case.. For help, you can look at the [Architecture][2] section and the <a href="https://github.com/penpot/penpot/tree/develop/docker/images" target="_blank">Docker configuration files</a>.
|
||||
|
||||
[1]: /technical-guide/configuration/
|
||||
[2]: /technical-guide/developer/architecture
|
||||
239
docs/technical-guide/getting-started/docker.md
Normal file
239
docs/technical-guide/getting-started/docker.md
Normal file
@@ -0,0 +1,239 @@
|
||||
---
|
||||
title: 1.3 Install with Docker
|
||||
---
|
||||
|
||||
# Install with Docker
|
||||
|
||||
This section details everything you need to know to get Penpot up and running in
|
||||
production environments using Docker. For this, we provide a series of *Dockerfiles* and a
|
||||
*docker-compose* file that orchestrate all.
|
||||
|
||||
## Install Docker
|
||||
|
||||
<p class="advice">
|
||||
Skip this section if you already have docker installed, up and running.
|
||||
</p>
|
||||
|
||||
Currently, Docker comes into two different flavours:
|
||||
|
||||
### Docker Desktop
|
||||
|
||||
This is the only option to have Docker in a Windows or MacOS. Recently it's also available
|
||||
for Linux, in the most popular distributions (Debian, Ubuntu and Fedora).
|
||||
|
||||
You can install it following the <a href="https://docs.docker.com/desktop/"
|
||||
target="_blank">official guide</a>.
|
||||
|
||||
Docker Desktop has a graphical control panel (GUI) to manage the service and view the
|
||||
containers, images and volumes. But you need the command line (Terminal in Linux and Mac, or
|
||||
PowerShell in Windows) to build and run the containers, and execute other operations.
|
||||
|
||||
It already includes **docker compose** utility, needed by Penpot.
|
||||
|
||||
### Docker Engine
|
||||
|
||||
This is the classic and default Docker setup for Linux machines, and the only option for a
|
||||
Linux VPS without graphical interface.
|
||||
|
||||
You can install it following the <a href="https://docs.docker.com/engine/"
|
||||
target="_blank">official guide</a>.
|
||||
|
||||
And you also need the [docker
|
||||
compose](https://docs.docker.com/compose/cli-command/#installing-compose-v2) (V2)
|
||||
plugin. You can use the old **docker-compose** tool, but all the documentation supposes
|
||||
you are using the V2.
|
||||
|
||||
You can easily check which version of **docker compose** you have. If you can execute
|
||||
<code class="language-bash">docker compose</code> command, then you have V2. If you need to write <code class="language-bash">docker-compose</code> (with a
|
||||
<code class="language-bash">-</code>) for it to work, you have the old version.
|
||||
|
||||
## Start Penpot
|
||||
|
||||
As a first step you will need to obtain the <code class="language-bash">docker-compose.yaml</code> file. You can download it
|
||||
<a
|
||||
href="https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml"
|
||||
target="_blank">from the Penpot repository</a>.
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml
|
||||
```
|
||||
or
|
||||
```bash
|
||||
curl -o docker-compose.yaml https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml
|
||||
```
|
||||
|
||||
Then simply launch composer:
|
||||
|
||||
```bash
|
||||
docker compose -p penpot -f docker-compose.yaml up -d
|
||||
```
|
||||
|
||||
At the end it will start listening on http://localhost:9001
|
||||
|
||||
<p class="advice">
|
||||
If you don't change anything, by default this will use the latest image published in dockerhub.
|
||||
</p>
|
||||
|
||||
If you want to have more control over the version (which is recommended), you can use the PENPOT_VERSION envvar in the common ways:
|
||||
- setting the value in the .env file
|
||||
- or passing the envvar in the command line
|
||||
|
||||
```bash
|
||||
PENPOT_VERSION=2.4.3 docker compose -p penpot -f docker-compose.yaml up -d
|
||||
```
|
||||
|
||||
## Stop Penpot
|
||||
|
||||
If you want to stop running Penpot, just type
|
||||
|
||||
```bash
|
||||
docker compose -p penpot -f docker-compose.yaml down
|
||||
```
|
||||
|
||||
## Configure Penpot with Docker
|
||||
|
||||
The configuration is defined using flags and environment variables in the <code class="language-bash">docker-compose.yaml</code>
|
||||
file. The default downloaded file comes with the essential flags and variables already set,
|
||||
and other ones commented out with some explanations.
|
||||
|
||||
You can find all configuration options in the [Configuration][1] section.
|
||||
|
||||
## Using the CLI for administrative tasks
|
||||
|
||||
Penpot provides a script (`manage.py`) with some administrative tasks to perform in the server.
|
||||
|
||||
**NOTE**: this script will only work with the <code class="language-bash">enable-prepl-server</code>
|
||||
flag set in the docker-compose.yaml file. For older versions of docker-compose.yaml file,
|
||||
this flag is set in the backend service.
|
||||
|
||||
For instance, if the registration is disabled, the only way to create a new user is with this script:
|
||||
|
||||
```bash
|
||||
docker exec -ti penpot-penpot-backend-1 python3 manage.py create-profile
|
||||
```
|
||||
|
||||
**NOTE:** the exact container name depends on your docker version and platform.
|
||||
For example it could be <code class="language-bash">penpot-penpot-backend-1</code> or <code class="language-bash">penpot_penpot-backend-1</code>.
|
||||
You can check the correct name executing <code class="language-bash">docker ps</code>.
|
||||
|
||||
## Update Penpot
|
||||
|
||||
To get the latest version of Penpot in your local installation, you just need to
|
||||
execute:
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.yaml pull
|
||||
```
|
||||
|
||||
This will fetch the latest images. When you do <code class="language-bash">docker compose up</code> again, the containers will be recreated with the latest version.
|
||||
|
||||
<p class="advice">
|
||||
It is strongly recommended to update the Penpot version in small increments, rather than updating between two distant versions.
|
||||
</p>
|
||||
|
||||
**Important: Upgrade from version 1.x to 2.0**
|
||||
|
||||
The migration to version 2.0, due to the incorporation of the new v2 components, includes
|
||||
an additional process that runs automatically as soon as the application starts. If your
|
||||
on-premises Penpot instance contains a significant amount of data (such as hundreds of
|
||||
penpot files, especially those utilizing SVG components and assets extensively), this
|
||||
process may take a few minutes.
|
||||
|
||||
In some cases, such as when the script encounters an error, it may be convenient to run
|
||||
the process manually. To do this, you can disable the automatic migration process using
|
||||
the <code class="language-bash">disable-v2-migration</code> flag in <code
|
||||
class="language-bash">PENPOT_FLAGS</code> environment variable. You can then execute the
|
||||
migration process manually with the following command:
|
||||
|
||||
```bash
|
||||
docker exec -ti <container-name-or-id> ./run.sh app.migrations.v2
|
||||
```
|
||||
|
||||
**IMPORTANT:** this script should be executed on passing from 1.19.x to 2.0.x. Executing
|
||||
it on versions greater or equal to 2.1 of penpot will not work correctly. It is known that
|
||||
this script is removed since 2.4.3
|
||||
|
||||
|
||||
## Backup Penpot
|
||||
|
||||
Penpot uses <a href="https://docs.docker.com/storage/volumes" target="_blank">Docker
|
||||
volumes</a> to store all persistent data. This allows you to delete and recreate
|
||||
containers whenever you want without losing information.
|
||||
|
||||
This also means you need to do regular backups of the contents of the volumes. You cannot
|
||||
directly copy the contents of the volume data folder. Docker provides you a <a
|
||||
href="https://docs.docker.com/storage/volumes/#back-up-restore-or-migrate-data-volumes"
|
||||
target="_blank">volume backup procedure</a>, that uses a temporary container to mount one
|
||||
or more volumes, and copy their data to an archive file stored outside of the container.
|
||||
|
||||
If you use Docker Desktop, <a
|
||||
href="https://www.docker.com/blog/back-up-and-share-docker-volumes-with-this-extension/"
|
||||
target="_blank">there is an extension</a> that may ease the backup process.
|
||||
|
||||
If you use the default **docker compose** file, there are two volumes used: one for the
|
||||
Postgres database and another one for the assets uploaded by your users (images and svg
|
||||
clips). There may be more volumes if you enable other features, as explained in the file
|
||||
itself.
|
||||
|
||||
## Configure the proxy
|
||||
|
||||
Your host configuration needs to make a proxy to http://localhost:9001.
|
||||
|
||||
### Example with NGINX
|
||||
|
||||
```bash
|
||||
server {
|
||||
listen 80;
|
||||
server_name penpot.mycompany.com;
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 443 ssl;
|
||||
server_name penpot.mycompany.com;
|
||||
|
||||
# This value should be in sync with the corresponding in the docker-compose.yml
|
||||
# PENPOT_HTTP_SERVER_MAX_BODY_SIZE: 31457280
|
||||
client_max_body_size 31457280;
|
||||
|
||||
# Logs: Configure your logs following the best practices inside your company
|
||||
access_log /path/to/penpot.access.log;
|
||||
error_log /path/to/penpot.error.log;
|
||||
|
||||
# TLS: Configure your TLS following the best practices inside your company
|
||||
ssl_certificate /path/to/fullchain;
|
||||
ssl_certificate_key /path/to/privkey;
|
||||
|
||||
# Websockets
|
||||
location /ws/notifications {
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection 'upgrade';
|
||||
proxy_pass http://localhost:9001/ws/notifications;
|
||||
}
|
||||
|
||||
# Proxy pass
|
||||
location / {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_redirect off;
|
||||
proxy_pass http://localhost:9001/;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Example with CADDY SERVER
|
||||
|
||||
```bash
|
||||
penpot.mycompany.com {
|
||||
reverse_proxy :9001
|
||||
tls /path/to/fullchain.pem /path/to/privkey.pem
|
||||
log {
|
||||
output file /path/to/penpot.log
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
[1]: /technical-guide/configuration/
|
||||
68
docs/technical-guide/getting-started/elestio.md
Normal file
68
docs/technical-guide/getting-started/elestio.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: 1.2 Install with Elestio
|
||||
---
|
||||
|
||||
# Install with Elestio
|
||||
|
||||
This section explains how to get Penpot up and running using <a href="https://elest.io/open-source/penpot"
|
||||
target="_blank">Elestio</a>.
|
||||
|
||||
This platform offers a fully managed service for on-premise instances of a selection of
|
||||
open-source software! This means you can deploy a dedicated instance of Penpot in just 3
|
||||
minutes. You’ll be relieved of the need to worry about DNS configuration, SMTP, backups,
|
||||
SSL certificates, OS & Penpot upgrades, and much more.
|
||||
|
||||
## Get an Elestio account
|
||||
|
||||
<p class="advice">
|
||||
Skip this section if you already have an Elestio account.
|
||||
</p>
|
||||
|
||||
To create your Elestio account <a href="https://dash.elest.io/deploy?soft=Penpot&id=121"
|
||||
target="_blank">click here</a>. You can choose to deploy on any one of five leading cloud
|
||||
providers or on-premise.
|
||||
|
||||
## Deploy Penpot using Elestio
|
||||
|
||||
Now you can Create your service in “Services”:
|
||||
1. Look for Penpot.
|
||||
2. Select a Service Cloud Provider.
|
||||
3. Select Service Cloud Region.
|
||||
4. Select Service Plan (for a team of 20 you should be fine with 2GB RAM).
|
||||
5. Select Elestio Service Support.
|
||||
6. Provide Service Name (this will show in the URL of your instance) & Admin email (used
|
||||
to create the admin account).
|
||||
7. Select Advanced Configuration options (you can also do this later).
|
||||
8. Hit “Create Service” on the bottom right.
|
||||
|
||||
It will take a couple of minutes to get the instance launched. When the status turns to
|
||||
“Service is running” you are ready to get started.
|
||||
|
||||
By clicking on the Service you go to all the details and configuration options.
|
||||
|
||||
In Network/CNAME you can find the URL of your instance. Copy and paste this into a browser
|
||||
and start using Penpot.
|
||||
|
||||
## Configure Penpot with Elestio
|
||||
|
||||
If you want to make changes to your Penpot setup click on the “Update config” button in
|
||||
Software. Here you can see the “Docker compose” used to create the instance. In “ENV” top
|
||||
middle left you can make configuration changes that will be reflected in the Docker
|
||||
compose.
|
||||
|
||||
In this file, a “#” at the start of the line means it is text and not considered part of
|
||||
the configuration. This means you will need to delete it to get some of the configuration
|
||||
options to work. Once you made all your changes hit “Update & restart”. After a couple of
|
||||
minutes, your changes will be active.
|
||||
|
||||
You can find all configuration options in the [Configuration][1] section.
|
||||
|
||||
Get in contact with us through <a href="mailto:support@penpot.app">support@penpot.app</a>
|
||||
if you have any questions or need help.
|
||||
|
||||
## Update Penpot
|
||||
|
||||
Elestio will update your instance automatically to the latest release unless you don't
|
||||
want this. In that case you need to “Disable auto updates” in Software auto updates.
|
||||
|
||||
[1]: /technical-guide/configuration/
|
||||
31
docs/technical-guide/getting-started/index.md
Normal file
31
docs/technical-guide/getting-started/index.md
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: 1. Self-hosting Guide
|
||||
---
|
||||
|
||||
# Self-hosting Guide
|
||||
|
||||
This guide explains how to get your own Penpot instance, running on a machine you control,
|
||||
to test it, use it by you or your team, or even customize and extend it any way you like.
|
||||
|
||||
If you need more context you can look at the <a
|
||||
href="https://community.penpot.app/t/self-hosting-penpot-i/2336" target="_blank">post
|
||||
about self-hosting</a> in Penpot community.
|
||||
|
||||
**There is absolutely no difference between <a
|
||||
href="https://design.penpot.app">our SaaS offer</a> for Penpot and your
|
||||
self-hosted Penpot platform!**
|
||||
|
||||
There are three main options for creating a Penpot instance:
|
||||
|
||||
1. Using the platform of our partner <a href="https://elest.io/open-source/penpot" target="_blank">Elestio</a>.
|
||||
2. Using <a href="https://docker.com" target="_blank">Docker</a> tool.
|
||||
3. Using <a href="https://kubernetes.io/" target="_blank">Kubernetes</a>.
|
||||
|
||||
<p class="advice">
|
||||
The recommended way is to use Elestio, since it's simpler, fully automatic and still greatly flexible.
|
||||
Use Docker if you already know the tool, if need full control of the process or have extra requirements
|
||||
and do not want to depend on any external provider, or need to do any special customization.
|
||||
</p>
|
||||
|
||||
Or you can try <a href="#unofficial-self-host-options">other options</a>,
|
||||
offered by Penpot community.
|
||||
136
docs/technical-guide/getting-started/kubernetes.md
Normal file
136
docs/technical-guide/getting-started/kubernetes.md
Normal file
@@ -0,0 +1,136 @@
|
||||
---
|
||||
title: 1.4 Install with Kubernetes
|
||||
---
|
||||
|
||||
# Install with Kubernetes
|
||||
|
||||
This section details everything you need to know to get Penpot up and running in
|
||||
production environments using a Kubernetes cluster of your choice. To do this, we have
|
||||
created a <a href="https://helm.sh/" target="_blank">Helm</a> repository with everything
|
||||
you need.
|
||||
|
||||
Therefore, your prerequisite will be to have a Kubernetes cluster on which we can install
|
||||
Helm.
|
||||
|
||||
## What is Helm
|
||||
|
||||
*Helm* is the package manager for Kubernetes. A *Chart* is a Helm package. It contains
|
||||
all of the resource definitions necessary to run an application, tool, or service inside
|
||||
of a Kubernetes cluster. Think of it like the Kubernetes equivalent of a Homebrew
|
||||
formula, an Apt dpkg, or a Yum RPM file.
|
||||
|
||||
A Repository is the place where charts can be collected and shared. It's like Perl's CPAN
|
||||
archive or the Fedora Package Database, but for Kubernetes packages.
|
||||
|
||||
A Release is an instance of a chart running in a Kubernetes cluster. One chart can often
|
||||
be installed many times into the same cluster. And each time it is installed, a new
|
||||
release is created. Consider a MySQL chart. If you want two databases running in your
|
||||
cluster, you can install that chart twice. Each one will have its own release, which will
|
||||
in turn have its own release name.
|
||||
|
||||
With these concepts in mind, we can now explain Helm like this:
|
||||
|
||||
> Helm installs charts into Kubernetes clusters, creating a new release for each
|
||||
> installation. To find new charts, you can search Helm chart repositories.
|
||||
|
||||
|
||||
## Install Helm
|
||||
|
||||
<p class="advice">
|
||||
Skip this section if you already have Helm installed in your system.
|
||||
</p>
|
||||
|
||||
You can install Helm by following the <a href="https://helm.sh/docs/intro/install/" target="_blank">official guide</a>.
|
||||
There are different ways to install Helm, depending on your infrastructure and operating
|
||||
system.
|
||||
|
||||
|
||||
## Add Penpot repository
|
||||
|
||||
To add the Penpot Helm repository, run the following command:
|
||||
|
||||
```bash
|
||||
helm repo add penpot http://helm.penpot.app
|
||||
```
|
||||
|
||||
This will add the Penpot repository to your Helm configuration, so you can install all
|
||||
the Penpot charts stored there.
|
||||
|
||||
|
||||
## Install Penpot Chart
|
||||
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
helm install my-release penpot/penpot
|
||||
```
|
||||
|
||||
You can customize the installation by specifying each parameter using the `--set key=value[,key=value]`
|
||||
argument to helm install. For example,
|
||||
|
||||
```bash
|
||||
helm install my-release \
|
||||
--set global.postgresqlEnabled=true \
|
||||
--set global.redisEnabled=true \
|
||||
--set persistence.assets.enabled=true \
|
||||
penpot/penpot
|
||||
```
|
||||
|
||||
Alternatively, a YAML file that specifies the values for the above parameters can be
|
||||
provided while installing the chart. For example,
|
||||
|
||||
```bash
|
||||
helm install my-release -f values.yaml penpot/penpot
|
||||
```
|
||||
|
||||
|
||||
## Configure Penpot with Helm Chart
|
||||
|
||||
In the previous section we have shown how to configure penpot during installation by
|
||||
using parameters or by using a yaml file.
|
||||
|
||||
The default values are defined in the
|
||||
<a href="https://github.com/penpot/penpot-helm/blob/main/charts/penpot/values.yaml" target="_blank">`values.yml`</a>
|
||||
file itself, which you can use as a basis for creating your own settings.
|
||||
|
||||
You can also consult the list of parameters on the
|
||||
<a href="https://artifacthub.io/packages/helm/penpot/penpot#parameters" target="_blank">ArtifactHub page of the project</a>.
|
||||
|
||||
|
||||
## Upgrade Penpot
|
||||
|
||||
When a new version of Penpot's chart is released, or when you want to change the
|
||||
configuration of your release, you can use the helm upgrade command.
|
||||
|
||||
```bash
|
||||
helm upgrade my-release -f values.yaml penpot/penpot
|
||||
```
|
||||
|
||||
An upgrade takes an existing release and upgrades it according to the information you
|
||||
provide. Because Kubernetes charts can be large and complex, Helm tries to perform the
|
||||
least invasive upgrade. It will only update things that have changed since the last
|
||||
release.
|
||||
|
||||
After each upgrade, a new *revision* will be generated. You can check the revision
|
||||
history of a release with `helm history my-release` and go back to the previous revision
|
||||
if something went wrong with `helm rollback my-release 1` (`1` is the revision number of
|
||||
the previous release revision).
|
||||
|
||||
|
||||
## Backup Penpot
|
||||
|
||||
The Penpot's Helm Chart uses different Persistent Volumes to store all persistent data.
|
||||
This allows you to delete and recreate the instance whenever you want without losing
|
||||
information.
|
||||
|
||||
You back up data from a Persistent Volume via snapshots, so you will want to ensure that
|
||||
your container storage interface (CSI) supports volume snapshots. There are a couple of
|
||||
different options for the CSI driver that you choose. All of the major cloud providers
|
||||
have their respective CSI drivers.
|
||||
|
||||
At last, there are two Persistent Volumes used: one for the Postgres database and another
|
||||
one for the assets uploaded by your users (images and svg clips). There may be more
|
||||
volumes if you enable other features, as explained in the file itself.
|
||||
|
||||
You have to back up your custom settings too (the yaml file or the list of parameters you
|
||||
are using during you setup).
|
||||
13
docs/technical-guide/getting-started/recommended-settings.md
Normal file
13
docs/technical-guide/getting-started/recommended-settings.md
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
title: 1.1 Recommended Settings
|
||||
---
|
||||
|
||||
# Recommended settings
|
||||
|
||||
To self-host Penpot, you’ll need a server with the following specifications:
|
||||
|
||||
* **CPU:** 1-2 CPUs
|
||||
* **RAM:** 4 GiB of RAM
|
||||
* **Disk Space:** Disk requirements depend on your usage. Disk usage primarily involves the database and any files uploaded by users.
|
||||
|
||||
This setup should be sufficient for a smooth experience with typical usage (your mileage may vary).
|
||||
14
docs/technical-guide/getting-started/unofficial-options.md
Normal file
14
docs/technical-guide/getting-started/unofficial-options.md
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
title: 1.5 Unofficial self-host options
|
||||
---
|
||||
|
||||
# Unofficial self-host options
|
||||
|
||||
There are some other options, **NOT SUPPORTED BY PENPOT**:
|
||||
|
||||
* Install with <a href="https://community.penpot.app/t/how-to-develop-penpot-with-podman-penpotman/2113" target="_blank">Podman</a> instead of Docker.
|
||||
* Try the under development <a href="https://github.com/author-more/penpot-desktop/releases/latest" target="_blank">Penpot Desktop app</a>.
|
||||
* Try a simple Kubernetes Deployment option <a href="https://github.com/degola/penpot-kubernetes" target="_blank">penpot-kubernetes</a>.
|
||||
* Or try a fully manual installation if you have a really specific use case.. For help, you can look at the [Architecture][1] section and the <a href="https://github.com/penpot/penpot/tree/develop/docker/images" target="_blank">Docker configuration files</a>.
|
||||
|
||||
[1]: /technical-guide/developer/architecture
|
||||
@@ -37,6 +37,11 @@ Also, if you are a developer, you can get into the code, to explore it, learn ho
|
||||
or extend it and contribute with new functionality. For this, we have a different Docker installation.
|
||||
In the [Developer Guide][6] you can find how to setup a development environment and many other dev-oriented documentation.
|
||||
|
||||
## Troubleshooting Penpot
|
||||
|
||||
The [Troubleshooting][8] section guides you through the different logs in Penpot so you can easily identify
|
||||
any issue that may arise as well as report it comprehensively.
|
||||
|
||||
[1]: /technical-guide/getting-started/#install-with-elestio
|
||||
[2]: /technical-guide/getting-started/#install-with-docker
|
||||
[3]: /technical-guide/configuration/
|
||||
@@ -44,3 +49,4 @@ In the [Developer Guide][6] you can find how to setup a development environment
|
||||
[5]: /technical-guide/integration/
|
||||
[6]: /technical-guide/developer/
|
||||
[7]: /technical-guide/getting-started/#install-with-kubernetes
|
||||
[8]: /technical-guide/troubleshooting/
|
||||
|
||||
62
docs/technical-guide/troubleshooting.md
Normal file
62
docs/technical-guide/troubleshooting.md
Normal file
@@ -0,0 +1,62 @@
|
||||
---
|
||||
title: 5. Troubleshooting Penpot
|
||||
---
|
||||
|
||||
# Troubleshooting Penpot
|
||||
|
||||
Knowing how to do Penpot troubleshooting can be very useful; on the one hand, it helps to create issues easier to resolve,
|
||||
since they include relevant information from the beginning which also makes them get solved faster;
|
||||
on the other hand, many times troubleshooting gives the necessary information to resolve a problem autonomously,
|
||||
without even creating an issue.
|
||||
|
||||
Troubleshooting requires patience and practice; you have to read the stacktrace carefully, even if it looks like a mess at first.
|
||||
It takes some practice to learn how to read the traces properly and extract important information.
|
||||
|
||||
So, if your Penpot installation is not working as intended, there are several places to look up searching for hints.
|
||||
|
||||
## Browser logs
|
||||
|
||||
Regardless of the type of installation you have performed, you can find useful information about Penpot in your browser.
|
||||
|
||||
First, use the devtools to ensure which version and flags you're using. Go to your Penpot instance in the browser and press F12;
|
||||
you'll see the devtools. In the <code class="language-bash">Console</code>, you can see the exact version that's being used.
|
||||
|
||||

|
||||
|
||||
Other interesting tab in the devtools is the <code class="language-bash">Network</code> tab, to check if there is a request that throws errors.
|
||||
|
||||

|
||||
|
||||
## Penpot report
|
||||
|
||||
When Penpot crashes, it provides a report with very useful information. Don't miss it!
|
||||
|
||||

|
||||
|
||||
## Docker logs
|
||||
|
||||
If you are using the Docker installation, this is an easy way to take a look at the logs.
|
||||
|
||||
Check if all containers are up and running:
|
||||
|
||||
```bash
|
||||
docker compose -p penpot -f docker-compose.yaml ps
|
||||
```
|
||||
|
||||
Check logs of all Penpot:
|
||||
|
||||
```bash
|
||||
docker compose -p penpot -f docker-compose.yaml logs -f
|
||||
```
|
||||
|
||||
If there is too much information and you'd like to check just one service at a time:
|
||||
|
||||
```bash
|
||||
docker compose -p penpot -f docker-compose.yaml logs penpot-frontend -f
|
||||
```
|
||||
|
||||
You can always check the logs form a specific container:
|
||||
|
||||
```bash
|
||||
docker logs -f penpot-penpot-postgres-1
|
||||
```
|
||||
@@ -5,52 +5,6 @@ title: 02· The interface
|
||||
<h1 id="the-interface">The interface</h1>
|
||||
<p class="main-paragraph">The Penpot interface has three main areas: Dashboard, Workspace and View mode. Lets take a look at their composition and main features.</p>
|
||||
|
||||
|
||||
<h2 id="interface-dashboard">Dashboard</h2>
|
||||
<p>The Dashboard is the place where you will be able to organize your files, libraries, projects and teams.</p>
|
||||
<figure>
|
||||
<a href="/img/interface/dashboard-dark.webp" target="_blank">
|
||||
<img src="/img/interface/dashboard-dark.webp" alt="Penpot's dashboard" />
|
||||
</a>
|
||||
</figure>
|
||||
|
||||
<p class="hint">
|
||||
<strong>1)</strong> Teams
|
||||
<strong>2)</strong> Search files
|
||||
<strong>3)</strong> Projects
|
||||
<strong>4)</strong> Drafts
|
||||
<strong>5)</strong> Shared Libraries
|
||||
<strong>6)</strong> Custom fonts
|
||||
<strong>7)</strong> Pinned projects
|
||||
<strong>8)</strong> User area
|
||||
<strong>9)</strong> Comment notifications
|
||||
<strong>10)</strong> Create project
|
||||
<strong>11)</strong> File card
|
||||
<strong>12)</strong> Libraries & Templates module
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li><strong>Teams:</strong> A team allows you to collaborate with other Penpot users. Team members are allowed to work with any project or file within the team depending on their permissions. Members with admin permissions can also invite other members. Create or join as many teams as you need with different groups of people.</li>
|
||||
<li><strong>Search:</strong> If you are looking for a specific file just type its title at the search box.</li>
|
||||
<li><strong>Projects:</strong> A project allows you to group design files. It works pretty much like a folder in a file system. You can create as many projects as you need. If you are going to work with more people in a project, you should create it inside a team.</li>
|
||||
<li><strong>Drafts:</strong> The drafts section is where you can find the design files that are not inside any project.</li>
|
||||
<li><strong>Shared Libraries:</strong> In this section you will find all the design files that have been added as shared libraries. That way you will be able to better control the files that are sharing their assets. </li>
|
||||
<li><strong>Custom fonts:</strong> If you have purchased or own personal fonts that are not included in the catalog provided by Penpot, you can upload them from your computer and use them across the files of a team.</li>
|
||||
<li><strong>Pinned projects:</strong> If you want to keep some projects handy (for instance because you’re currently working on them) you can pin them to make them quickly available at the sidebar.</li>
|
||||
<li><strong>User area:</strong> This must be you! Access your profile settings, Penpot tutorials, the Penpot Community and more. You can also find here a way to leave us feedback. We’d love to read your thoughts :)</li>
|
||||
<li><strong>Comments notifications:</strong> Here you will be able to see if you have unread comments inside the files of the team.</li>
|
||||
<li><strong>Create project:</strong> Create as many projects as you need to organize your designs.</li>
|
||||
<li><strong>File card:</strong> Basic information about a file at plain sight. A preview, update info or if it’s added as a Shared Library. From there you can perform several actions over the file (rename, duplicate, move, download, delete).</li>
|
||||
<li><strong>Libraries & Templates module:</strong> A curated selection of Libraries & Templates files ready to import.</li>
|
||||
</ol>
|
||||
|
||||
|
||||
<h3 id="your-account">Your account</h3>
|
||||
<p>Your account settings can be changed at the user area, in <b>Your account</b>. Here you can make changes to your profile, password or account language, as well as generate personal access tokens and access release notes.</p>
|
||||
<p>If you want to change the email address associated to your account or remove your account entirely, this can be done in the <b>Profile</b> section.</p>
|
||||
|
||||
|
||||
|
||||
<h2 id="interface-workspace">Workspace</h2>
|
||||
<p>The Workspace is where you actually create your designs. You have an infinite canvas where you can work directly but you also have the ability to create and work inside boards that will help you to create pages and exportation units.</p>
|
||||
|
||||
@@ -102,8 +56,6 @@ title: 02· The interface
|
||||
<li><strong>Assets panel:</strong> Each file has a default library (File Library) where you can store elements and styles that are likely to be reused within a project. That includes components, colors and typographies. To add an asset to a library just click the “+” button at the header of each asset group.</li>
|
||||
</ol>
|
||||
|
||||
|
||||
|
||||
<h2 id="interface-viewmode">View mode</h2>
|
||||
<p>Launch the view mode to present and share your designs, comment on them and play with the interactions set at the workspace. You also have an Inspect mode where you can get properties specifications and code snippets. <a href="/user-guide/view-mode/">More about the View mode.</a></p>
|
||||
|
||||
@@ -145,6 +97,83 @@ title: 02· The interface
|
||||
<li><strong>Navigation buttons:</strong> Forward and backwards buttons.</li>
|
||||
</ol>
|
||||
|
||||
<h2 id="interface-dashboard">Dashboard</h2>
|
||||
<p>The Dashboard is the place where you will be able to organize your files, libraries, projects and teams.</p>
|
||||
<figure>
|
||||
<a href="/img/interface/dashboard-dark.webp" target="_blank">
|
||||
<img src="/img/interface/dashboard-dark.webp" alt="Penpot's dashboard" />
|
||||
</a>
|
||||
</figure>
|
||||
|
||||
<p class="hint">
|
||||
<strong>1)</strong> Teams
|
||||
<strong>2)</strong> Search files
|
||||
<strong>3)</strong> Projects
|
||||
<strong>4)</strong> Drafts
|
||||
<strong>5)</strong> Shared Libraries
|
||||
<strong>6)</strong> Custom fonts
|
||||
<strong>7)</strong> Pinned projects
|
||||
<strong>8)</strong> User area
|
||||
<strong>9)</strong> Comment notifications
|
||||
<strong>10)</strong> Create project
|
||||
<strong>11)</strong> File card
|
||||
<strong>12)</strong> Libraries & Templates module
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li><strong>Teams:</strong> A team allows you to collaborate with other Penpot users. Team members are allowed to work with any project or file within the team depending on their permissions. Members with admin permissions can also invite other members. Create or join as many teams as you need with different groups of people.</li>
|
||||
<li><strong>Search:</strong> If you are looking for a specific file just type its title at the search box.</li>
|
||||
<li><strong>Projects:</strong> A project allows you to group design files. It works pretty much like a folder in a file system. You can create as many projects as you need. If you are going to work with more people in a project, you should create it inside a team.</li>
|
||||
<li><strong>Drafts:</strong> The drafts section is where you can find the design files that are not inside any project.</li>
|
||||
<li><strong>Shared Libraries:</strong> In this section you will find all the design files that have been added as shared libraries. That way you will be able to better control the files that are sharing their assets. </li>
|
||||
<li><strong>Custom fonts:</strong> If you have purchased or own personal fonts that are not included in the catalog provided by Penpot, you can upload them from your computer and use them across the files of a team.</li>
|
||||
<li><strong>Pinned projects:</strong> If you want to keep some projects handy (for instance because you’re currently working on them) you can pin them to make them quickly available at the sidebar.</li>
|
||||
<li><strong>User area:</strong> This must be you! Access your profile settings, Penpot tutorials, the Penpot Community and more. You can also find here a way to leave us feedback. We’d love to read your thoughts :)</li>
|
||||
<li><strong>Comments notifications:</strong> Here you will be able to see if you have unread comments inside the files of the team.</li>
|
||||
<li><strong>Create project:</strong> Create as many projects as you need to organize your designs.</li>
|
||||
<li><strong>File card:</strong> Basic information about a file at plain sight. A preview, update info or if it’s added as a Shared Library. From there you can perform several actions over the file (rename, duplicate, move, download, delete).</li>
|
||||
<li><strong>Libraries & Templates module:</strong> A curated selection of Libraries & Templates files ready to import.</li>
|
||||
</ol>
|
||||
|
||||
<h3 id="your-account">Your account</h3>
|
||||
<p>Your account settings can be changed at the user area, in <b>Your account</b>. Here you can make changes to your profile, password or account language, as well as generate personal access tokens and access release notes.</p>
|
||||
|
||||
<h4 id="your-account-profile">Profile
|
||||
<a class="direct-link" href="#your-account-profile">#</a>
|
||||
</h3>
|
||||
<p>If you want to change the email address associated to your account or remove your account entirely, this can be done in the <b>Profile</b> section.</p>
|
||||
<figure>
|
||||
<img src="/img/interface/youraccount-profile.webp" alt="Penpot's profile" />
|
||||
</figure>
|
||||
|
||||
<h4 id="your-account-password">Password
|
||||
<a class="direct-link" href="#your-account-password">#</a>
|
||||
</h3>
|
||||
<p>If you want to change your password to a new one, this can be done in the <b>Password</b> section.</p>
|
||||
<figure>
|
||||
<img src="/img/interface/youraccount-password.webp" alt="Penpot's password" />
|
||||
</figure>
|
||||
|
||||
<h4 id="your-account-notifications">Notifications
|
||||
<a class="direct-link" href="#your-account-notifications">#</a>
|
||||
</h3>
|
||||
<p>At the <strong>Notifications</strong> section you can configure the email and dashboard notifications.</p>
|
||||
<figure>
|
||||
<img src="/img/interface/youraccount-notifications.webp" alt="Penpot's notifications" />
|
||||
</figure>
|
||||
|
||||
<h4 id="your-account-settings">Settings
|
||||
<a class="direct-link" href="#your-account-settings">#</a>
|
||||
</h3>
|
||||
<p>At the <strong>Settings</strong> section you can change the language and the UI color theme.</p>
|
||||
<figure>
|
||||
<img src="/img/interface/youraccount-settings.webp" alt="Penpot's settings" />
|
||||
</figure>
|
||||
|
||||
<h4 id="your-account-accesstokens">Access tokens
|
||||
<a class="direct-link" href="#your-account-accesstokens">#</a>
|
||||
</h3>
|
||||
<p>At the <strong>Asset tokens</strong> section you can manage your access tokens. <a href="https://help.penpot.app/technical-guide/integration/#access-tokens" target="_blank">Read more about access tokens here</a>.</p>
|
||||
|
||||
<h2 id="interface-ui-theme">UI Theme</h2>
|
||||
<p>Penpot's default interface is dark but you can switch anytime to a light option. You have 2 ways to change the theme:</p>
|
||||
@@ -170,4 +199,4 @@ title: 02· The interface
|
||||
<img src="/img/interface/viewmode-light.webp" alt="Penpot's view mode" />
|
||||
</a>
|
||||
<figcaption>Penpot's view mode in light mode</figcaption>
|
||||
</figure>
|
||||
</figure>
|
||||
@@ -70,6 +70,7 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||
);
|
||||
this.toolbarOptions = page.getByTestId("toolbar-options");
|
||||
this.rectShapeButton = page.getByRole("button", { name: "Rectangle (R)" });
|
||||
this.moveButton = page.getByRole("button", { name: "Move (V)" });
|
||||
this.boardButton = page.getByRole("button", { name: "Board (B)" });
|
||||
this.toggleToolbarButton = page.getByRole("button", {
|
||||
name: "Toggle toolbar",
|
||||
|
||||
@@ -13,6 +13,7 @@ test("Bug 7549 - User clicks on color swatch to display the color picker next to
|
||||
await workspacePage.setupEmptyFile(page);
|
||||
|
||||
await workspacePage.goToWorkspace();
|
||||
await workspacePage.moveButton.click();
|
||||
const swatch = workspacePage.page.getByRole("button", { name: "E8E9EA" });
|
||||
const swatchBox = await swatch.boundingBox();
|
||||
await swatch.click();
|
||||
@@ -171,6 +172,7 @@ test("Bug 9900 - Color picker has no inputs for HSV values", async ({
|
||||
await workspacePage.setupEmptyFile(page);
|
||||
|
||||
await workspacePage.goToWorkspace();
|
||||
await workspacePage.moveButton.click();
|
||||
const swatch = workspacePage.page.getByRole("button", { name: "E8E9EA" });
|
||||
await swatch.click();
|
||||
|
||||
|
||||
@@ -178,6 +178,7 @@ test("Bug 10179 - Drag & drop doesn't add colors to the Recent Colors palette",
|
||||
const workspacePage = new WorkspacePage(page);
|
||||
await workspacePage.setupEmptyFile();
|
||||
await workspacePage.goToWorkspace();
|
||||
await workspacePage.moveButton.click();
|
||||
|
||||
await workspacePage.page.keyboard.press("Alt+p");
|
||||
|
||||
|
||||
10
frontend/resources/styles/common/dependencies/storybook.scss
Normal file
10
frontend/resources/styles/common/dependencies/storybook.scss
Normal file
@@ -0,0 +1,10 @@
|
||||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
.sb-show-main.sb-main-fullscreen,
|
||||
.sb-show-main.sb-main-padded {
|
||||
overflow-y: auto;
|
||||
}
|
||||
@@ -13,6 +13,7 @@
|
||||
@import "common/dependencies/fonts";
|
||||
@import "common/dependencies/animations";
|
||||
@import "common/dependencies/highlight.scss";
|
||||
@import "common/dependencies/storybook.scss";
|
||||
|
||||
@import "common/refactor/themes.scss";
|
||||
@import "common/refactor/design-tokens.scss";
|
||||
|
||||
@@ -90,7 +90,6 @@
|
||||
(update :comments-local assoc :open id))
|
||||
(update :comments-local assoc :options nil)
|
||||
(update :comments-local dissoc :draft)
|
||||
(update :workspace-drawing dissoc :comment)
|
||||
(update-in [:comments id] assoc (:id comment) comment))))
|
||||
|
||||
ptk/WatchEvent
|
||||
@@ -146,7 +145,6 @@
|
||||
(update :comments-local assoc :open id)
|
||||
(update :comments-local assoc :options nil)
|
||||
(update :comments-local dissoc :draft)
|
||||
(update :workspace-drawing dissoc :comment)
|
||||
(update-in [:comments id] assoc (:id comment) comment))))
|
||||
|
||||
ptk/WatchEvent
|
||||
@@ -415,8 +413,8 @@
|
||||
(->> (rp/cmd! :get-comment-threads {:file-id file-id :share-id share-id})
|
||||
(rx/map comment-threads-fetched))
|
||||
|
||||
;; Refresh team members
|
||||
(rx/of (dtm/fetch-members)))))))
|
||||
(when (:workspace-local state)
|
||||
(rx/of (dtm/fetch-members))))))))
|
||||
|
||||
(defn retrieve-comments
|
||||
[thread-id]
|
||||
@@ -474,7 +472,7 @@
|
||||
(-> state
|
||||
(update :comments-local assoc :open id)
|
||||
(update :comments-local assoc :options nil)
|
||||
(update :workspace-drawing dissoc :comment)))))
|
||||
(update :comments-local dissoc :draft)))))
|
||||
|
||||
(defn close-thread
|
||||
[]
|
||||
@@ -482,8 +480,7 @@
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update :comments-local dissoc :open :draft :options)
|
||||
(update :workspace-drawing dissoc :comment)))))
|
||||
(update :comments-local dissoc :open :draft :options)))))
|
||||
|
||||
(defn update-filters
|
||||
[{:keys [mode show list] :as params}]
|
||||
@@ -524,7 +521,6 @@
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(update :workspace-drawing assoc :comment params)
|
||||
(update :comments-local assoc :draft params)))))
|
||||
|
||||
(defn update-draft-thread
|
||||
@@ -533,7 +529,6 @@
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(d/update-in-when [:workspace-drawing :comment] merge data)
|
||||
(d/update-in-when [:comments-local :draft] merge data)))))
|
||||
|
||||
(defn toggle-comment-options
|
||||
|
||||
@@ -171,7 +171,7 @@
|
||||
(declare go-to-frame-auto)
|
||||
|
||||
(defn bundle-fetched
|
||||
[{:keys [project file share-links libraries users permissions thumbnails] :as bundle}]
|
||||
[{:keys [project file team share-links libraries users permissions thumbnails] :as bundle}]
|
||||
(let [pages (->> (dm/get-in file [:data :pages])
|
||||
(map (fn [page-id]
|
||||
(let [data (get-in file [:data :pages-index page-id])]
|
||||
@@ -183,15 +183,19 @@
|
||||
(ptk/reify ::bundle-fetched
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(-> state
|
||||
(assoc :share-links share-links)
|
||||
(assoc :viewer {:libraries (d/index-by :id libraries)
|
||||
:users (d/index-by :id users)
|
||||
:permissions permissions
|
||||
:project project
|
||||
:pages pages
|
||||
:thumbnails thumbnails
|
||||
:file file})))
|
||||
(let [team-id (:id team)
|
||||
team {:members users}]
|
||||
(-> state
|
||||
(assoc :share-links share-links)
|
||||
(assoc :current-team-id team-id)
|
||||
(assoc :teams {team-id team})
|
||||
(assoc :viewer {:libraries (d/index-by :id libraries)
|
||||
:users (d/index-by :id users)
|
||||
:permissions permissions
|
||||
:project project
|
||||
:pages pages
|
||||
:thumbnails thumbnails
|
||||
:file file}))))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
|
||||
@@ -478,8 +478,7 @@
|
||||
(rx/of (initialize-page* file-id page-id page)
|
||||
(dwth/watch-state-changes file-id page-id)
|
||||
(dwl/watch-component-changes)
|
||||
(when (cf/external-feature-flag "boards-02" "test")
|
||||
(select-frame-tool file-id page-id)))
|
||||
(select-frame-tool file-id page-id))
|
||||
(rx/of (dcm/go-to-workspace :file-id file-id ::rt/replace true))))))
|
||||
|
||||
(defn finalize-page
|
||||
|
||||
@@ -1186,20 +1186,19 @@
|
||||
(ctf/used-assets-changed-since file-data library sync-date))))))
|
||||
|
||||
(defn notify-sync-file
|
||||
;; file-id is the id of the modified library
|
||||
[file-id]
|
||||
(dm/assert! (uuid? file-id))
|
||||
(ptk/reify ::notify-sync-file
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(let [file (dsh/lookup-file state file-id)
|
||||
|
||||
(let [file (dsh/lookup-file state (:current-file-id state))
|
||||
file-data (get file :data)
|
||||
ignore-until (get file :ignore-sync-until)
|
||||
|
||||
libraries-need-sync
|
||||
(filter #(seq (assets-need-sync % file-data ignore-until))
|
||||
(vals (get state :files)))
|
||||
|
||||
do-more-info
|
||||
#(modal/show! :libraries-dialog {:starting-tab "updates" :file-id file-id})
|
||||
|
||||
|
||||
@@ -317,6 +317,6 @@
|
||||
(ptk/reify ::handle-library-change
|
||||
ptk/WatchEvent
|
||||
(watch [_ state _]
|
||||
(when (contains? (:libraries state) file-id)
|
||||
(when (contains? (:files state) file-id)
|
||||
(rx/of (dwl/ext-library-changed file-id modified-at revn changes)
|
||||
(dwl/notify-sync-file file-id))))))
|
||||
|
||||
@@ -62,18 +62,21 @@
|
||||
;; --- Navigate (Event)
|
||||
|
||||
(defn navigated
|
||||
[match]
|
||||
[match send-event-info?]
|
||||
(ptk/reify ::navigated
|
||||
IDeref
|
||||
(-deref [_] match)
|
||||
|
||||
ev/Event
|
||||
(-data [_]
|
||||
(let [route (dm/get-in match [:data :name])
|
||||
params (get match :path-params)]
|
||||
(assoc params
|
||||
::ev/name "navigate"
|
||||
:route (name route))))
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(when send-event-info?
|
||||
(let [route (dm/get-in match [:data :name])
|
||||
params (get match :query-params)]
|
||||
(rx/of (ptk/event
|
||||
::ev/event
|
||||
(assoc params
|
||||
::ev/name "navigate"
|
||||
:route (name route)))))))
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
@@ -186,6 +189,21 @@
|
||||
|
||||
;; --- History API
|
||||
|
||||
;; Check the urls to see if we need to send the navigated event.
|
||||
;; If two paths are the same we only send the event when there is a
|
||||
;; change in the parameters `file-id`, `page-id` or `team-id`
|
||||
(defn- send-event-info?
|
||||
[old-url new-url]
|
||||
(let [params [:file-id :page-id :team-id]
|
||||
new-uri (u/uri new-url)
|
||||
new-path (:path new-uri)
|
||||
new-params (-> new-uri :query u/query-string->map (select-keys params))
|
||||
old-uri (u/uri old-url)
|
||||
old-path (:path old-uri)
|
||||
old-params (-> old-uri :query u/query-string->map (select-keys params))]
|
||||
(or (not= old-path new-path)
|
||||
(not= new-params old-params))))
|
||||
|
||||
(defn initialize-history
|
||||
[on-change]
|
||||
(ptk/reify ::initialize-history
|
||||
@@ -200,11 +218,19 @@
|
||||
(let [stopper (rx/filter (ptk/type? ::initialize-history) stream)
|
||||
history (:history state)
|
||||
router (:router state)]
|
||||
(ts/schedule #(on-change router (.getToken ^js history)))
|
||||
(->> (rx/create (fn [subs]
|
||||
(let [key (e/listen history "navigate" (fn [o] (rx/push! subs (.-token ^js o))))]
|
||||
(fn []
|
||||
(bhistory/disable! history)
|
||||
(e/unlistenByKey key)))))
|
||||
(ts/schedule #(on-change router (.getToken ^js history) true))
|
||||
(->> (rx/concat
|
||||
(rx/of nil nil)
|
||||
(rx/create
|
||||
(fn [subs]
|
||||
(let [key (e/listen history "navigate" (fn [o] (rx/push! subs (.-token ^js o))))]
|
||||
(fn []
|
||||
(bhistory/disable! history)
|
||||
(e/unlistenByKey key))))))
|
||||
(rx/buffer 2 1)
|
||||
(rx/take-until stopper)
|
||||
(rx/subs! #(on-change router %)))))))
|
||||
(rx/subs!
|
||||
(fn [[old-url new-url]]
|
||||
(when (some? new-url)
|
||||
(let [send? (or (nil? old-url) (send-event-info? old-url new-url))]
|
||||
(on-change router new-url send?))))))))))
|
||||
|
||||
@@ -132,10 +132,11 @@
|
||||
|
||||
(defn- blank-content?
|
||||
[content]
|
||||
(or (str/blank? content)
|
||||
(str/empty? content)
|
||||
;; If only one char and it's the zero-width whitespace
|
||||
(and (= 1 (count content)) (= (first content) zero-width-space))))
|
||||
(let [content (str/trim content)]
|
||||
(or (str/blank? content)
|
||||
(str/empty? content)
|
||||
(and (= (count content) 1)
|
||||
(= (first content) zero-width-space)))))
|
||||
|
||||
;; Component that renders the component content
|
||||
(mf/defc comment-content*
|
||||
|
||||
@@ -959,6 +959,7 @@
|
||||
on-power-up-click
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (ptk/event ::ev/event {::ev/name "explore-pricing-click" ::ev/origin "dashboard" :section "sidebar"}))
|
||||
(dom/open-new-window "https://penpot.app/pricing")))]
|
||||
|
||||
[:*
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
:plugin-url plugin))))
|
||||
|
||||
(defn on-navigate
|
||||
[router path]
|
||||
[router path send-event-info?]
|
||||
(let [location (.-location js/document)
|
||||
[base-path qs] (str/split path "?")
|
||||
location-path (dm/str (.-origin location) (.-pathname location))
|
||||
@@ -102,7 +102,7 @@
|
||||
(st/emit! (rt/assign-exception {:type :not-found}))
|
||||
|
||||
(some? match)
|
||||
(st/emit! (rt/navigated match))
|
||||
(st/emit! (rt/navigated match send-event-info?))
|
||||
|
||||
:else
|
||||
;; We just recheck with an additional profile request; this
|
||||
|
||||
@@ -35,5 +35,8 @@
|
||||
|
||||
;; Old components can have texts without position data that must be rendered via foreign key
|
||||
(cond
|
||||
(some? position-data) [:> svg/text-shape props]
|
||||
is-component? [:> fo/text-shape props])))
|
||||
(some? position-data)
|
||||
[:> svg/text-shape props]
|
||||
|
||||
(or (nil? position-data) is-component?)
|
||||
[:> fo/text-shape props])))
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc options*
|
||||
[{:keys [shape file-id shapes-with-children shared-libs] :as props}]
|
||||
[{:keys [shape file-id shapes-with-children libraries] :as props}]
|
||||
(let [shape-id (dm/get-prop shape :id)
|
||||
shape-type (dm/get-prop shape :type)
|
||||
|
||||
@@ -116,7 +116,7 @@
|
||||
[:> color-selection-menu* {:type shape-type
|
||||
:shapes shapes-with-children
|
||||
:file-id file-id
|
||||
:libraries shared-libs}]
|
||||
:libraries libraries}]
|
||||
[:> shadow-menu* {:ids ids :values (get shape :shadow)}]
|
||||
[:& blur-menu {:ids ids
|
||||
:values (select-keys shape [:blur])}]
|
||||
|
||||
@@ -292,7 +292,7 @@
|
||||
|
||||
page-id (unchecked-get props "page-id")
|
||||
file-id (unchecked-get props "file-id")
|
||||
shared-libs (unchecked-get props "shared-libs")
|
||||
shared-libs (unchecked-get props "libraries")
|
||||
|
||||
show-caps (some #(and (= :path (:type %)) (gsh/open-path? %)) shapes)
|
||||
|
||||
|
||||
@@ -304,8 +304,7 @@
|
||||
:page-id page-id
|
||||
:file-id file-id
|
||||
:vport vport
|
||||
:zoom zoom
|
||||
:drawing drawing}])
|
||||
:zoom zoom}])
|
||||
|
||||
(when picking-color?
|
||||
[:& pixel-overlay/pixel-overlay {:vport vport
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc comments-layer*
|
||||
[{:keys [vbox vport zoom drawing file-id page-id]}]
|
||||
[{:keys [vbox vport zoom file-id page-id]}]
|
||||
(let [vbox-x (dm/get-prop vbox :x)
|
||||
vbox-y (dm/get-prop vbox :y)
|
||||
vport-w (dm/get-prop vport :width)
|
||||
@@ -73,7 +73,7 @@
|
||||
:viewport viewport
|
||||
:zoom zoom}])))
|
||||
|
||||
(when-let [draft (:comment drawing)]
|
||||
(when-let [draft (:draft local)]
|
||||
[:> cmt/comment-floating-thread-draft*
|
||||
{:draft draft
|
||||
:on-cancel on-draft-cancel
|
||||
|
||||
@@ -350,8 +350,7 @@
|
||||
[:> comments/comments-layer* {:vbox vbox
|
||||
:page-id page-id
|
||||
:vport vport
|
||||
:zoom zoom
|
||||
:drawing drawing}])
|
||||
:zoom zoom}])
|
||||
|
||||
(when picking-color?
|
||||
[:& pixel-overlay/pixel-overlay {:vport vport
|
||||
|
||||
@@ -4754,7 +4754,7 @@ msgstr "Or add some of these to try:"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:368
|
||||
msgid "workspace.libraries.empty.no-libraries"
|
||||
msgstr "There are no Shared Libraries at you team, you can look for"
|
||||
msgstr "There are no Shared Libraries at your team, you can look for"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:372
|
||||
msgid "workspace.libraries.empty.some-templates"
|
||||
|
||||
@@ -4772,7 +4772,7 @@ msgstr "O añadir algunas de éstas para probar:"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:368
|
||||
msgid "workspace.libraries.empty.no-libraries"
|
||||
msgstr "No hay Biblioteacas Compartidas en tu equipo, puedes buscar"
|
||||
msgstr "No hay Bibliotecas Compartidas en tu equipo, puedes buscar"
|
||||
|
||||
#: src/app/main/ui/workspace/libraries.cljs:372
|
||||
msgid "workspace.libraries.empty.some-templates"
|
||||
|
||||
Reference in New Issue
Block a user