Backend · Infra

Figma 살 돈이없다면? Penpot self-hosting으로 대체하자

devhyen 2025. 7. 21. 10:12

직접 구르고 굴러 끝낸, 개인 PC WSL(우분투ㅋ) 기반 Penpot Self-hosting 튜토리얼
+ 사내망 같은 대역끼리 접속 가능하게 하기

라이브 편집도 잘됩니다요

왜 Figma는 못 쓰나요?

  • Figma는 상용이고 유료입니다
  • 클라우드 기반이라 외부 유출 위험 때문에 회사 정책상 사용이 불가합니다.

왜 Penpot을 선택했나요?

  • Self-hosting이 가능해서 내부망에서만 운영할 수 있음 ➡ 보안 OK
  • 완전 무료 (오픈소스)
  • Lunacy 보다 UI가 예쁘다
  • Lunacy는 공동편집이 클라우드에서만 가능하지만
    Penpot은 공동편집도 Self-hosting 가능! 

지금까지 한 일 

  • 팀장님 허락받음
  • 보안팀에 내 PC에 self-hosting 하는거 허락받음 
  • 내 PC (WSL + Ubuntu)에 self-hosting (완료)

앞으로 할 일 

  • 팀에 먼저 소개 및 발표
  • 연구소에 소개 및 발표
  • 반응좋으면 사내 서버에 self-hosting 해서 사내에서 공식적으로 사용하도록 하기 

Penpot self-hosting 방법 ( WSL Ubuntu )

더보기

테스트 환경 : 

OS : Window 10 + WSL2 (Ubuntu 22.04)

Penpot 버전 : latest (공식 docker image)

docker, docker compose 설치 완료 상태

https://penpot.app/

 

Penpot: The Design Tool for Design & Code Collaboration

Penpot is the open-source free design software that connects designers and developers with no handoff drama. Prototyping, UI design and code - all in one app.

penpot.app

 

git clone

git clone https://github.com/penpot/penpot.git
cd penpot/docker/images

 

기본 설정 변경

사내에 배포해둔 IAM OIDC를 연동해보려고 한다. 

docker-compose.yaml에서 

x-flags를 아래와 같이 변경해준다. 

x-flags: &penpot-flags
  PENPOT_FLAGS: disable-email-verification disable-smtp disable-prepl-server disable-telemetry disable-secure-session-cookies enable-login-with-oidc enable-oidc-registration

 

내 PC에서 호스팅할거니까 URI도 수정해주기 

x-uri: &penpot-public-uri
  PENPOT_PUBLIC_URI: https://<your-local-ip>
지금 보면 https 로 했는데 !!! IAM을 연동하려면 IAM 정책상 https 여야하기 때문이다. 
https를 위한 ssl 관련 설정은 아래에 설명 예정입니다 

 

HTTPS 통신 + 도메인 접근 + nginx reverse proxy 구성 을 위해 nginx 설정

  nginx:
    image: nginx:alpine
    ports:
      - "443:443"
    volumes:
      - ./chain.pem:/etc/nginx/certs/penpot.crt
      - ./key.pem:/etc/nginx/certs/penpot.key
      - ./nginx.conf:/etc/nginx/nginx.conf
    depends_on:
      - penpot-frontend
    networks:
      - penpot

  penpot-frontend:
    image: "penpotapp/frontend:${PENPOT_VERSION:-latest}"
    restart: always
    ports:
      # - "443:8443"
      - "0.0.0.0:9001:8080"

    volumes:
      - penpot_assets:/opt/data/assets

    depends_on:
      - penpot-backend
      - penpot-exporter

    networks:
      - penpot

 

사내 iam은 자체 서명 인증서(ca)를 사용하기 때문에 

아래 설정이 필요하다.

  penpot-backend:
    image: "penpotapp/backend:${PENPOT_VERSION:-latest}"
    user: root
    restart: always

    volumes:
      - penpot_assets:/opt/data/assets
      - ./files/hydra-ca.crt:/usr/local/share/ca-certificates/hydra-ca.crt:ro
    depends_on:
      penpot-postgres:
        condition: service_healthy
      penpot-valkey:
        condition: service_healthy

    networks:
      - penpot
    entrypoint:
      - sh
      - -c
      - |
        # 1) OS 레벨 CA 저장소에 추가
        update-ca-certificates

        # 2) Java 트러스트스토어에도 추가
        keytool -importcert -noprompt \
          -alias hydra-root \
          -file /usr/local/share/ca-certificates/hydra-ca.crt \
          -keystore $$JAVA_HOME/lib/security/cacerts \
          -storepass changeit

        # 3) Penpot 원래 커맨드
        exec /bin/bash run.sh

 

./files/hydra-ca.crt 에다가  사내 인증서를 먼저 위치시키는거 필수!!

이제 OIDC 를 위해서 필요한 값들을 environment에 입력해주기!

 environment:
      << : [*penpot-flags, *penpot-public-uri, *penpot-http-body-size]
      PENPOT_OIDC_CLIENT_ID: penpot
      PENPOT_OIDC_CLIENT_SECRET: <your_secret>
      PENPOT_OIDC_SCOPES: "openid profile email"
      PENPOT_OIDC_BASE_URI: <hydra_uri>
      PENPOT_OIDC_USERINFO_URI: <hydra_uri>
      PENPOT_OIDC_AUTH_URI:  <hydra_uri>
      PENPOT_OIDC_TOKEN_URI:  <hydra_uri>
      PENPOT_OIDC_REVOCATION_URI: <hydra_uri>

주의할점은 penpot 에서는 client_secret_post 만 지원한다. 

그래서 hydra를 사용하는 경우 client 등록할때 

ory create oauth2-client \
  --token-endpoint-auth-method client_secret_post \
  ...

위 처럼 post로 설정해두어야 한다.

 

아까 설명한 https를 위해서 

먼저 self-signed 인증서 발급!

openssl req -x509 -nodes -newkey rsa:2048 \
  -keyout key.pem \
  -out cert.pem \
  -days 365

 

nginx.conf 파일도 작성해주기 

events {}

http {
  include /etc/nginx/conf.d/*.conf;
  server {
    listen 443 ssl;
    server_name _;

    client_max_body_size 31457280;

    ssl_certificate /etc/nginx/certs/penpot.crt;
    ssl_certificate_key /etc/nginx/certs/penpot.key;

    location /ws/notifications {
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection 'upgrade';
      proxy_pass http://penpot-frontend:8080/ws/notifications;
    }

    location / {
      proxy_pass http://penpot-frontend:8080;
      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
    }
  }

 



이렇게 하고 

docker compose up --build -d

하면 penpot이 실행된다죠 .. 

 

Windows 방화벽 인바운드 규칙 설정

WSL/Windows에서 Penpot를 띄우는 경우라면, Windows 방화벽에서 인바운드 규칙을 다음처럼 설정:

  • 프로토콜: TCP
  • 포트: 443
  • 원격 IP 주소: 172.16.0.0/12 등 내부망 대역만 허용
  • 동작: 허용

그 외 IP는 자동으로 차단되기 때문에 외부에선 접근이 안 된다.