1.17 to 2.1.1 : trouble with image and font

Hello,

For several reasons, we choice the self-hosted solution in docker.
We use this version : 1.17
We have some trouble with this version and in particular this one :
• Into a project, on design page, when we would like to move a componant we have : « Internal Error Something bad happened. Please retry the operation and if the problem persists, contact support. ».

So we decide to start the migration with the version 2.1.1.
We follow : 1. Self-hosting Guide

We want to run the Penpot 2.1.1 on another machine.

Our steps :

  1. copy volumes with docker : Volumes | Docker Docs
  2. add disable-v2-migration flag in PENPOT_FLAGS environment variable
  3. start docker compose without open web application
  4. run this command docker exec -ti <container-name-or-id> ./run.sh app.migrations.v2 on backend container.

The Penpot 2.1.1 start.
Unfortunatly, we have some troubles :

  • We lost some assets like icon team or preview project.
    image
  • we lost fonts.
  • we have the same problem with “Internal Error…”

We contact support by mail. After some exchanges, they directed us here.

Have you the process to migrate in 2.1.1 without lost datas ?

Thanks you.

I think this can be related to something like this → Nginx, how to serve from /assets · Issue #2751 · penpot/penpot · GitHub

Check the format of your docker compose file (and base it on the last version that can be found here https://raw.githubusercontent.com/penpot/penpot/main/docker/images/docker-compose.yaml) and confirm the volumes and path are ok.

It would also be helpful if you show us your docker-compose.yaml file

1 Like

Hello,

Nginx is already on /opt/data/assets.

See below all of our config with anonymous data/password.

docker-compose.yaml :

networks:
  penpot_prod:
  traefik-frontend:
    external : true


volumes:
  # external true because create by copy from 1.17
  penpot_postgres_data:
    external : true 
  penpot_assets_data:
    external : true

services:
  penpot-frontend:
    image: ${IMAGE_PENPOT_FRONTEND}
    volumes:
      - penpot_assets_data:/opt/data
    env_file:
      - config.env
    depends_on:
      - penpot-backend
      - penpot-exporter
    networks:
      - penpot_prod
      - traefik-frontend
    labels:
      - "traefik.enable=true"
      - "traefik.docker.network=traefik-frontend"
      - "traefik.http.routers.penpot.rule=Host(`penpot2.****.***`)"
      - "traefik.http.routers.penpot.entrypoints=websecure"
      - "traefik.http.routers.penpot.tls=true"
    dns: 10.10.10.1

  penpot-backend:
    image: ${IMAGE_PENPOT_BACKEND}
    volumes:
      - penpot_assets_data:/opt/data
    depends_on:
      - penpot-postgres
      - penpot-redis
    env_file:
      - config.env
    networks:
      - penpot_prod
    dns: 10.10.10.1

  penpot-exporter:
    image: ${IMAGE_PENPOT_EXPORTER}
    environment:
      # Don't touch it; this uses internal docker network to
      # communicate with the frontend.
      - PENPOT_PUBLIC_URI=http://penpot-frontend
      
      ## Redis is used for the websockets notifications.
      - PENPOT_REDIS_URI=redis://penpot-redis/0
    networks:
      - penpot_prod
    dns: 10.10.10.1

  penpot-postgres:
    image: ${IMAGE_PENPOT_POSTGRES}
    restart: always
    stop_signal: SIGINT
    environment:
      - POSTGRES_INITDB_ARGS=--data-checksums
      - POSTGRES_DB=****
      - POSTGRES_USER=****
      - POSTGRES_PASSWORD=****
    volumes:
      - penpot_postgres_data:/var/lib/postgresql/data
    networks:
      - penpot_prod
    dns: 10.10.10.1
    privileged: true

  penpot-redis:
    image: ${IMAGE_PENPOT_REDIS}
    restart: always
    networks:
      - penpot_prod
    dns: 10.10.10.1

.env

IMAGE_PENPOT_FRONTEND=penpotapp/frontend:2.1.1
IMAGE_PENPOT_BACKEND=penpotapp/backend:2.1.1
IMAGE_PENPOT_REDIS=penpotapp/redis:7
IMAGE_PENPOT_POSTGRES=penpotapp/postgres:15
IMAGE_PENPOT_EXPORTER=penpotapp/exporter:2.1.1

config.env

# Should be set to the public domain where penpot is going to be served.
PENPOT_PUBLIC_URI=http://penpot2.***.***

# Standard database connection parameters (only postgresql is supported):
PENPOT_DATABASE_URI=postgresql://penpot-postgres/penpot
PENPOT_DATABASE_USERNAME=****
PENPOT_DATABASE_PASSWORD=****

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

# By default, files uploaded by users are stored in local filesystem. But it
# can be configured to store in AWS S3 or completely in de the database.
# Storing in the database makes the backups more easy but will make access to
# media less performant.
ASSETS_STORAGE_BACKEND=assets-fs
PENPOT_STORAGE_ASSETS_FS_DIRECTORY=/opt/data/assets

# Telemetry. When enabled, a periodical process will send anonymous data about
# this instance. Telemetry data will enable us to learn on how the application
# is used, based on real scenarios. If you want to help us, please leave it
# enabled.
PENPOT_TELEMETRY_ENABLED=false

# Email sending configuration. By default, emails are printed in the console,
# but for production usage is recommended to setup a real SMTP provider. Emails
# are used to confirm user registrations.
PENPOT_SMTP_ENABLED=true
PENPOT_SMTP_DEFAULT_FROM=penpot@****.****
PENPOT_SMTP_DEFAULT_REPLY_TO=penpot@****.****
PENPOT_SMTP_HOST=****
PENPOT_SMTP_PORT=****
#PENPOT_SMTP_USERNAME=
#PENPOT_SMTP_PASSWORD=
PENPOT_SMTP_TLS=false
PENPOT_SMTP_SSL=false

# Feature flags. Right now they are only affect frontend, but in
# future release they will affect to both backend and frontend.
#En 1.17
#PENPOT_FLAGS=$PENPOT_FLAGS disable-registration enable-insecure-registration enable-login-with-ldap disable-login disable-local-login disable-secure-session-cookies enable-smtp disable-demo-users

#En 2.0.0
PENPOT_FLAGS=$PENPOT_FLAGS disable-registration enable-login-with-ldap disable-login disable-secure-session-cookies enable-smtp disable-v2-migration

# Comma separated list of allowed domains to register. Empty to allow all.
# PENPOT_REGISTRATION_DOMAIN_WHITELIST=""

## Authentication providers

# Google
# PENPOT_GOOGLE_CLIENT_ID=
# PENPOT_GOOGLE_CLIENT_SECRET=

# GitHub
# PENPOT_GITHUB_CLIENT_ID=
# PENPOT_GITHUB_CLIENT_SECRET=

# GitLab
# PENPOT_GITLAB_BASE_URI=https://gitlab.com
# PENPOT_GITLAB_CLIENT_ID=
# PENPOT_GITLAB_CLIENT_SECRET=

# OpenID Connect (since 1.5.0)
# PENPOT_OIDC_BASE_URI=
# PENPOT_OIDC_CLIENT_ID=
# PENPOT_OIDC_CLIENT_SECRET=

# LDAP
PENPOT_LDAP_HOST=****
PENPOT_LDAP_PORT=****
PENPOT_LDAP_SSL=false
PENPOT_LDAP_STARTTLS=false
PENPOT_LDAP_BASE_DN=****
PENPOT_LDAP_BIND_DN=****
PENPOT_LDAP_BIND_PASSWORD=****
PENPOT_LDAP_ATTRS_USERNAME=****
PENPOT_LDAP_ATTRS_EMAIL=****
PENPOT_LDAP_ATTRS_FULLNAME=****
PENPOT_LDAP_ATTRS_PHOTO=jpegPhoto
PENPOT_LOGIN_WITH_LDAP=true

Our docker command line :

docker compose --project-name "penpot-prod" -f docker-compose.yaml up -d

edit:
see below browser console

Hello,

Lets see this in parts.

About the images: we will need what you have on the penpot_assets_data volume.

Can you execute the following command and paste the output:

docker exec -ti <frontend-container-name> ls -lha /opt/data/

and

docker exec -ti <frontend-container-name> ls -lha /opt/data/assets/

Example of output that I have on my test vm:

penpot@mgm02:~/ > docker exec -ti test-penpot-frontend-1 ls -lha /opt/data/assets
total 20K
drwxr-xr-x 5 penpot penpot 4.0K Aug  9 10:46 .
drwxr-xr-x 3 penpot penpot 4.0K Jul 25 12:04 ..
drwxr-xr-x 4 penpot penpot 4.0K Aug  9 10:44 85
drwxr-xr-x 3 penpot penpot 4.0K Aug  9 10:46 ae
drwxr-xr-x 3 penpot penpot 4.0K Aug  9 10:46 df

This output will allow us to understand the underlying problem with assets.

About the fonts: The problem looks like a very different one. The console errors show that there are some issues with fetching fonts. It can be caused by a number of reasons:

  • Can be a problem of your network that for some reason blocks these requests. You can try to check it on other network.
  • Can be some problem with the internal resolver, so you will probably need to look at the container logs and observe what happens when a request fails to fetch fonts.

Hello,
Thanks for your response.

About the images:

----@----:~$ docker container exec -it penpot-prod-penpot-frontend-1 ls -lha /opt/data/
total 12K
drwxr-xr-x   3 penpot penpot 4.0K Jul 31 14:56 .
drwxr-xr-x   1 root   root   4.0K Jul 25 12:04 ..
drwxr-xr-x 258 penpot penpot 4.0K Jul 31 14:56 assets
----@----:~$ docker container exec -it penpot-prod-penpot-frontend-1 ls -lha /opt/data/assets
total 1.1M
drwxr-xr-x 258 penpot penpot 4.0K Jul 31 14:56 .
drwxr-xr-x   3 penpot penpot 4.0K Jul 31 14:56 ..
drwxr-xr-x  17 penpot penpot 4.0K Jul 31 15:07 00
drwxr-xr-x  15 penpot penpot 4.0K Jul 31 14:56 01
drwxr-xr-x  21 penpot penpot 4.0K Jul 31 14:56 02
drwxr-xr-x  17 penpot penpot 4.0K Jul 31 14:56 03

It’s allright now, we found a error by using gosthery extension. You have to disable for this website.

About the fonts:
We’re looking on container log. we’re looking in web browser log.

On web browser log on penpot 2.1 :

https://penpot2.***.***/internal/gfonts/css?family=Montserrat:100,200,300,regular,500,600,700,800,900,100italic,200italic,300italic,italic,500italic,600italic,700italic,800italic,900italic&display=block

We found this error on front docker for penpot 2.1.1 :

[error] 10#10: *38101 connect() to [2a00:1450:4007:813::200a]:443 failed (101: Network is unreachable) while connecting to upstream, client: 172.80.0.3, server: _, request: 
"GET /internal/gfonts/css?family=Montserrat:100,200,300,regular,500,600,700,800,900,100italic,200italic,300italic,italic,500italic,600italic,700italic,800italic,900italic&display=block HTTP/1.1", 
upstream: "https://[2a00:1450:4007:813::200a]:443/css?family=Montserrat:100,200,300,regular,500,600,700,800,900,100italic,200italic,300italic,italic,500italic,600italic,700italic,800italic,900italic&display=block", host: "penpot2.***.***",


[error] 10#10: *38102 upstream timed out (110: Connection timed out) while connecting to upstream, client: 172.80.0.3, server: _, request: "GET /internal/gfonts/css?family=Montserrat:700&display=block HTTP/1.1", 
upstream: "https://142.250.178.138:443/css?family=Montserrat:700&display=block", host: "penpot2.***.***"

The same action on penpot 1.17 is OK, the request is :

https://fonts.googleapis.com/css?family=Montserrat:100,200,300,regular,500,600,700,800,900,100italic,200italic,300italic,italic,500italic,600italic,700italic,800italic,900italic&display=block

Thank you very much @conception :slight_smile:

So about the images: everything is working ok, isn’t it?

About the fonts: could you please try commenting the line dns: 10.10.10.1 from the penpot-frontend service?. Internally it has a nginx configured this way, penpot/docker/images/files/nginx.conf at develop · penpot/penpot · GitHub so probably if that penpot-front service can’t access to fonts.gstatic.com the request will fail

Hello,
Thank you for your response

About the images:
yes it’s working

About the font:
We compared the nginx.conf from penpot 1.17 and 2.1.
In penpot 2 there are locations concerning gfont

location ~ ^/internal/gfonts/font/(?<font_file>.+) {
  proxy_pass https://fonts.gstatic.com/s/$font_file;

  proxy_hide_header Access-Control-Allow-Origin;
  proxy_hide_header Cross-Origin-Resource-Policy;
  proxy_hide_header Link;
  proxy_hide_header Alt-Svc;
  proxy_hide_header Cache-Control;
  proxy_hide_header Expires;
  proxy_hide_header Cross-Origin-Opener-Policy;
  proxy_hide_header Report-To;

  proxy_ignore_headers Set-Cookie Vary Cache-Control Expires;

  proxy_set_header User-Agent "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36";
  proxy_set_header Host "fonts.gstatic.com";
  proxy_set_header Accept "*/*";
  
  proxy_cache penpot;
  
  add_header Access-Control-Allow-Origin $http_origin;
  add_header Cache-Control max-age=86400;
  add_header X-Cache-Status $upstream_cache_status;
}

location ~ ^/internal/gfonts/css {
  proxy_pass https://fonts.googleapis.com/css?$args;
  proxy_hide_header Access-Control-Allow-Origin;
  proxy_hide_header Cross-Origin-Resource-Policy;
  proxy_hide_header Link;
  proxy_hide_header Alt-Svc;
  proxy_hide_header Cache-Control;
  proxy_hide_header Expires;
  
  proxy_ignore_headers Set-Cookie Vary Cache-Control Expires;
  
  proxy_set_header User-Agent "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/113.0.0.0 Safari/537.36";
  proxy_set_header Host "fonts.googleapis.com";
  proxy_set_header Accept "*/*";
  
  proxy_cache penpot;
  
  add_header Access-Control-Allow-Origin $http_origin;
  add_header Cache-Control max-age=86400;
  add_header X-Cache-Stat
}

We suppose that in penpot 1.17 the client request directly googleapis, but in penpot 2.1 the request pass throw nginx server then redirected on googleapis.
In our case, penpot is in closed network, so nginx can’t reache googleapis.
We find a solution:
use the flag “disable-google-fonts-provider” in config.env and upload the font as custom font.

Great!

Exactly, the problem with doing the requests directly to googleapis can have problems with GDPR so we decided to pass them throw the nginx server.

If you need penpot network to be closed you can use the disable-google-fonts-provider as you are doing. Another possibility some users are overwriting the google fonts url to serve them internally