Penpot – The Open Source Design Tool For Your Creative Work

Looking for a design tool that allows you to unleash your inner creativity? Look no further than Penpot. Penpot is a free alternative to Figma. It is also a powerful web design tool that allows you to design and code beautiful product together.

Features

  • Real-time collaboration
  • Developer tools – comes with Code inspector tool to get actual code snippets
  • Infinite canvas
  • Fonts management
  • Advanced styling features
  • Libraries & templates in app
  • Flex and Grid CSS Layout

Installation

The easiest way to install Penpot is via Docker.

Create a folder for Penpot:

mkdir penpot
cd penpot

Download the docker-compose file.

wget https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml

Open the docker compose file:

nano docker-compose.yml

You should see something like this:

## Common flags:
# demo-users
# email-verification
# log-emails
# log-invitation-tokens
# login-with-github
# login-with-gitlab
# login-with-google
# login-with-ldap
# login-with-oidc
# login-with-password
# prepl-server
# registration
# secure-session-cookies
# smtp
# smtp-debug
# telemetry
# webhooks
##
## You can read more about all available flags and other
## environment variables here:
## https://help.penpot.app/technical-guide/configuration/#advanced-configuration
#
# WARNING: if you're exposing Penpot to the internet, you should remove the flags
# 'disable-secure-session-cookies' and 'disable-email-verification'
x-flags
: &penpot-flags
PENPOT_FLAGS
: disable-email-verification enable-smtp enable-prepl-server disable-secure-session-cookies

x-uri
: &penpot-public-uri
PENPOT_PUBLIC_URI
: http://localhost:9001

x-body-size
: &penpot-http-body-size
# Max body size (30MiB); Used for plain requests, should never be
# greater than multi-part size
PENPOT_HTTP_SERVER_MAX_BODY_SIZE
: 31457280

# Max multipart body size (350MiB)
PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE
: 367001600


networks
:
penpot
:

volumes
:
penpot_postgres_v15
:
penpot_assets
:
# penpot_traefik:
# penpot_minio:

services
:
## Traefik service declaration example. Consider using it if you are going to expose
## penpot to the internet, or a different host than `localhost`.

# traefik:
# image: traefik:v2.9
# networks:
# - penpot
# command:
# - "--api.insecure=true"
# - "--entryPoints.web.address=:80"
# - "--providers.docker=true"
# - "--providers.docker.exposedbydefault=false"
# - "--entryPoints.websecure.address=:443"
# - "--certificatesresolvers.letsencrypt.acme.tlschallenge=true"
# - "--certificatesresolvers.letsencrypt.acme.email=<EMAIL_ADDRESS>"
# - "--certificatesresolvers.letsencrypt.acme.storage=/traefik/acme.json"
# volumes:
# - "penpot_traefik:/traefik"
# - "/var/run/docker.sock:/var/run/docker.sock"
# ports:
# - "80:80"
# - "443:443"

penpot-frontend
:
image
: "penpotapp/frontend:latest"
restart
: always
ports
:
- 9001:8080

volumes
:
- penpot_assets:/opt/data/assets

depends_on
:
- penpot-backend
- penpot-exporter

networks
:
- penpot

labels
:
- "traefik.enable=true"

## HTTP: example of labels for the case where penpot will be exposed to the
## internet with only HTTP (without HTTPS) using traefik.

# - "traefik.http.routers.penpot-http.entrypoints=web"
# - "traefik.http.routers.penpot-http.rule=Host(`<DOMAIN_NAME>`)"
# - "traefik.http.services.penpot-http.loadbalancer.server.port=80"

## HTTPS: example of labels for the case where penpot will be exposed to the
## internet with HTTPS using traefik.

# - "traefik.http.middlewares.http-redirect.redirectscheme.scheme=https"
# - "traefik.http.middlewares.http-redirect.redirectscheme.permanent=true"
# - "traefik.http.routers.penpot-http.entrypoints=web"
# - "traefik.http.routers.penpot-http.rule=Host(`<DOMAIN_NAME>`)"
# - "traefik.http.routers.penpot-http.middlewares=http-redirect"
# - "traefik.http.routers.penpot-https.entrypoints=websecure"
# - "traefik.http.routers.penpot-https.rule=Host(`<DOMAIN_NAME>`)"
# - "traefik.http.services.penpot-https.loadbalancer.server.port=80"
# - "traefik.http.routers.penpot-https.tls=true"
# - "traefik.http.routers.penpot-https.tls.certresolver=letsencrypt"

environment
:
<<
: [*penpot-flags, *penpot-http-body-size]

penpot-backend
:
image
: "penpotapp/backend:latest"
restart
: always

volumes
:
- penpot_assets:/opt/data/assets

depends_on
:
- penpot-postgres
- penpot-redis

networks
:
- penpot

## Configuration envronment variables for the backend
## container.

environment
:
<<
: [*penpot-flags, *penpot-public-uri, *penpot-http-body-size]

## Penpot SECRET KEY. It serves as a master key from which other keys for subsystems
## (eg http sessions, or invitations) are derived.
##
## If you leave it commented, all created sessions and invitations will
## become invalid on container restart.
##
## If you going to uncomment this, we recommend to use a trully randomly generated
## 512 bits base64 encoded string here. You can generate one with:
##
## python3 -c "import secrets; print(secrets.token_urlsafe(64))"

# PENPOT_SECRET_KEY: my-insecure-key

## The PREPL host. Mainly used for external programatic access to penpot backend
## (example: admin). By default it will listen on `localhost` but if you are going to use
## the `admin`, you will need to uncomment this and set the host to `0.0.0.0`.

# PENPOT_PREPL_HOST: 0.0.0.0

## Database connection parameters. Don't touch them unless you are using custom
## postgresql connection parameters.

PENPOT_DATABASE_URI
: postgresql://penpot-postgres/penpot
PENPOT_DATABASE_USERNAME
: penpot
PENPOT_DATABASE_PASSWORD
: penpot

## Redis is used for the websockets notifications. Don't touch unless the redis
## container has different parameters or different name.

PENPOT_REDIS_URI
: redis://penpot-redis/0

## Default configuration for assets storage: using filesystem based with all files
## stored in a docker volume.

PENPOT_ASSETS_STORAGE_BACKEND
: assets-fs
PENPOT_STORAGE_ASSETS_FS_DIRECTORY
: /opt/data/assets

## Also can be configured to to use a S3 compatible storage
## service like MiniIO. Look below for minio service setup.

# AWS_ACCESS_KEY_ID: <KEY_ID>
# AWS_SECRET_ACCESS_KEY: <ACCESS_KEY>
# PENPOT_ASSETS_STORAGE_BACKEND: assets-s3
# PENPOT_STORAGE_ASSETS_S3_ENDPOINT: http://penpot-minio:9000
# PENPOT_STORAGE_ASSETS_S3_BUCKET: <BUKET_NAME>

## Telemetry. When enabled, a periodical process will send anonymous data about this
## instance. Telemetry data will enable us to learn how the application is used,
## based on real scenarios. If you want to help us, please leave it enabled. You can
## audit what data we send with the code available on github.

PENPOT_TELEMETRY_ENABLED
: true

## Example SMTP/Email configuration. By default, emails are sent to the mailcatch
## service, but for production usage it is recommended to setup a real SMTP
## provider. Emails are used to confirm user registrations & invitations. Look below
## how the mailcatch service is configured.

PENPOT_SMTP_DEFAULT_FROM
: no-reply@example.com
PENPOT_SMTP_DEFAULT_REPLY_TO
: no-reply@example.com
PENPOT_SMTP_HOST
: penpot-mailcatch
PENPOT_SMTP_PORT
: 1025
PENPOT_SMTP_USERNAME
:
PENPOT_SMTP_PASSWORD
:
PENPOT_SMTP_TLS
: false
PENPOT_SMTP_SSL
: false

penpot-exporter
:
image
: "penpotapp/exporter:latest"
restart
: always
networks
:
- penpot

environment
:
# Don't touch it; this uses an internal docker network to
# communicate with the frontend.
PENPOT_PUBLIC_URI
: http://penpot-frontend:8080

## Redis is used for the websockets notifications.
PENPOT_REDIS_URI
: redis://penpot-redis/0

penpot-postgres
:
image
: "postgres:15"
restart
: always
stop_signal
: SIGINT

volumes
:
- penpot_postgres_v15:/var/lib/postgresql/data

networks
:
- penpot

environment
:
- POSTGRES_INITDB_ARGS=--data-checksums
- POSTGRES_DB=penpot
- POSTGRES_USER=penpot
- POSTGRES_PASSWORD=penpot

penpot-redis
:
image
: redis:7.2
restart
: always
networks
:
- penpot

## A mailcatch service, used as temporal SMTP server. You can access via HTTP to the
## port 1080 for read all emails the penpot platform has sent. Should be only used as a
## temporal solution while no real SMTP provider is configured.

penpot-mailcatch
:
image
: sj26/mailcatcher:latest
restart
: always
expose
:
- '1025'
ports
:
- "1080:1080"
networks
:
- penpot

## Example configuration of MiniIO (S3 compatible object storage service); If you don't
## have preference, then just use filesystem, this is here just for the completeness.

# minio:
# image: "minio/minio:latest"
# command: minio server /mnt/data --console-address ":9001"
# restart: always
#
# volumes:
# - "penpot_minio:/mnt/data"
#
# environment:
# - MINIO_ROOT_USER=minioadmin
# - MINIO_ROOT_PASSWORD=minioadmin
#
# ports:
# - 9000:9000
# - 9001:9001

There are a few things that you need to configure here:

  • PENPOT_FLAGS: This will determine the features of your Penpot installation. If you are exposing it to the Internet, remove disable-secure-session-cookies‘ and disable-email-verification from the list. You can either “enable” or “disable” any of the flags. For example, if you want to disable registration, simply add disable-registration to the list. Or if you want to enable Github login, add enable-login-with-github to the list.
  • PENPOT_PUBLIC_URI: Change this if you are planning to expose the app to the Internet with its own domain name. Change it to the public URL you will be using to access the app.
  • traefik: The traefik service is included, but disabled by default. If you need a proxy server, you can enable it (by removing all the “#” in front of the entry)
  • PENPOT_SECRET_KEY: This is a master key to keep your session secure. You should enable it and add a randomly generated 512 bits base64 encoded string. You can generate the random string with the command:
python3 -c "import secrets; print(secrets.token_urlsafe(64))"
  • PENPOT_SMTP: The SMTP section requires you to configure your SMTP settings. If it is not properly configured, you won’t be able to receive email verification when registering for a new account.

Once you have made the above changes, save and exit the docker-compose.yml file.

Start the container:

docker compose up -d

Once it is running, you can access it via the URL: http://localhost:9001 or the custom domain you added earlier.

Usage

Start by creating an account on your Penpot installation.

Penpot Create Account

It will send you an email verification, of which you have to click the link in the email to verify your signup. After which, you will be able to login to the dashboard.

In the main project page, it will be blank (since it is new and there is no project yet). At the bottom is a list of Libraries and Templates that you can download and use them as a quick start.

Penpot Dashboard Libraries Templates
Penpot Import Libraries
Penpot Import Successfully

You can create a Team and invite your team members to work together on your project and files.

Penpot Invite Team Members

To get started, click on the “New Project” button at the top right corner. Give your project a name, and it will open up a blank canvas.

Penpot New Project

You can then proceed to unleash your creativity.

On the left panel, you can click on the “Libraries” button to add the libraries and templates you downloaded earlier to your project.

Penpot Add Libraries To Project

If you need more templates, you can check out the Penpot resources page and download the .penpot templates you want.

One good thing about the design in Penpot is that all your elements are in HTML/CSS format. You can click “Inspect” on the right menu to view the element’s code. This allows you to copy and paste easily in your development project.

Penpot Inspect Code

Other than libraries and templates, Penpot also supports Plugins. Check out the list of plugins here. For the plugin you want to install, copy the URL. Then in your Penpot project page, click on the three dots icon beside your project name, and select Plugins -> Plugins Manager.

Penpot Access Plugins Manager

Paste the plugin url, and click Install.

Penpot Import Plugin

Final Thoughts

If you have experience with using Figma, you’ll have no problem in using Penpot. In fact, the interface is so similar that you can get started immediately. This free version of Penpot comes has all the features you need to start designing and collaborating with your team. If you are looking for a self-hosted Figma alternative, Penpot is the one we recommend.

Be the first to comment! Get the discussion going.

Leave a Comment

Yeah! You've decided to leave a comment. That's fantastic! Check out our comment policy here. Let's have a personal and meaningful conversation.