mirror of
https://github.com/penpot/penpot-docs.git
synced 2024-07-06 05:41:47 +00:00
🎉 Reorganize technical documentation.
This commit is contained in:
parent
84bbb29a4e
commit
0b916550ca
|
@ -8,7 +8,9 @@ templateClass: tmpl-developer-guide
|
|||
{%- if loop.first -%}<ul>{%- endif -%}
|
||||
<li>
|
||||
<a href="{{ child.url }}">{{ child.data.title }}</a>
|
||||
{%- if page.url.includes(child.url) -%}
|
||||
{{ show_children(child) }}
|
||||
{%- endif -%}
|
||||
{%- if child.url == page.url -%}
|
||||
{{ content | toc(tags=['h2', 'h3']) | stripHash | safe }}
|
||||
{%- endif -%}
|
||||
|
@ -19,7 +21,7 @@ templateClass: tmpl-developer-guide
|
|||
|
||||
<div class="main-container with-sidebar">
|
||||
<aside id="stickySidebar" class="sidebar">
|
||||
{%- set root = '/developer-guide/index' | find -%}
|
||||
{%- set root = '/technical-guide/index' | find -%}
|
||||
<div id="toc">
|
||||
<div class="header mobile" id="toc-title">{{ root.data.title }}</div>
|
||||
<a class="header" href="{{ root.url }}">{{ root.data.title }}</a>
|
|
@ -148,6 +148,7 @@ pre {
|
|||
padding: 1em;
|
||||
margin: .5em 0;
|
||||
background-color: #f6f6f6;
|
||||
overflow: auto;
|
||||
}
|
||||
.highlight-line {
|
||||
display: block;
|
||||
|
@ -370,6 +371,17 @@ a[href].direct-link:focus:visited,
|
|||
color: var(--primary);
|
||||
}
|
||||
|
||||
[id]::before {
|
||||
visibility: hidden;
|
||||
content: '';
|
||||
}
|
||||
|
||||
:target[id]::before {
|
||||
content: '';
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
height: 94px;
|
||||
}
|
||||
|
||||
/* Particular classes */
|
||||
|
||||
|
@ -381,6 +393,7 @@ a[href].direct-link:focus:visited,
|
|||
.main-container {
|
||||
margin: auto;
|
||||
max-width: 80rem;
|
||||
min-height: 60vh;
|
||||
}
|
||||
.main-container.with-sidebar {
|
||||
/* display: grid;
|
||||
|
@ -635,11 +648,11 @@ a[href].direct-link:focus:visited,
|
|||
}
|
||||
.main-container h2 {
|
||||
margin-top: 0rem;
|
||||
padding-top: 7rem;
|
||||
padding-top: 4rem;
|
||||
}
|
||||
.main-container h3 {
|
||||
margin-top: 0rem;
|
||||
padding-top: 7rem;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,253 +0,0 @@
|
|||
---
|
||||
title: 2. Configuration guide
|
||||
---
|
||||
|
||||
# Configuration Guide #
|
||||
|
||||
This section intends to explain all available configuration options.
|
||||
|
||||
## Backend ##
|
||||
|
||||
The default approach for pass options to backend application is using
|
||||
environment variables. Almost all environment variables starts with
|
||||
the `PENPOT_` prefix.
|
||||
|
||||
NOTE: All the examples that comes with values, they represent the
|
||||
**default** values.
|
||||
|
||||
|
||||
### Configuration Options
|
||||
|
||||
|
||||
#### Database Connection
|
||||
|
||||
```bash
|
||||
PENPOT_DATABASE_USERNAME=penpot
|
||||
PENPOT_DATABASE_PASSWORD=penpot
|
||||
PENPOT_DATABASE_URI=postgresql://127.0.0.1/penpot
|
||||
```
|
||||
|
||||
The username and password are optional.
|
||||
|
||||
#### Email (SMTP)
|
||||
|
||||
```bash
|
||||
PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
|
||||
PENPOT_SMTP_DEFAULT_FROM=no-reply@example.com
|
||||
|
||||
# When not enabled, the emails are printed to the console.
|
||||
PENPOT_SMTP_ENABLED=false
|
||||
|
||||
PENPOT_SMTP_HOST=<host>
|
||||
PENPOT_SMTP_PORT=25
|
||||
PENPOT_SMTP_USER=<username>
|
||||
PENPOT_SMTP_PASSWORD=<password>
|
||||
PENPOT_SMTP_SSL=false
|
||||
PENPOT_SMTP_TLS=false
|
||||
```
|
||||
|
||||
#### Storage (assets)
|
||||
|
||||
Assets storage is implemented using "plugable" backends. Currently
|
||||
there are three backends available: `db`, `fs` and `s3` (for AWS S3).
|
||||
|
||||
##### fs backend
|
||||
|
||||
The default backend is: **fs**.
|
||||
|
||||
```bash
|
||||
PENPOT_STORAGE_BACKEND=fs
|
||||
PENPOT_STORAGE_FS_DIRECTORY=resources/public/assets`
|
||||
```
|
||||
|
||||
The fs backend is hightly coupled with nginx way to serve files using
|
||||
`x-accel-redirect` and for correctly configuring it you will need to
|
||||
touch your nginx config for correctly expose the directory specified
|
||||
in `PENPOT_STORAGE_FS_DIRECTORY` environment.
|
||||
|
||||
For more concrete example look at the devenv nginx configurtion
|
||||
located in `<repo-root>/docker/devenv/files/nginx.conf`.
|
||||
|
||||
**NOTE**: The **fs** storage backend is used for store temporal files
|
||||
when a user uploads an image and that image need to be processed for
|
||||
creating thumbnails. So is **hightly recommeded** setting up a correct
|
||||
directory for this backend independently if it is used as main backend
|
||||
or not.
|
||||
|
||||
##### db backend
|
||||
|
||||
In some circumstances or just for convenience you can use the `db`
|
||||
backend that stores all media uploaded by the user directly inside the
|
||||
database. This backend, at expenses of some overhead, facilitates the
|
||||
backups, because with this backend all that you need to backup is the
|
||||
postgresql database. Convenient for small installations and personal
|
||||
use.
|
||||
|
||||
```bash
|
||||
PENPOT_STORAGE_BACKEND=db
|
||||
```
|
||||
|
||||
|
||||
##### s3 backend
|
||||
|
||||
And finally, you can use AWS S3 service as backend for assets
|
||||
storage. For this you will need to have AWS credentials, an bucket and
|
||||
the region of the bucket.
|
||||
|
||||
```bash
|
||||
AWS_ACCESS_KEY_ID=<you-access-key-id-here>
|
||||
AWS_SECRET_ACCESS_KEY=<your-secret-access-key-here>
|
||||
PENPOT_STORAGE_BACKEND=s3
|
||||
PENPOT_STORAGE_S3_REGION=<aws-region>
|
||||
PENPOT_STORAGE_S3_BUCKET=<bucket-name>
|
||||
```
|
||||
|
||||
Right now, only `eu-central-1` region is supported. If you need others, open an issue.
|
||||
|
||||
#### Redis
|
||||
|
||||
The redis configuration is very simple, just provide with a valid redis URI. Redis is used
|
||||
mainly for websocket notifications coordination.
|
||||
|
||||
```bash
|
||||
PENPOT_REDIS_URI=redis://localhost/0
|
||||
```
|
||||
|
||||
|
||||
#### HTTP Server
|
||||
|
||||
```bash
|
||||
PENPOT_HTTP_SERVER_PORT=6060
|
||||
PENPOT_PUBLIC_URI=http://localhost:3449
|
||||
PENPOT_REGISTRATION_ENABLED=true
|
||||
|
||||
# comma-separated domains, defaults to `""` which means that all domains are allowed)
|
||||
PENPOT_REGISTRATION_DOMAIN_WHITELIST=""
|
||||
```
|
||||
|
||||
When disabling registation, remember to also do it [in frontend](#auth-with-3rd-party-2).
|
||||
|
||||
#### Server REPL
|
||||
|
||||
The production environment by default starts a server REPL where you
|
||||
can connect and perform diagnosis operations. For this you will need
|
||||
`netcat` or `telnet` installed in the server.
|
||||
|
||||
```bash
|
||||
$ rlwrap netcat localhost 6062
|
||||
user=>
|
||||
```
|
||||
The default configuration is:
|
||||
|
||||
```bash
|
||||
PENPOT_SREPL_HOST=127.0.0.1
|
||||
PENPOT_SREPL_PORT=6062
|
||||
```
|
||||
|
||||
#### Auth with 3rd party
|
||||
|
||||
**NOTE**: a part of setting this configuration on backend, frontend
|
||||
application will also require configuration tweaks for make it work.
|
||||
|
||||
##### Google
|
||||
|
||||
```bash
|
||||
PENPOT_GOOGLE_CLIENT_ID=<client-id>
|
||||
PENPOT_GOOGLE_CLIENT_SECRET=<client-secret>
|
||||
```
|
||||
|
||||
##### Gitlab
|
||||
|
||||
```bash
|
||||
PENPOT_GITLAB_BASE_URI=https://gitlab.com
|
||||
PENPOT_GITLAB_CLIENT_ID=<client-id>
|
||||
PENPOT_GITLAB_CLIENT_SECRET=<client-secret>
|
||||
```
|
||||
|
||||
##### Github
|
||||
|
||||
```bash
|
||||
PENPOT_GITHUB_CLIENT_ID=<client-id>
|
||||
PENPOT_GITHUB_CLIENT_SECRET=<client-secret>
|
||||
```
|
||||
|
||||
##### LDAP
|
||||
|
||||
```bash
|
||||
PENPOT_LDAP_AUTH_HOST=
|
||||
PENPOT_LDAP_AUTH_PORT=
|
||||
PENPOT_LDAP_AUTH_VERSION=3
|
||||
PENPOT_LDAP_BIND_DN=
|
||||
PENPOT_LDAP_BIND_PASSWORD=
|
||||
PENPOT_LDAP_AUTH_SSL=false
|
||||
PENPOT_LDAP_AUTH_STARTTLS=false
|
||||
PENPOT_LDAP_AUTH_BASE_DN=
|
||||
PENPOT_LDAP_AUTH_USER_QUERY=(|(uid=$username)(mail=$username))
|
||||
PENPOT_LDAP_AUTH_USERNAME_ATTRIBUTE=uid
|
||||
PENPOT_LDAP_AUTH_EMAIL_ATTRIBUTE=mail
|
||||
PENPOT_LDAP_AUTH_FULLNAME_ATTRIBUTE=displayName
|
||||
PENPOT_LDAP_AUTH_AVATAR_ATTRIBUTE=jpegPhoto
|
||||
```
|
||||
|
||||
## Frontend ##
|
||||
|
||||
In comparison with backend frontend only has a few number of runtime
|
||||
configuration options and are located in the
|
||||
`<dist-root>/js/config.js` file. This file is completly optional; if
|
||||
it exists, it is loaded by the main index.html.
|
||||
|
||||
The `config.js` consists in a bunch of globar variables that are read
|
||||
by the frontend application on the bootstrap.
|
||||
|
||||
|
||||
### Auth with 3rd party
|
||||
|
||||
If any of the following variables are defined, they will enable the
|
||||
corresponding auth button in the login page
|
||||
|
||||
```js
|
||||
var penpotGoogleClientID = "<google-client-id-here>";
|
||||
var penpotGitlabClientID = "<gitlab-client-id-here>";
|
||||
var penpotGithubClientID = "<github-client-id-here>";
|
||||
var penpotLoginWithLDAP = <true|false>;
|
||||
```
|
||||
|
||||
You can disable new user registration, if you want only 3rd party
|
||||
authorized users:
|
||||
|
||||
```js
|
||||
var penpotRegistrationEnabled = <true|false>;
|
||||
```
|
||||
|
||||
**NOTE:** The configuration should match the backend configuration for
|
||||
respective services.
|
||||
|
||||
|
||||
### Demo warning and Demo users
|
||||
|
||||
It is possible to display a warning message on a demo environment and
|
||||
disable/enable demo users:
|
||||
|
||||
```js
|
||||
var penpotDemoWarning = <true|false>;
|
||||
var penpotAllowDemoUsers = <true|false>;
|
||||
```
|
||||
|
||||
**NOTE:** The configuration for demo users should match the backend
|
||||
configuration.
|
||||
|
||||
|
||||
## Exporter ##
|
||||
|
||||
The exporter application only have a single configuration option and
|
||||
it can be provided using environment variables in the same way as
|
||||
backend.
|
||||
|
||||
|
||||
```bash
|
||||
PENPOT_PUBLIC_URI=http://pubic-domain
|
||||
```
|
||||
|
||||
This environment variable indicates where the exporter can access to
|
||||
the public frontend application (because it uses special pages from it
|
||||
to render the shapes in the underlying headless web browser).
|
|
@ -1,65 +0,0 @@
|
|||
---
|
||||
title: 3.4. Common guide
|
||||
---
|
||||
|
||||
# Common guide
|
||||
|
||||
This section intends to have articles that related to both frontend
|
||||
and backend, such as: code style hints, architecture dicisions, etc...
|
||||
|
||||
|
||||
## Assertions
|
||||
|
||||
Penpot source code has this types of assertions:
|
||||
|
||||
**assert**: just using the clojure builtin `assert` macro.
|
||||
|
||||
Example:
|
||||
|
||||
```clojure
|
||||
(assert (number? 3) "optional message")
|
||||
```
|
||||
|
||||
This asserts are only executed on development mode. On production
|
||||
environment all assets like this will be ignored by runtime.
|
||||
|
||||
**spec/assert**: using the `app.common.spec/assert` macro.
|
||||
|
||||
Also, if you are using clojure.spec, you have the spec based
|
||||
`clojure.spec.alpha/assert` macro. In the same way as the
|
||||
`clojure.core/assert`, on production environment this asserts will be
|
||||
removed by the compiler/runtime.
|
||||
|
||||
Example:
|
||||
|
||||
````clojure
|
||||
(require '[clojure.spec.alpha :as s]
|
||||
'[app.common.spec :as us])
|
||||
|
||||
(s/def ::number number?)
|
||||
|
||||
(us/assert ::number 3)
|
||||
```
|
||||
|
||||
In the same way as the `assert` macro, this performs the spec
|
||||
assertion only on development build. On production this code will
|
||||
completely removed.
|
||||
|
||||
**spec/verify**: An assertion type that is executed always.
|
||||
|
||||
Example:
|
||||
|
||||
```clojure
|
||||
(require '[app.common.spec :as us])
|
||||
|
||||
(us/verify ::number 3)
|
||||
```
|
||||
|
||||
This macro enables you have assetions on production code.
|
||||
|
||||
**Why don't use the `clojure.spec.alpha/assert` instead of the `app.common.spec/assert`?**
|
||||
|
||||
The Penpot variant does not peforms additional runtime checks for know
|
||||
if asserts are disabled in "runtime". As a result it generates much
|
||||
simplier code at development and production builds.
|
||||
|
|
@ -1,138 +0,0 @@
|
|||
---
|
||||
title: 3.1. Development environment
|
||||
---
|
||||
|
||||
# Development environment
|
||||
|
||||
## System requirements
|
||||
|
||||
You should have `docker` and `docker-compose` installed in your system
|
||||
in order to set up properly the development enviroment.
|
||||
|
||||
In debian like linux distributions you can install it executing:
|
||||
|
||||
```bash
|
||||
sudo apt-get install docker docker-compose
|
||||
```
|
||||
|
||||
Start and enable docker environment:
|
||||
|
||||
|
||||
```bash
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
```
|
||||
|
||||
Add your user to the docker group:
|
||||
|
||||
```bash
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
And finally, increment user watches:
|
||||
|
||||
```
|
||||
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
|
||||
```
|
||||
|
||||
NOTE: you probably need to login again for group change take the effect.
|
||||
|
||||
|
||||
## Start the devenv
|
||||
|
||||
**Requires a minimum knowledge of tmux usage in order to use that
|
||||
development environment.**
|
||||
|
||||
For start it, staying in this repository, execute:
|
||||
|
||||
```bash
|
||||
./manage.sh pull-devenv
|
||||
./manage.sh run-devenv
|
||||
```
|
||||
|
||||
This will do the following:
|
||||
|
||||
- Pulls the latest devenv image.
|
||||
- Starts all the containers in the background.
|
||||
- Attaches to the **devenv** container and executes the tmux session.
|
||||
- The tmux session automatically starts all the necessary services.
|
||||
|
||||
You can execute the individual steps manully if you want:
|
||||
|
||||
```bash
|
||||
./manage.sh build-devenv # builds the devenv docker image (not necessary in normal sircumstances)
|
||||
./manage.sh start-devenv # starts background running containers
|
||||
./manage.sh run-devenv # enters to new tmux session inside of one of the running containers
|
||||
./manage.sh stop-devenv # stops background running containers
|
||||
./manage.sh drop-devenv # removes all the volumes, containers and networks used by the devenv
|
||||
```
|
||||
|
||||
Now having the the container running and tmux open inside the
|
||||
container, you are free to execute any commands and open many shells
|
||||
as you want.
|
||||
|
||||
You can create a new shell just pressing the **Ctr+b c** shortcut. And
|
||||
**Ctrl+b w** for switch between windows, **Ctrl+b &** for kill the
|
||||
current window.
|
||||
|
||||
For more info: https://tmuxcheatsheet.com/
|
||||
|
||||
|
||||
### Inside the tmux session
|
||||
|
||||
#### gulp
|
||||
|
||||
The styles and many related tasks are executed thanks to gulp and they are
|
||||
executed in the tmux **window 0**. This is a normal gulp watcher with some
|
||||
additional tasks.
|
||||
|
||||
|
||||
#### shadow-cljs
|
||||
|
||||
The frontend build process is located on the tmux **window 1**.
|
||||
**Shadow-cljs** is used for build and serve the frontend code. For
|
||||
more information, please refer to `02-Frontend-Developer-Guide.md`.
|
||||
|
||||
By default the **window 1** executes the shadow-cljs watch process,
|
||||
that starts a new JVM/Clojure instance if there is no one running.
|
||||
|
||||
Finally, you can start a REPL linked to the instance and the current
|
||||
connected browser, by opening a third window with `Ctrl+c` and running
|
||||
`npx shadow-cljs cljs-repl main`.
|
||||
|
||||
|
||||
#### exporter
|
||||
|
||||
The exporter app (clojurescript app running in nodejs) is located in
|
||||
**window 2**, and you can go directly to it using `ctrl+b 2` shortcut.
|
||||
|
||||
There you will found the window split in two slices. On the top slice
|
||||
you will have the build process (using shadow-cljs in the same way as
|
||||
frontend application), and on the bot slice the script that launeches
|
||||
the node process.
|
||||
|
||||
If some reason scripts does not stars correctly, you can manually
|
||||
execute `node target/app.js ` to start the exporter app.
|
||||
|
||||
|
||||
#### backend
|
||||
|
||||
The backend related environment is located in the tmux **window 3**,
|
||||
and you can go directly to it using `ctrl+b 2` shortcut.
|
||||
|
||||
By default the backend will be started in non-interactive mode for
|
||||
convenience but you can just press `Ctrl+c` and execute `./scripts/repl`
|
||||
for start the repl.
|
||||
|
||||
On the REPL you have this helper functions:
|
||||
- `(start)`: start all the environment
|
||||
- `(stop)`: stops the environment
|
||||
- `(restart)`: stops, reload and start again.
|
||||
|
||||
And many other that are defined in the `dev/user.clj` file.
|
||||
|
||||
If some exception is raised when code is reloaded, just use
|
||||
`(repl/refresh-all)` in order to finish correctly the code swaping and
|
||||
later use `(restart)` again.
|
||||
|
||||
For more information, please refer to: `03-Backend-Guide.md`.
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
title: 3. Core developer guide
|
||||
---
|
||||
|
||||
# Core developer guide
|
||||
|
||||
This is a generic "getting started" guide for the Penpot platform. It
|
||||
intends to explain how to get the development environment up and
|
||||
running with many additional tips.
|
||||
|
||||
The main development environment consists in a docker compose
|
||||
configuration that starts the external services and the development
|
||||
container (called **devenv**).
|
||||
|
||||
We use tmux script in order to multiplex the single terminal and run
|
||||
both the backend and frontend in the same container.
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
---
|
||||
title: 3.6. Miscellaneous
|
||||
---
|
||||
|
||||
# Miscellaneous
|
||||
|
||||
## Collaborative Edition & Persistence protocol
|
||||
|
||||
This is a collection of design notes for collaborative edition feature
|
||||
and persistence protocol (STILL IN CONSTRUCTION).
|
||||
|
||||
|
||||
### Persistence Operations
|
||||
|
||||
This is a page data structure:
|
||||
|
||||
```clojure
|
||||
{:version 2
|
||||
:options {}
|
||||
|
||||
:rmap
|
||||
{:id1 :default
|
||||
:id2 :default
|
||||
:id3 :id1}
|
||||
|
||||
:objects
|
||||
{:root
|
||||
{:type :root
|
||||
:shapes [:id1 :id2]}
|
||||
|
||||
:id1
|
||||
{:type :canvas
|
||||
:shapes [:id3]}
|
||||
|
||||
:id2 {:type :rect}
|
||||
:id3 {:type :circle}}}
|
||||
```
|
||||
|
||||
|
||||
This is a potential list of persistent ops:
|
||||
|
||||
```clojure
|
||||
{:type :mod-obj
|
||||
:operations [<op>, ...]
|
||||
|
||||
{:type :add-obj
|
||||
:id <uuid>
|
||||
:parent <uuid>
|
||||
:obj <shape-object>}
|
||||
|
||||
{:type :mod-obj
|
||||
:id <uuid>
|
||||
:operations [<op>, ...]}
|
||||
|
||||
{:type :mov-obj
|
||||
:id <uuid>
|
||||
:frame-id <uuid>}
|
||||
|
||||
{:type :del-obj
|
||||
:id <uuid>}
|
||||
```
|
||||
|
||||
This is a potential list of operations:
|
||||
|
||||
```clojure
|
||||
{:type :set
|
||||
:attr <any>
|
||||
:val <any>}
|
||||
|
||||
{:type :abs-order
|
||||
:id <uuid>
|
||||
:index <int>}
|
||||
|
||||
{:type :rel-order
|
||||
:id <uuid>
|
||||
:loc <one-of:up,down,top,bottom>}
|
||||
```
|
||||
|
||||
|
||||
### Ephemeral communication (Websocket protocol)
|
||||
|
||||
|
||||
#### `join`
|
||||
|
||||
Sent by clients for notify joining a concrete page-id inside a file.
|
||||
|
||||
```clojure
|
||||
{:type :join
|
||||
:page-id <id>
|
||||
:version <number>
|
||||
}
|
||||
```
|
||||
|
||||
Will cause:
|
||||
|
||||
- A posible `:page-changes`.
|
||||
- Broadcast `:joined` message to all users of the file.
|
||||
|
||||
The `joined` message has this aspect:
|
||||
|
||||
```clojure
|
||||
{:type :joined
|
||||
:page-id <id>
|
||||
:user-id <id>
|
||||
}
|
||||
```
|
||||
|
||||
#### `who`
|
||||
|
||||
Sent by clients for request the list of users in the channel.
|
||||
|
||||
```clojure
|
||||
{:type :who}
|
||||
```
|
||||
|
||||
Will cause:
|
||||
|
||||
- Reply to the client with the current users list:
|
||||
|
||||
```clojure
|
||||
{:type :who
|
||||
:users #{<id>,...}}
|
||||
```
|
||||
|
||||
This will be sent all the time user joins or leaves the channel for
|
||||
maintain the frontend updated with the lates participants. This
|
||||
message is also sent at the beggining of connection from server to
|
||||
client.
|
||||
|
||||
|
||||
#### `pointer-update`
|
||||
|
||||
This is sent by client to server and then, broadcasted to the rest of
|
||||
channel participants.
|
||||
|
||||
```clojure
|
||||
{:type :pointer-update
|
||||
:page-id <id>
|
||||
:x <number>
|
||||
:y <number>
|
||||
}
|
||||
```
|
||||
|
||||
The server broadcast message will look like:
|
||||
|
||||
```clojure
|
||||
{:type :pointer-update
|
||||
:user-id <id>
|
||||
:page-id <id>
|
||||
:x <number>
|
||||
:y <number>
|
||||
}
|
||||
```
|
||||
|
||||
#### `:page-snapshot`
|
||||
|
||||
A message that server sends to client for notify page changes. It can be sent
|
||||
on `join` and when a page change is commited to the database.
|
||||
|
||||
```clojure
|
||||
{:type :page-snapshot
|
||||
:user-id <id>
|
||||
:page-id <id>
|
||||
:version <number>
|
||||
:operations [<op>, ...]
|
||||
}
|
||||
```
|
||||
|
||||
This message is only sent to users that does not perform this change.
|
||||
|
|
@ -1,50 +0,0 @@
|
|||
---
|
||||
title: 3.5. Testing guide
|
||||
---
|
||||
|
||||
# Testing guide
|
||||
|
||||
## Backend / Common
|
||||
|
||||
You can run the tests directly with:
|
||||
|
||||
```bash
|
||||
~/penpot/backend$ clojure -M:dev:tests
|
||||
```
|
||||
|
||||
Alternatively, you can run them from a REPL. First starting a REPL.
|
||||
|
||||
```bash
|
||||
~/penpot/backend$ scripts/repl
|
||||
```
|
||||
|
||||
And then:
|
||||
|
||||
```bash
|
||||
user=> (run-tests)
|
||||
user=> (run-tests 'namespace)
|
||||
user=> (run-tests 'namespace/test)
|
||||
```
|
||||
|
||||
## Frontend
|
||||
|
||||
Frontend tests have to be compiled first, and then run with node.
|
||||
|
||||
```bash
|
||||
npx shadow-cljs compile tests && node target/tests.js
|
||||
```
|
||||
|
||||
Or run the watch (that automatically runs the test):
|
||||
|
||||
```bash
|
||||
npx shadow-cljs watch tests
|
||||
```
|
||||
|
||||
## Linter
|
||||
|
||||
We can execute the linter for the whole codebase with the following command:
|
||||
|
||||
```bash
|
||||
clj-kondo --lint common:backend/src:frontend/src
|
||||
```
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"layout": "layouts/developer-guide.njk",
|
||||
"tags": "developer-guide"
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
---
|
||||
title: Developer guide
|
||||
eleventyNavigation:
|
||||
key: Developer guide
|
||||
order: 3
|
||||
---
|
||||
|
||||
# Developer guide
|
||||
|
||||
This documentation intends to explain how to get penpot application and run it
|
||||
locally, to test it or make changes to it.
|
||||
|
||||
> If you only want to run it or change external parts, the simplest approach is
|
||||
to use the official docker image, as explained below.
|
||||
|
||||
> If you want to modify the core application, see instead the
|
||||
[Development Environment guide](/developer-guide/core-developer/development-environment).
|
||||
|
||||
|
||||
## Install Docker ##
|
||||
|
||||
Skip this section if you already have docker installed, up and running.
|
||||
|
||||
You can install docker and its dependencies from your distribution repository
|
||||
with:
|
||||
|
||||
```bash
|
||||
sudo apt-get install docker docker-compose
|
||||
```
|
||||
|
||||
Or follow installation instructions from docker.com; (for Debian
|
||||
https://docs.docker.com/engine/install/debian/).
|
||||
|
||||
Ensure that the docker is started and optionally enable it to start with the
|
||||
system:
|
||||
|
||||
```bash
|
||||
sudo systemctl start docker
|
||||
sudo systemctl enable docker
|
||||
```
|
||||
|
||||
And finally, add your user to the docker group:
|
||||
|
||||
```bash
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
This will make use of the docker without `sudo` command all the time.
|
||||
|
||||
NOTE: probably you will need to re-login again to make this change take effect.
|
||||
|
||||
|
||||
## Start penpot application ##
|
||||
|
||||
You can create it from scratch or take a base from the [penpot repository][1]
|
||||
|
||||
[1]: https://raw.githubusercontent.com/penpot/penpot/develop/docker/images/docker-compose.yaml
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/penpot/penpot/develop/docker/images/docker-compose.yaml
|
||||
```
|
||||
|
||||
And then:
|
||||
|
||||
```bash
|
||||
docker-compose -p penpot -f docker-compose.yaml up
|
||||
```
|
||||
|
||||
The docker compose file contains the essential configuration for getting the
|
||||
application running, and many essential configurations already explained in the
|
||||
comments. All other configuration options are explained in the [Configuration
|
||||
guide](/developer-guide/configuration).
|
18
index.njk
18
index.njk
|
@ -18,23 +18,23 @@ eleventyNavigation:
|
|||
<span class="advice"> WIP </span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/developer-guide/">
|
||||
<h3>Developer guide →</h3>
|
||||
<p>Comprehensive documentation about architecture, configuration and core.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/faqs">
|
||||
<h3>Frequently asked questions →</h3>
|
||||
<p>Get quick answers to usual questions about "why and how" Penpot.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/technical-guide/">
|
||||
<h3>Technical guide →</h3>
|
||||
<p>Comprehensive documentation about installation, configuration and architecture.</p>
|
||||
</a>
|
||||
</li>
|
||||
<li class="no-link">
|
||||
<!-- a href="" -->
|
||||
<h3>Contact us →</h3>
|
||||
<p>Write us at <a href="mailto:info@penpot.app" target="_blank">info@penpot.app</a> or join the <a href="https://github.com/penpot/penpot/discussions" target="_blank">team discusions</a>.</p>
|
||||
<!-- p>Write us an email, join team discussions or chat with us.</p-->
|
||||
<h3>Contact us →</h3>
|
||||
<p>Write us at <a href="mailto:info@penpot.app" target="_blank">info@penpot.app</a> or join the <a href="https://github.com/penpot/penpot/discussions" target="_blank">team discusions</a>.</p>
|
||||
<!-- p>Write us an email, join team discussions or chat with us.</p-->
|
||||
<!-- /a -->
|
||||
</li>
|
||||
<li class="github">
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: 1. Architecture
|
||||
title: 3. Architecture
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
@ -97,7 +97,7 @@ worker, that may be used to queue tasks to be scheduled and executed when the
|
|||
backend is idle. Other tasks are email sending, collecting data for telemetry
|
||||
and detecting unused media attachment, for removing them from the file storage.
|
||||
|
||||
## Broker
|
||||
## PubSub
|
||||
|
||||
To manage subscriptions to a file, to be notified of changes, we use a redis
|
||||
server as a pub/sub broker. Whenever a user visits a file and opens a
|
331
technical-guide/configuration.md
Normal file
331
technical-guide/configuration.md
Normal file
|
@ -0,0 +1,331 @@
|
|||
---
|
||||
title: 2. Configuration
|
||||
---
|
||||
|
||||
# Configuration #
|
||||
|
||||
This section intends to explain all available configuration options.
|
||||
|
||||
The main and unique approach to configure penpot application is
|
||||
using environment variables. All penpot related variables start with
|
||||
`PENPOT_` prefix.
|
||||
|
||||
**NOTE**: All the examples that have values represent the
|
||||
**default** values, and the examples that do not have values are
|
||||
optional.
|
||||
|
||||
## Common ##
|
||||
|
||||
This section will list all common configuration that affects backend
|
||||
and frontend, and they need to be in sync to work correctly.
|
||||
|
||||
|
||||
### Registration ###
|
||||
|
||||
Penpot comes with an option to completely disable the registration
|
||||
process or restrict it to some domains.
|
||||
|
||||
If you want to completelly disable registration, use the following
|
||||
variable in both fontend & backend:
|
||||
|
||||
```bash
|
||||
# backend & frontend
|
||||
PENPOT_REGISTRATION_ENABLED=false
|
||||
```
|
||||
|
||||
You also can restict the registrations to a closed list of domains:
|
||||
|
||||
```bash
|
||||
# comma separated list of domains (backend only)
|
||||
PENPOT_REGISTRATION_DOMAIN_WHITELIST=""
|
||||
```
|
||||
|
||||
### Demo users ###
|
||||
|
||||
Penpot comes with facilities for fast creation of demo users without the need
|
||||
of a registration process. The demo users by default have an expiration time of
|
||||
7 days, and once expired they are completly deleted with all the generated
|
||||
content. Very useful for testing or demostration purposes.
|
||||
|
||||
You can enable demo users using the following variable:
|
||||
|
||||
```
|
||||
# backend & frontend
|
||||
PENPOT_ALLOW_DEMO_USERS=true
|
||||
```
|
||||
|
||||
### OAuth Providers
|
||||
|
||||
#### Google
|
||||
|
||||
Allow use google as oauth provider:
|
||||
|
||||
|
||||
On backend:
|
||||
|
||||
```bash
|
||||
# Backend & Frontend
|
||||
PENPOT_GOOGLE_CLIENT_ID=<client-id>
|
||||
|
||||
# Backend only:
|
||||
PENPOT_GOOGLE_CLIENT_SECRET=<client-secret>
|
||||
```
|
||||
|
||||
#### Gitlab
|
||||
|
||||
Allows use gitlab as oauth provider:
|
||||
|
||||
```bash
|
||||
# Backend & Frontend
|
||||
PENPOT_GITLAB_CLIENT_ID=<client-id>
|
||||
|
||||
# Backend only
|
||||
PENPOT_GITLAB_BASE_URI=https://gitlab.com
|
||||
PENPOT_GITLAB_CLIENT_SECRET=<client-secret>
|
||||
```
|
||||
|
||||
#### Github
|
||||
|
||||
Allows use github as oauth provider:
|
||||
|
||||
|
||||
```bash
|
||||
# Backend & Frontend
|
||||
PENPOT_GITHUB_CLIENT_ID=<client-id>
|
||||
|
||||
# Backend only
|
||||
PENPOT_GITHUB_CLIENT_SECRET=<client-secret>
|
||||
```
|
||||
|
||||
### LDAP ###
|
||||
|
||||
Penpot comes with support for *Lightweight Directory Access Protocol*
|
||||
(LDAP). This is the example configuration we use internally for testing
|
||||
this authentication backend.
|
||||
|
||||
```bash
|
||||
# Backend
|
||||
PENPOT_LDAP_HOST=ldap
|
||||
PENPOT_LDAP_PORT=10389
|
||||
PENPOT_LDAP_SSL=false
|
||||
PENPOT_LDAP_STARTTLS=false
|
||||
PENPOT_LDAP_BASE_DN=ou=people,dc=planetexpress,dc=com
|
||||
PENPOT_LDAP_BIND_DN=cn=admin,dc=planetexpress,dc=com
|
||||
PENPOT_LDAP_BIND_PASSWORD=GoodNewsEveryone
|
||||
PENPOT_LDAP_ATTRS_USERNAME=uid
|
||||
PENPOT_LDAP_ATTRS_EMAIL=mail
|
||||
PENPOT_LDAP_ATTRS_FULLNAME=cn
|
||||
PENPOT_LDAP_ATTRS_PHOTO=jpegPhoto
|
||||
|
||||
# Frontend
|
||||
PENPOT_LOGIN_WITH_LDAP=true
|
||||
```
|
||||
|
||||
If you miss something, please open an issue and we discuss it.
|
||||
|
||||
|
||||
## Backend ##
|
||||
|
||||
This section enumerates the backend only configuration variables.
|
||||
|
||||
|
||||
### Database
|
||||
|
||||
We only support PostgreSQL and we highly recommend >=13 version. If
|
||||
you are using official docker images this is already solved for you.
|
||||
|
||||
Essential database configuration:
|
||||
|
||||
```bash
|
||||
PENPOT_DATABASE_USERNAME=penpot
|
||||
PENPOT_DATABASE_PASSWORD=penpot
|
||||
PENPOT_DATABASE_URI=postgresql://127.0.0.1/penpot
|
||||
```
|
||||
|
||||
The username and password are optional.
|
||||
|
||||
|
||||
### Email (SMTP)
|
||||
|
||||
By default, when no SMTP (email) is configured, the email will be printed to
|
||||
the console, which means that the emails will be shown in the stdout. If you
|
||||
have an SMTP service, uncomment the appropiate settings section in
|
||||
`docker-compose.yml` and configure those environment variables.
|
||||
|
||||
Setting up the default FROM and REPLY-TO:
|
||||
|
||||
```bash
|
||||
PENPOT_SMTP_DEFAULT_REPLY_TO=Penpot <no-reply@example.com>
|
||||
PENPOT_SMTP_DEFAULT_FROM=Penpot <no-reply@example.com>
|
||||
```
|
||||
|
||||
Enable SMTP:
|
||||
|
||||
```bash
|
||||
PENPOT_SMTP_ENABLED=true
|
||||
PENPOT_SMTP_HOST=<host>
|
||||
PENPOT_SMTP_PORT=587
|
||||
PENPOT_SMTP_USER=<username>
|
||||
PENPOT_SMTP_PASSWORD=<password>
|
||||
PENPOT_SMTP_TLS=true
|
||||
```
|
||||
|
||||
|
||||
### Storage
|
||||
|
||||
Storage refers to storage used for store the user uploaded assets.
|
||||
|
||||
Assets storage is implemented using "plugable" backends. Currently
|
||||
there are three backends available: `db`, `fs` and `s3` (for AWS S3).
|
||||
|
||||
#### FS Backend (default) ####
|
||||
|
||||
This is the default backend when you use the official docker images and
|
||||
the default configuration looks like this:
|
||||
|
||||
```bash
|
||||
PENPOT_STORAGE_BACKEND=fs
|
||||
PENPOT_STORAGE_FS_DIRECTORY=/opt/data/assets
|
||||
```
|
||||
|
||||
The main downside of this backend is the hard dependency on nginx
|
||||
approach to serve files managed by an application (not a simple
|
||||
directory serving static files). But you should not worry about this
|
||||
unless you want to install it outside the docker container and
|
||||
configure the nginx yourself.
|
||||
|
||||
In case you want undestand how it internally works, you can take a look
|
||||
on the [nginx configuration file][1] used in the docker images.
|
||||
|
||||
[1]: https://github.com/penpot/penpot/blob/main/docker/images/files/nginx.conf
|
||||
|
||||
|
||||
#### DB Backend ####
|
||||
|
||||
This backend stores all the user uploaded assets on the database and
|
||||
is ideal for small setups when you don't want to worry about backups
|
||||
apart from the database.
|
||||
|
||||
In case you want to use this backend, proceed using the following
|
||||
environment variable:
|
||||
|
||||
```bash
|
||||
PENPOT_STORAGE_BACKEND=db
|
||||
```
|
||||
|
||||
|
||||
#### AWS S3 Backend ####
|
||||
|
||||
This backend uses AWS S3 bucket for store the user uploaded
|
||||
assets. For use it you should have an appropriate account on AWS cloud
|
||||
and have the credentials, region and the bucket.
|
||||
|
||||
This is how configuration looks for S3 backend:
|
||||
|
||||
```bash
|
||||
# AWS Credentials
|
||||
AWS_ACCESS_KEY_ID=<you-access-key-id-here>
|
||||
AWS_SECRET_ACCESS_KEY=<your-secret-access-key-here>
|
||||
|
||||
# Backend configuration
|
||||
PENPOT_STORAGE_BACKEND=s3
|
||||
PENPOT_STORAGE_S3_REGION=<aws-region>
|
||||
PENPOT_STORAGE_S3_BUCKET=<bucket-name>
|
||||
```
|
||||
|
||||
Right now, only `eu-central-1` region is supported. If you need
|
||||
others, open an issue.
|
||||
|
||||
|
||||
### Redis
|
||||
|
||||
The redis configuration is very simple, just provide with a valid
|
||||
redis URI. Redis is used mainly for websocket notifications
|
||||
coordination.
|
||||
|
||||
```bash
|
||||
PENPOT_REDIS_URI=redis://localhost/0
|
||||
```
|
||||
|
||||
If you are using the official docker compose file, this is already
|
||||
configured.
|
||||
|
||||
|
||||
### HTTP
|
||||
|
||||
You can set the port where the backend http server will listen for requests.
|
||||
|
||||
```bash
|
||||
PENPOT_HTTP_SERVER_PORT=6060
|
||||
```
|
||||
|
||||
Additionally, you probably will need to set the `PENPOT_PUBLIC_URI`
|
||||
environment variable in case you go to serve penpot to the users, and
|
||||
it should point to public URI where users will access the application:
|
||||
|
||||
```bash
|
||||
PENPOT_PUBLIC_URI=http://localhost:9001
|
||||
```
|
||||
|
||||
### Server REPL
|
||||
|
||||
This is a more advanced setting, because it allows to set a port where the
|
||||
server REPL will listen. Server REPL is very useful for performing diagnosis,
|
||||
executing code on the running process, and/or making hotfixes of isolated pure
|
||||
functions without restarting the process.
|
||||
|
||||
The default configuration is:
|
||||
|
||||
```bash
|
||||
PENPOT_SREPL_HOST=127.0.0.1
|
||||
PENPOT_SREPL_PORT=6062
|
||||
```
|
||||
|
||||
You can connect to the repl using `netcat` or `telnet` in combination
|
||||
with `rlwrap`. Example:
|
||||
|
||||
```bash
|
||||
$ rlwrap netcat localhost 6062
|
||||
user=>
|
||||
```
|
||||
|
||||
|
||||
## Frontend ##
|
||||
|
||||
In comparison with backend, frontend only has a small number of runtime
|
||||
configuration options, and they are located in the `<dist>/js/config.js`
|
||||
file.
|
||||
|
||||
If you are using the official docker images, the best approach to set
|
||||
any configuration is using environment variables, and the image
|
||||
automatically generates the `config.js` from them.
|
||||
|
||||
**NOTE**: many frontend related configuration variables are explained in the
|
||||
[Common](#common) section, this section explains **frontend only** options.
|
||||
|
||||
|
||||
### Demo warning ###
|
||||
|
||||
If you want to show a warning in the register and login page saying
|
||||
that this is a demostration purpose instance (no backups, periodical
|
||||
data wipe, ...), set the following variable:
|
||||
|
||||
```bash
|
||||
PENPOT_DEMO_WARNING=true
|
||||
```
|
||||
|
||||
|
||||
## Exporter ##
|
||||
|
||||
The exporter application only have a single configuration option and
|
||||
it can be provided using environment variables in the same way as
|
||||
backend.
|
||||
|
||||
|
||||
```bash
|
||||
PENPOT_PUBLIC_URI=http://pubic-domain
|
||||
```
|
||||
|
||||
This environment variable indicates where the exporter can access to
|
||||
the public frontend application (because it uses special pages from it
|
||||
to render the shapes in the underlying headless web browser).
|
|
@ -1,14 +1,14 @@
|
|||
---
|
||||
title: 3.3. Backend guide
|
||||
title: 4.4. Backend Guide
|
||||
---
|
||||
|
||||
# Backend guide
|
||||
# Backend guide #
|
||||
|
||||
This guide intends to explain the essential details of the backend
|
||||
application.
|
||||
|
||||
|
||||
## Fixtures
|
||||
## Fixtures ##
|
||||
|
||||
This is a development feature that allows populate the database with a
|
||||
good amount of content (usually used for just test the application or
|
||||
|
@ -34,22 +34,8 @@ in the aplication. All users uses the following pattern:
|
|||
|
||||
Where `N` is a number from 0 to 5 on the default fixture parameters.
|
||||
|
||||
If you have a REPL access to the running process, you can execute it
|
||||
from there:
|
||||
|
||||
```clojure
|
||||
(require 'app.cli.fixtures)
|
||||
(app.cli.fixtures/run :small)
|
||||
```
|
||||
|
||||
To access to the running process repl you usually will execute this
|
||||
command:
|
||||
|
||||
```bash
|
||||
rlwrap netcat localhost 6062
|
||||
```
|
||||
|
||||
## Migrations
|
||||
## Migrations ##
|
||||
|
||||
The database migrations are located in two directories:
|
||||
|
||||
|
@ -69,7 +55,7 @@ Examples:
|
|||
0026-mod-profile-table-add-is-active-field
|
||||
```
|
||||
|
||||
**NOTE**: if table name has more than one words, we still use `-` as a separator.
|
||||
**NOTE**: if table name has more than one word, we still use `-` as a separator.
|
||||
|
||||
If you need to have a global overview of the all schema of the database you can extract it
|
||||
using postgresql:
|
||||
|
@ -79,3 +65,40 @@ using postgresql:
|
|||
pg_dump -h postgres -s > schema.sql
|
||||
```
|
||||
|
||||
|
||||
## Tests ##
|
||||
|
||||
You can run the tests directly with:
|
||||
|
||||
```bash
|
||||
~/penpot/backend$ clojure -M:dev:tests
|
||||
```
|
||||
|
||||
Alternatively, you can run them from a REPL. First start a REPL.
|
||||
|
||||
```bash
|
||||
~/penpot/backend$ scripts/repl
|
||||
```
|
||||
|
||||
And then:
|
||||
|
||||
```bash
|
||||
user=> (run-tests)
|
||||
user=> (run-tests 'namespace)
|
||||
user=> (run-tests 'namespace/test)
|
||||
```
|
||||
|
||||
## Linter ##
|
||||
|
||||
There are no watch process for the linter; you will need to execute it
|
||||
manually. We use [clj-kondo][kondo] for linting purposes and the
|
||||
repository already comes with base configuration.
|
||||
|
||||
[kondo]: https://github.com/clj-kondo/clj-kondo
|
||||
|
||||
You can run **clj-kondo** as-is (is included in the devenv image):
|
||||
|
||||
```bash
|
||||
cd penpot/backend;
|
||||
clj-kondo --lint src
|
||||
```
|
67
technical-guide/developer/common.md
Normal file
67
technical-guide/developer/common.md
Normal file
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
title: 4.2. Common Guide
|
||||
---
|
||||
|
||||
# Common guide
|
||||
|
||||
This section has articles related to all submodules (frontend, backend and
|
||||
exporter) such as: code style hints, architecture decisions, etc...
|
||||
|
||||
|
||||
## Assertions
|
||||
|
||||
Penpot source code has this types of assertions:
|
||||
|
||||
### **assert**
|
||||
|
||||
Just using the clojure builtin `assert` macro.
|
||||
|
||||
Example:
|
||||
|
||||
```clojure
|
||||
(assert (number? 3) "optional message")
|
||||
```
|
||||
|
||||
This asserts are only executed in development mode. In production
|
||||
environment all asserts like this will be ignored by runtime.
|
||||
|
||||
### **spec/assert**
|
||||
|
||||
Using the `app.common.spec/assert` macro.
|
||||
|
||||
Also, if you are using clojure.spec, you have the spec based
|
||||
`clojure.spec.alpha/assert` macro. In the same way as the
|
||||
`clojure.core/assert`, in production environment these asserts will
|
||||
be removed by the compiler/runtime.
|
||||
|
||||
Example:
|
||||
|
||||
```clojure
|
||||
(require '[clojure.spec.alpha :as s]
|
||||
'[app.common.spec :as us])
|
||||
|
||||
(s/def ::number number?)
|
||||
|
||||
(us/assert ::number 3)
|
||||
```
|
||||
|
||||
**Why don't use the `clojure.spec.alpha/assert` instead of the `app.common.spec/assert`?**
|
||||
|
||||
The Penpot variant does not peforms additional runtime checks for know
|
||||
if asserts are disabled in "runtime". As a result it generates much
|
||||
simpler code at development and production builds.
|
||||
|
||||
### **spec/verify**
|
||||
|
||||
An assertion type that is always executed.
|
||||
|
||||
Example:
|
||||
|
||||
```clojure
|
||||
(require '[app.common.spec :as us])
|
||||
|
||||
(us/verify ::number 3)
|
||||
```
|
||||
|
||||
This macro enables you to have assertions on production code.
|
||||
|
135
technical-guide/developer/devenv.md
Normal file
135
technical-guide/developer/devenv.md
Normal file
|
@ -0,0 +1,135 @@
|
|||
---
|
||||
title: 4.1. Environment
|
||||
---
|
||||
|
||||
# Development environment
|
||||
|
||||
## System requirements
|
||||
|
||||
You should have `docker` and `docker-compose` installed in your system
|
||||
in order to set up properly the development enviroment.
|
||||
|
||||
You can [look here][1] for complete instructions.
|
||||
|
||||
[1]: /technical-guide/getting-started/#docker
|
||||
|
||||
|
||||
Optionally, increment user watches:
|
||||
|
||||
```
|
||||
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
|
||||
```
|
||||
|
||||
|
||||
## Getting Started
|
||||
|
||||
**It requires a minimum knowledge of [tmux](https://github.com/tmux/tmux/wiki)
|
||||
usage in order to use the development environment.**
|
||||
|
||||
To start it, clone penpot repository, and execute:
|
||||
|
||||
```bash
|
||||
./manage.sh pull-devenv
|
||||
./manage.sh run-devenv
|
||||
```
|
||||
|
||||
This will do the following:
|
||||
|
||||
1. Pull the latest devenv image from dockerhub.
|
||||
2. Start all the containers in the background.
|
||||
3. Attach the terminal to the **devenv** container and execute the tmux session.
|
||||
4. The tmux session automatically starts all the necessary services.
|
||||
|
||||
This is an incomplete list of devenv related subcommands found on
|
||||
manage.sh script:
|
||||
|
||||
```bash
|
||||
./manage.sh build-devenv # builds the devenv docker image (called by run-devenv automatically when needed)
|
||||
./manage.sh start-devenv # starts background running containers
|
||||
./manage.sh run-devenv # enters to new tmux session inside of one of the running containers
|
||||
./manage.sh stop-devenv # stops background running containers
|
||||
./manage.sh drop-devenv # removes all the containers, volumes and networks used by the devenv
|
||||
```
|
||||
|
||||
Having the the container running and tmux opened inside the container,
|
||||
you are free to execute any commands and open many shells as you want.
|
||||
|
||||
You can create a new shell just pressing the **Ctr+b c** shortcut. And
|
||||
**Ctrl+b w** for switch between windows, **Ctrl+b &** for kill the
|
||||
current window.
|
||||
|
||||
For more info: https://tmuxcheatsheet.com/
|
||||
|
||||
|
||||
<!-- ## Inside the tmux session -->
|
||||
|
||||
<!-- By default, the tmux session opens 4 windows: -->
|
||||
|
||||
<!-- - **gulp** (0): responsible of build, watch (and other related) of -->
|
||||
<!-- styles, images, fonts and templates. -->
|
||||
<!-- - **frontend** (1): responsible of cljs compilation process of frontend. -->
|
||||
<!-- - **exporter** (2): responsible of cljs compilation process of exporter. -->
|
||||
<!-- - **backend** (3): responsible of starting the backend jvm process. -->
|
||||
|
||||
|
||||
### Frontend
|
||||
|
||||
The frontend build process is located on the tmux **window 0** and
|
||||
**window 1**. On the **window 0** we have the gulp process responsible
|
||||
of watching and building styles, fonts, icon-spreads and templates.
|
||||
|
||||
On the **window 1** we can found the **shadow-cljs** process that is
|
||||
responsible on watch and build frontend clojurescript code.
|
||||
|
||||
Additionally to the watch process you probably want to be able open a REPL
|
||||
process on the frontend application, for this case you can split the window
|
||||
and execute this:
|
||||
|
||||
```bash
|
||||
npx shadow-cljs cljs-repl main
|
||||
```
|
||||
|
||||
### Exporter
|
||||
|
||||
The exporter build process is located in the **window 2** and in the
|
||||
same way as frontend application, it is build and watched using
|
||||
**shadow-cljs**.
|
||||
|
||||
The main difference is that exporter will be executed in a nodejs, on
|
||||
the server side instead of browser.
|
||||
|
||||
There you will found the window split in two slices. On the top slice
|
||||
you will have the build process and on the bot slice shell ready to
|
||||
execute the generated bundle.
|
||||
|
||||
You can start the exporter process executing:
|
||||
|
||||
```bash
|
||||
node target/app.js
|
||||
```
|
||||
|
||||
This process does not start automatically.
|
||||
|
||||
|
||||
### Backend
|
||||
|
||||
The backend related process is located in the tmux **window 3**, and
|
||||
you can go directly to it using `ctrl+b 3` shortcut.
|
||||
|
||||
By default the backend will be started in non-interactive mode for convenience
|
||||
but you can just press `Ctrl+c` and execute this to start the repl:
|
||||
|
||||
```bash
|
||||
./scripts/repl
|
||||
```
|
||||
|
||||
On the REPL you have these helper functions:
|
||||
- `(start)`: start all the environment
|
||||
- `(stop)`: stops the environment
|
||||
- `(restart)`: stops, reload and start again.
|
||||
|
||||
And many other that are defined in the `dev/user.clj` file.
|
||||
|
||||
If some exception is raised when code is reloaded, just use
|
||||
`(repl/refresh-all)` in order to finish correctly the code swaping and
|
||||
later use `(restart)` again.
|
|
@ -1,34 +1,33 @@
|
|||
---
|
||||
title: 3.2. Frontend guide
|
||||
title: 4.3. Frontend Guide
|
||||
---
|
||||
|
||||
# Frontend guide
|
||||
# Frontend Guide
|
||||
|
||||
This guide intends to explain the essential details of the frontend
|
||||
application.
|
||||
|
||||
|
||||
## Visual debug mode and utilities
|
||||
## Icons & Assets
|
||||
|
||||
Debugging a problem in the viewport algorithms for grouping and
|
||||
rotating is difficult. We have set a visual debug mode that displays
|
||||
some annotations on screen, to help understanding what's happening.
|
||||
The icons used on the frontend application are loaded using svgsprite
|
||||
(properly handled by the gulp watch task). All icons should be on SVG
|
||||
format located in `resources/images/icons`. The gulp task will
|
||||
generate the sprite and the embedd it into the `index.html` file.
|
||||
|
||||
To activate it, open the javascript console and type
|
||||
Then, you can reference the icon from the sprite using the
|
||||
`app.builtins.icons/icon-xref` macro:
|
||||
|
||||
```javascript
|
||||
app.util.debug.toggle_debug("option")
|
||||
```clojure
|
||||
(ns some.namespace
|
||||
(:require-macros [app.main.ui.icons :refer [icon-xref]]))
|
||||
|
||||
(icon-xref :arrow)
|
||||
```
|
||||
|
||||
Current options are `bounding-boxes`, `group`, `events` and
|
||||
`rotation-handler`.
|
||||
For performance reasons, all used icons are statically defined in the
|
||||
`src/app/main/ui/icons.cljs` file.
|
||||
|
||||
You can also activate or deactivate all visual aids with
|
||||
|
||||
```javascript
|
||||
app.util.debug.debug_all()
|
||||
app.util.debug.debug_none()
|
||||
```
|
||||
|
||||
## Logging, Tracing & Debugging
|
||||
|
||||
|
@ -45,16 +44,19 @@ type of the data.
|
|||
```
|
||||
|
||||
An alternative is using the pprint function, usefull for pretty
|
||||
printing a medium-big data sturcture for completly understand it.
|
||||
printing a medium-big data structure to completely understand it.
|
||||
|
||||
```clojure
|
||||
;; on the ns part
|
||||
(:require [cljs.pprint :refer [pprint]])
|
||||
|
||||
;; On the code
|
||||
(pprint expression)
|
||||
; Outputs a clojure value as a string, nicely formatted and with data type information.
|
||||
;; => Outputs a clojure value as a string, nicely formatted and with data type information.
|
||||
```
|
||||
|
||||
Use the js native functions for printing data. The clj->js converts
|
||||
the clojure data sturcture to js data sturcture and it is
|
||||
the clojure data structure to js data structure and it is
|
||||
inspeccionable in the devtools console.
|
||||
|
||||
```clojure
|
||||
|
@ -78,11 +80,11 @@ the console.
|
|||
|
||||
Additionally to the traditional way of putting traces in the code, we
|
||||
have a logging framework with steroids. It is usefull for casual
|
||||
debugging (as replacement for a `prn` and `js/console.log`) and as a
|
||||
debugging (as replacement for a `prn` and `js/console.log`) and for
|
||||
permanent traces in the code.
|
||||
|
||||
You have the ability to specify the logging level per namespace and
|
||||
all logging is ellided in production build.
|
||||
all logging is elided in production build.
|
||||
|
||||
Lets start with a simple example:
|
||||
|
||||
|
@ -90,7 +92,7 @@ Lets start with a simple example:
|
|||
(ns some.ns
|
||||
(:require [app.util.logging :as log]))
|
||||
|
||||
;; This function sets the level to the current namespace; messages
|
||||
;; This function sets the level of the current namespace; messages
|
||||
;; with level behind this will not be printed.
|
||||
(log/set-level! :info)
|
||||
|
||||
|
@ -105,7 +107,7 @@ Lets start with a simple example:
|
|||
(log/trace :msg "trace message")
|
||||
```
|
||||
|
||||
Each macro accept arbitrary number of key values pairs:
|
||||
Each macro accepts an arbitrary number of key values pairs:
|
||||
|
||||
```clojure
|
||||
(log/info :foo "bar" :msg "test" :value 1 :items #{1 2 3})
|
||||
|
@ -126,7 +128,8 @@ Some keys ara treated as special cases for helping in debugging:
|
|||
```
|
||||
|
||||
|
||||
## Access to clojure from javascript console
|
||||
|
||||
### Access to clojure from js console
|
||||
|
||||
The penpot namespace of the main application is exported, so that is
|
||||
accessible from javascript console in Chrome developer tools. Object
|
||||
|
@ -139,7 +142,7 @@ app.main.store.emit_BANG_(app.main.data.workspace.reset_zoom)
|
|||
```
|
||||
|
||||
|
||||
## Debug state and objects
|
||||
### Debug state and objects
|
||||
|
||||
There are also some useful functions to visualize the global state or
|
||||
any complex object. To use them from clojure:
|
||||
|
@ -169,31 +172,33 @@ dbg(js_expression) // equivalent to cljs.core.clj__GT_js(js_expression)
|
|||
```
|
||||
|
||||
|
||||
## Icons & Assets
|
||||
|
||||
The icons used on the frontend application are loaded using svgsprite
|
||||
(properly handled by the gulp watch task). All icons should be on SVG
|
||||
format located in `resources/images/icons`. The gulp task will
|
||||
generate the sprite and the embedd it into the `index.html`.
|
||||
|
||||
Then, you can reference the icon from the sprite using the
|
||||
`app.builtins.icons/icon-xref` macro:
|
||||
## Workspace visual debug
|
||||
|
||||
```clojure
|
||||
(ns some.namespace
|
||||
(:require-macros [app.main.ui.icons :refer [icon-xref]]))
|
||||
Debugging a problem in the viewport algorithms for grouping and
|
||||
rotating is difficult. We have set a visual debug mode that displays
|
||||
some annotations on screen, to help understanding what's happening.
|
||||
|
||||
(icon-xref :arrow)
|
||||
To activate it, open the javascript console and type:
|
||||
|
||||
```js
|
||||
app.util.debug.toggle_debug("option")
|
||||
```
|
||||
|
||||
For performance reasons, all used icons are statically defined in the
|
||||
`src/app/main/ui/icons.cljs` file.
|
||||
Current options are `bounding-boxes`, `group`, `events` and
|
||||
`rotation-handler`.
|
||||
|
||||
You can also activate or deactivate all visual aids with
|
||||
|
||||
```js
|
||||
app.util.debug.debug_all()
|
||||
app.util.debug.debug_none()
|
||||
```
|
||||
|
||||
## Translations (I18N) ##
|
||||
|
||||
### How it Works ###
|
||||
### How it works ###
|
||||
|
||||
All the translation strings of this application are stored in
|
||||
`resources/locales.json` file. It has a self explanatory format that
|
||||
|
@ -202,13 +207,13 @@ looks like this:
|
|||
```json
|
||||
{
|
||||
"auth.email-or-username" : {
|
||||
"used-in" : [ "src/app/main/ui/auth/login.cljs:61" ],
|
||||
"used-in" : [ "src/app/main/ui/auth/login.cljs" ],
|
||||
"translations" : {
|
||||
"en" : "Email or Username",
|
||||
"fr" : "adresse email ou nom d'utilisateur"
|
||||
}
|
||||
},
|
||||
"ds.num-projects" : {
|
||||
"labels.num-projects" : {
|
||||
"translations": {
|
||||
"en": ["1 project", "%s projects"]
|
||||
}
|
||||
|
@ -229,7 +234,7 @@ of that file, and just add a simple key-value entry pairs like this:
|
|||
|
||||
The file is automatically bundled into the `index.html` file on
|
||||
compile time (in development and production). The bundled content is a
|
||||
simplified version of this data structure for avoid load unnecesary
|
||||
simplified version of this data structure for avoid loading unnecesary
|
||||
data.
|
||||
|
||||
The development environment has a watch process that detect changes on
|
||||
|
@ -241,27 +246,24 @@ If you have used the short (key-value) format, the watch process will
|
|||
automatically convert it to the apropriate format before generate the
|
||||
`index.html`.
|
||||
|
||||
Finally, when you have finished to adding texts, execute the following
|
||||
command for reformat the file, and track the usage locations (the
|
||||
Finally, when you have finished adding texts, execute the following
|
||||
command to reformat the file, and track the usage locations (the
|
||||
"used-in" list) before commiting the file into the repository:
|
||||
|
||||
```bash
|
||||
clojure -Adev locales.clj collect src/app/main/ resources/locales.json
|
||||
# cd <repo>/frontend
|
||||
yarn run collect-locales
|
||||
```
|
||||
|
||||
NOTE: Later, we will need to think and implement the way to export and
|
||||
import to other formats (mainly for transifex and similar services
|
||||
import to other formats (mainly for Transifex and similar services
|
||||
compatibility).
|
||||
|
||||
|
||||
### How to use it ###
|
||||
|
||||
You have two aproaches for translate strings: one for general purpose
|
||||
and other specific for React components (that leverages reactivity for
|
||||
language changes).
|
||||
|
||||
The `app.util.i18n/tr` is the general purpose function. This is a
|
||||
simple use case example:
|
||||
You need to use the `app.util.i18n/tr` function for lookup translation
|
||||
strings:
|
||||
|
||||
```clojure
|
||||
(require '[app.util.i18n :refer [tr])
|
||||
|
@ -277,10 +279,23 @@ allow the system know when to show the plural:
|
|||
```clojure
|
||||
(require '[app.util.i18n :as i18n :refer [tr]])
|
||||
|
||||
(tr "ds.num-projects" (i18n/c 10))
|
||||
(tr "labels.num-projects" (i18n/c 10))
|
||||
;; => "10 projects"
|
||||
|
||||
(tr "ds.num-projects" (i18n/c 1))
|
||||
(tr "labels.num-projects" (i18n/c 1))
|
||||
;; => "1 project"
|
||||
```
|
||||
|
||||
## Tests ##
|
||||
|
||||
Frontend tests have to be compiled first, and then run with node.
|
||||
|
||||
```bash
|
||||
npx shadow-cljs compile tests && node target/tests.js
|
||||
```
|
||||
|
||||
Or run the watch (that automatically runs the test):
|
||||
|
||||
```bash
|
||||
npx shadow-cljs watch tests
|
||||
```
|
14
technical-guide/developer/index.md
Normal file
14
technical-guide/developer/index.md
Normal file
|
@ -0,0 +1,14 @@
|
|||
---
|
||||
title: 4. Developer Guide
|
||||
---
|
||||
|
||||
# Developer Guide
|
||||
|
||||
This section is intended for people wanting to mess with the
|
||||
code. The [Dev Env][1] section explains how to setup the common
|
||||
development enviroment that we (the core team) use internally.
|
||||
|
||||
The rest of sections are a list categorized of probably not deeply
|
||||
related HOWTO articles about dev-centric subjects.
|
||||
|
||||
[1]: /technical-guide/developer/devenv/
|
82
technical-guide/getting-started.md
Normal file
82
technical-guide/getting-started.md
Normal file
|
@ -0,0 +1,82 @@
|
|||
---
|
||||
title: 1. Getting Started.
|
||||
---
|
||||
|
||||
# Getting Started #
|
||||
|
||||
This section details everything you need to know to get Penpot up and
|
||||
running in production environments. Although it can be installed in
|
||||
many ways, the recommended approach is using **docker** and
|
||||
**docker-compose**.
|
||||
|
||||
|
||||
## Install Docker ##
|
||||
|
||||
**Skip this section if you already have docker installed, up and running.**
|
||||
|
||||
|
||||
Probably the best approach to install docker is following the official docker
|
||||
installation guide: https://docs.docker.com/engine/install/
|
||||
|
||||
|
||||
|
||||
Optionally, after installing docker, you can tweak your sistem for
|
||||
avoid constanly using of **sudo**. The easy, single step way is
|
||||
executong the following command that will add the current user to the
|
||||
docker group:
|
||||
|
||||
```bash
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
*NOTE*: probably you will need to re-login again to make this change take effect.
|
||||
|
||||
|
||||
For more advanced setup, docker already has a guide for [rootleass docker][1]
|
||||
|
||||
[1]: https://docs.docker.com/engine/security/rootless/
|
||||
|
||||
|
||||
|
||||
## Start Penpot ##
|
||||
|
||||
As first step you will need to obtain the `docker-compose.yaml`
|
||||
file. You can create it from scratch or start with the [default
|
||||
one][2] from penpot repository:
|
||||
|
||||
[2]: https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml
|
||||
|
||||
```bash
|
||||
wget https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml
|
||||
```
|
||||
|
||||
The default compose file has all essential configuration variables
|
||||
already set and they are pretty auto-explained. So we can proceed starting
|
||||
the application without touching anything:
|
||||
|
||||
```bash
|
||||
docker-compose -p penpot -f docker-compose.yaml up -d
|
||||
```
|
||||
|
||||
This will start listening on http://localhost:9001
|
||||
|
||||
|
||||
## Configuration ##
|
||||
|
||||
If you started the application without configuring SMTP, you probably
|
||||
need to create a user in order be able login into the application. You
|
||||
can create an additional, already activated user using this command:
|
||||
|
||||
```bash
|
||||
docker exec -ti penpot_penpot-backend_1 ./manage.sh create-profile
|
||||
```
|
||||
|
||||
In general, the application is ready to be used without email
|
||||
configuration; for example when no smtp configuration is found you
|
||||
should be able to change the user email (in profile section) without
|
||||
the email validation step.
|
||||
|
||||
For more advanced setups, look a the [Configuration][3] section.
|
||||
|
||||
[3]: /technical-guide/configuration/
|
||||
|
26
technical-guide/index.md
Normal file
26
technical-guide/index.md
Normal file
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
title: Overview
|
||||
eleventyNavigation:
|
||||
key: Technical Guide
|
||||
order: 4
|
||||
---
|
||||
|
||||
# Overview
|
||||
|
||||
This documentation intends to explain how to get penpot application
|
||||
and run it locally, to test it or make changes to it.
|
||||
|
||||
The official installation guide is described in the [Getting
|
||||
Started][1] section; and complemented with the [Configuration][2]
|
||||
section for more advanced setups.
|
||||
|
||||
[1]: /technical-guide/getting-started/
|
||||
[2]: /technical-guide/configuration/
|
||||
|
||||
|
||||
If you are a developer and want to get into the code, we recommend the
|
||||
[Developer Guide][3] that explains how to properly setup a development
|
||||
environment and many other dev-oriented documentation.
|
||||
|
||||
[3]: /technical-guide/developer/
|
||||
|
4
technical-guide/technical-guide.json
Normal file
4
technical-guide/technical-guide.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"layout": "layouts/technical-guide.njk",
|
||||
"tags": "technical-guide"
|
||||
}
|
Loading…
Reference in New Issue
Block a user