railway-setup-penpot
Workspace
OTF
Created
2026-03-26
Updated
2026-03-26
Content
# Railway Setup: Penpot
## Overview
- **Project:** otf-penpot (`6c601dc5-5b4e-4e49-99e7-dee4c5264859`)
- **Template:** https://railway.com/deploy/penpot
- **Domain:** design.optimified.com
- **Port:** 8080 (frontend)
- **Services:** frontend (`ccf1c2d9`), backend (`99f4fe1b`), exporter (`a4122f76`), postgres (`5928479a`), minio (`9aa58cac`), valkey (`09c19ac5`)
## Key Env Vars (backend)
| Var | Value |
|---|---|
| `PENPOT_PUBLIC_URI` | `https://design.optimified.com` |
| `PENPOT_FLAGS` | `enable-prepl-server enable-smtp` |
| `PENPOT_TELEMETRY_ENABLED` | `false` |
| `PENPOT_ASSETS_STORAGE_BACKEND` | `assets-s3` |
| `PENPOT_STORAGE_ASSETS_S3_BUCKET` | `penpot-assets` |
| `PENPOT_STORAGE_ASSETS_S3_ENDPOINT` | `http://minio.railway.internal:9000` |
| `PENPOT_SMTP_HOST` | `smtp.resend.com` |
## Key Env Vars (frontend)
| Var | Value |
|---|---|
| `PENPOT_PUBLIC_URI` | `https://design.optimified.com` |
| `PENPOT_BACKEND_URI` | `http://backend.railway.internal:6060` |
| `PENPOT_EXPORTER_URI` | `http://exporter.railway.internal:6061` |
## Custom Domain
CNAME: `design` → `frontend-production-9099.up.railway.app` (Cloudflare proxied)
**Important:** Custom domain goes on the **frontend** service only. Backend and exporter are internal.
## MinIO Setup
- **Bucket:** `penpot-assets` — **must be created manually** after deploy
- **Console:** accessible via MinIO public domain (port 1453 internally)
- **Credentials:** `MINIO_ROOT_USER` / `MINIO_ROOT_PASSWORD` (stored in Railway)
- **Volume:** Persistent at `/mnt/data`
## Critical Post-Deploy Steps
1. Log into MinIO console → create bucket `penpot-assets`
2. Set `PENPOT_PUBLIC_URI` on **both** frontend and backend services
3. Verify image upload works in the app
## Telemetry
Disabled. Penpot telemetry goes to Penpot's servers — anonymous usage data for their team. No value for us.
## Registration
Currently open. Disable after Martha creates her account by adding `disable-registration` to `PENPOT_FLAGS` on the backend.
## Issues Encountered
- **DNS timing issue:** Setting `PENPOT_PUBLIC_URI` to the custom domain before DNS propagated made both the Railway URL and custom domain inaccessible. The app redirects based on this value. **Lesson:** Don't update the public URI until DNS is confirmed via `dig` or `curl`.
- **MinIO bucket not auto-created:** The template does NOT create the `penpot-assets` bucket. Uploads and exports silently fail without it. Must be created manually via the MinIO console after deploy.