mirror of
https://github.com/penpot/penpot.git
synced 2026-11-15 06:31:02 +00:00
Add an optional PENPOT_TRUSTED_ORIGINS setting listing alternate origins as bare scheme://host[:port] entries. Matching is exact on the trimmed, lowercased Origin; unlisted origins and requests without Origin keep the canonical public-uri, and server-to-server or queued work is unchanged. Malformed entries produce a startup warning and never match. Stamp the trusted origin on each request with a global http middleware that binds config public-uri for the request extent. Expose the chain as root-middleware so tests can assert trusted-origin runs before auth and errors. Email links, asset URLs, audit and webhook link fields, and redirects then use the alternate base while serving that request. Carry the origin through OIDC in the signed state, since the IdP callback is a navigation without Origin: auth and organization SSO store it, and the callback re-applies it with with-public-uri for the token exchange redirect_uri and every redirect target, including the logout post-logout redirect. Verify the state token once per callback and reuse the claims. Build redirect URIs with the uniform ensure-path-slash plus join pattern so subpaths survive, using append-query-param for hash routes. Closes #11625 AI-assisted-by: deepseek-v4.1-flash AI-assisted-by: qwen3.7-plus AI-assisted-by: gpt-5.6-luna
325 lines
10 KiB
YAML
325 lines
10 KiB
YAML
## 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/#penpot-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 enable-mcp
|
|
|
|
## Public URI where Penpot is reached. To serve Penpot from a subpath, include
|
|
## it with a trailing slash, e.g. https://example.com/penpot/. A reverse proxy in
|
|
## front must forward the subpath unchanged, without rewriting it.
|
|
x-uri: &penpot-public-uri
|
|
PENPOT_PUBLIC_URI: http://localhost:9001
|
|
## Optional: alternate origins the backend may use as the base for generated
|
|
## links (emails, assets, redirects) when a request Origin matches. Bare
|
|
## origins only, comma/whitespace separated; each must register its OIDC
|
|
## callback URL (https://<origin>/api/auth/oidc/callback) at the IdP.
|
|
# PENPOT_TRUSTED_ORIGINS: https://alt.example.com, https://staging.example.com
|
|
|
|
x-body-size: &penpot-http-body-size
|
|
# Max body size
|
|
PENPOT_HTTP_SERVER_MAX_BODY_SIZE: 367001600
|
|
# Deprecation warning: this variable is deprecated. Use PENPOT_HTTP_SERVER_MAX_BODY (defaults to 367001600)
|
|
PENPOT_HTTP_SERVER_MAX_MULTIPART_BODY_SIZE: 367001600
|
|
|
|
## Penpot SECRET KEY. It serves as a master key from which other keys for subsystems
|
|
## (eg http sessions, or invitations) are derived.
|
|
##
|
|
## We recommend to use a truly randomly generated
|
|
## 512 bits base64 encoded string here. You can generate one with:
|
|
##
|
|
## python3 -c "import secrets; print(secrets.token_urlsafe(64))"
|
|
x-secret-key: &penpot-secret-key
|
|
PENPOT_SECRET_KEY: change-this-insecure-key
|
|
|
|
## Single database configuration block, shared by backend and admin-console.
|
|
## Don't touch them unless you are using custom postgresql connection parameters.
|
|
x-database: &penpot-database
|
|
PENPOT_DATABASE_URI: postgresql://penpot-postgres/penpot
|
|
PENPOT_DATABASE_USERNAME: penpot
|
|
PENPOT_DATABASE_PASSWORD: penpot
|
|
|
|
networks:
|
|
penpot:
|
|
|
|
volumes:
|
|
penpot_postgres_v15:
|
|
penpot_assets:
|
|
# penpot_mailpit_data:
|
|
# penpot_traefik:
|
|
|
|
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:v3.3
|
|
# 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:${PENPOT_VERSION:-2.18}"
|
|
restart: always
|
|
ports:
|
|
- 9001:8080
|
|
|
|
volumes:
|
|
- penpot_assets:/opt/data/assets
|
|
|
|
depends_on:
|
|
- penpot-backend
|
|
- penpot-admin-console
|
|
- penpot-mcp
|
|
- penpot-exporter
|
|
|
|
networks:
|
|
- penpot
|
|
|
|
# labels:
|
|
# - "traefik.enable=true"
|
|
|
|
# ## HTTPS: example of labels for the case where penpot will be exposed to the
|
|
# ## internet with HTTPS using traefik.
|
|
|
|
# - "traefik.http.routers.penpot-https.rule=Host(`<DOMAIN_NAME>`)"
|
|
# ## When Penpot is served from a subpath, match it too:
|
|
# - "traefik.http.routers.penpot-https.rule=Host(`<DOMAIN_NAME>`) && PathPrefix(`/<SUBPATH>`)"
|
|
# - "traefik.http.routers.penpot-https.entrypoints=websecure"
|
|
# - "traefik.http.routers.penpot-https.tls.certresolver=letsencrypt"
|
|
# - "traefik.http.routers.penpot-https.tls=true"
|
|
|
|
environment:
|
|
<< : [*penpot-flags, *penpot-http-body-size, *penpot-public-uri]
|
|
|
|
# Don't touch it; this uses an internal docker network to
|
|
# communicate with the admin-console.
|
|
PENPOT_ADMIN_CONSOLE_URI: http://penpot-admin-console:3000
|
|
|
|
# Set to "true" on hosts where IPv6 is disabled at kernel boot level.
|
|
# PENPOT_DISABLE_IPV6_LISTEN: "true"
|
|
|
|
penpot-backend:
|
|
image: "penpotapp/backend:${PENPOT_VERSION:-2.18}"
|
|
restart: always
|
|
|
|
volumes:
|
|
- penpot_assets:/opt/data/assets
|
|
|
|
depends_on:
|
|
penpot-postgres:
|
|
condition: service_healthy
|
|
penpot-valkey:
|
|
condition: service_healthy
|
|
|
|
networks:
|
|
- penpot
|
|
|
|
## Configuration environment variables for the backend container.
|
|
|
|
|
|
environment:
|
|
<< : [*penpot-flags, *penpot-public-uri, *penpot-http-body-size, *penpot-secret-key, *penpot-database]
|
|
|
|
# Don't touch it; this uses an internal docker network to
|
|
# communicate with the admin-console.
|
|
PENPOT_ADMIN_CONSOLE_URI: http://penpot-admin-console:3000
|
|
|
|
## Valkey (or previously redis) is used for the websockets notifications. Don't touch
|
|
## unless the valkey container has different parameters or different name.
|
|
PENPOT_REDIS_URI: redis://penpot-valkey/0
|
|
|
|
## Default configuration for assets storage: using filesystem based with all files
|
|
## stored in a docker volume.
|
|
PENPOT_OBJECTS_STORAGE_BACKEND: fs
|
|
PENPOT_OBJECTS_STORAGE_FS_DIRECTORY: /opt/data/assets
|
|
|
|
## Also can be configured to to use a S3 compatible storage.
|
|
# AWS_ACCESS_KEY_ID: <KEY_ID>
|
|
# AWS_SECRET_ACCESS_KEY: <ACCESS_KEY>
|
|
# PENPOT_OBJECTS_STORAGE_BACKEND: s3
|
|
# PENPOT_OBJECTS_STORAGE_S3_ENDPOINT: <ENDPOINT>
|
|
# PENPOT_OBJECTS_STORAGE_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"
|
|
PENPOT_TELEMETRY_REFERER: compose
|
|
|
|
## Example SMTP/Email configuration. By default, emails are sent to the Mailpit
|
|
## 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 Mailpit service is configured.
|
|
PENPOT_SMTP_DEFAULT_FROM: no-reply@example.com
|
|
PENPOT_SMTP_DEFAULT_REPLY_TO: no-reply@example.com
|
|
PENPOT_SMTP_HOST: penpot-mailpit
|
|
PENPOT_SMTP_PORT: 1025
|
|
PENPOT_SMTP_USERNAME:
|
|
PENPOT_SMTP_PASSWORD:
|
|
PENPOT_SMTP_TLS: "false"
|
|
PENPOT_SMTP_SSL: "false"
|
|
|
|
## Inbox for the feedback that MCP agents send. Set it together with
|
|
## PENPOT_MCP_BACKEND_URI on the penpot-mcp service.
|
|
# PENPOT_MCP_FEEDBACK_EMAIL: mcp-feedback@example.com
|
|
|
|
penpot-admin-console:
|
|
image: "penpotapp/admin-console:${PENPOT_VERSION:-2.18}"
|
|
restart: always
|
|
|
|
depends_on:
|
|
penpot-postgres:
|
|
condition: service_healthy
|
|
|
|
networks:
|
|
- penpot
|
|
|
|
environment:
|
|
<< : [*penpot-public-uri, *penpot-secret-key, *penpot-database]
|
|
|
|
# Don't touch it; this uses an internal docker network to
|
|
# communicate with the frontend.
|
|
PENPOT_INTERNAL_URI: http://penpot-frontend:8080
|
|
|
|
penpot-mcp:
|
|
image: "penpotapp/mcp:${PENPOT_VERSION:-2.18}"
|
|
restart: always
|
|
networks:
|
|
- penpot
|
|
|
|
# environment:
|
|
## Offers the submit_feedback tool, which emails agent feedback through the
|
|
## backend. Set it together with PENPOT_MCP_FEEDBACK_EMAIL on the backend.
|
|
# PENPOT_MCP_BACKEND_URI: http://penpot-backend:6060/
|
|
|
|
penpot-exporter:
|
|
image: "penpotapp/exporter:${PENPOT_VERSION:-2.18}"
|
|
restart: always
|
|
|
|
depends_on:
|
|
penpot-valkey:
|
|
condition: service_healthy
|
|
|
|
networks:
|
|
- penpot
|
|
|
|
environment:
|
|
<< : [*penpot-flags, *penpot-secret-key, *penpot-public-uri]
|
|
|
|
# Don't touch it; this uses an internal docker network to
|
|
# communicate with the frontend.
|
|
PENPOT_INTERNAL_URI: http://penpot-frontend:8080
|
|
|
|
## Valkey (or previously Redis) is used for the websockets notifications
|
|
## and for storing the state export jobs
|
|
PENPOT_REDIS_URI: redis://penpot-valkey/0
|
|
|
|
# PENPOT_EXPORTER_MAX_CONCURRENT_JOBS: 4
|
|
# PENPOT_EXPORTER_MAX_JOBS_PER_PROFILE: 2
|
|
# PENPOT_EXPORTER_QUEUE_MAX: 64
|
|
# PENPOT_EXPORTER_JOB_TTL: 3600
|
|
# PENPOT_WASM_WORKER_POOL_MAX: 2
|
|
# PENPOT_WASM_WORKER_POOL_MIN: 1
|
|
# PENPOT_WASM_WORKER_IDLE_TIMEOUT: 300
|
|
# PENPOT_WASM_WORKER_IMAGE_CACHE_SIZE: 134217728
|
|
|
|
penpot-postgres:
|
|
image: "postgres:15"
|
|
restart: always
|
|
stop_signal: SIGINT
|
|
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "pg_isready -U penpot"]
|
|
interval: 2s
|
|
timeout: 10s
|
|
retries: 5
|
|
start_period: 2s
|
|
|
|
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-valkey:
|
|
image: valkey/valkey:8.1
|
|
restart: always
|
|
|
|
healthcheck:
|
|
test: ["CMD-SHELL", "valkey-cli ping | grep PONG"]
|
|
interval: 1s
|
|
timeout: 3s
|
|
retries: 5
|
|
start_period: 3s
|
|
|
|
networks:
|
|
- penpot
|
|
|
|
environment:
|
|
# You can increase the max memory size if you have sufficient resources,
|
|
# although this should not be necessary.
|
|
- VALKEY_EXTRA_FLAGS=--maxmemory 128mb --maxmemory-policy volatile-lfu
|
|
|
|
## A Mailpit service, used as temporal SMTP server. You can access via HTTP to the
|
|
## port 8025 to read all emails the penpot platform has sent. Should be only used as a
|
|
## temporal solution while no real SMTP provider is configured. Messages are kept in
|
|
## memory only and are lost when the container is recreated; uncomment the volume
|
|
## below (and the one in the top-level volumes: section) to persist them instead.
|
|
|
|
penpot-mailpit:
|
|
image: axllent/mailpit:v1
|
|
restart: always
|
|
# volumes:
|
|
# - penpot_mailpit_data:/data
|
|
# environment:
|
|
# - MP_DATABASE=/data/mailpit.db
|
|
expose:
|
|
- '1025'
|
|
ports:
|
|
- "8025:8025"
|
|
networks:
|
|
- penpot
|