initial commit
This commit is contained in:
55
.env.example
Normal file
55
.env.example
Normal file
@@ -0,0 +1,55 @@
|
||||
# Penpot Environment Variables Template
|
||||
# Copy this file to .env and fill in the secure values.
|
||||
|
||||
# ==========================================
|
||||
# ENVIRONMENT TOGGLE: DEV vs PRODUCTION
|
||||
# ==========================================
|
||||
|
||||
# ---> OPTION A: DEVELOPMENT (No SSL / Plain HTTP)
|
||||
# Prefix your IP or localhost with http:// to disable SSL generation.
|
||||
# CADDY_SITE_ADDRESS=http://192.168.1.50
|
||||
# PENPOT_PUBLIC_URI=http://192.168.1.50
|
||||
|
||||
# ---> OPTION B: PRODUCTION (Automatic SSL via Let's Encrypt)
|
||||
# Comment out Option A, and uncomment these two lines.
|
||||
# Do NOT prefix CADDY_SITE_ADDRESS with https://, just the domain.
|
||||
# CADDY_SITE_ADDRESS=design.yourdomain.com
|
||||
# PENPOT_PUBLIC_URI=https://design.yourdomain.com
|
||||
|
||||
# ==========================================
|
||||
|
||||
# --- Domain and SSL Setup ---
|
||||
CADDY_SITE_ADDRESS=https://design.yourdomain.com
|
||||
PENPOT_PUBLIC_URI=https://design.yourdomain.com
|
||||
TLS_EMAIL=admin@yourdomain.com
|
||||
|
||||
# --- Security ---
|
||||
# Generate a random string for this (e.g., using `openssl rand -base64 32`)
|
||||
PENPOT_SECRET_KEY=your_super_secret_key_here
|
||||
|
||||
# --- Database Setup ---
|
||||
# Must match between PostgreSQL and Backend
|
||||
POSTGRES_USER=penpot
|
||||
POSTGRES_PASSWORD=your_secure_db_password
|
||||
POSTGRES_DB=penpot
|
||||
PENPOT_DATABASE_URI=postgresql://penpot-postgres/penpot
|
||||
PENPOT_DATABASE_USERNAME=penpot
|
||||
PENPOT_DATABASE_PASSWORD=your_secure_db_password
|
||||
|
||||
# --- Redis Setup ---
|
||||
PENPOT_REDIS_URI=redis://penpot-redis/0
|
||||
|
||||
# --- Telemetry (Optional) ---
|
||||
# Set to true to disable sending anonymous telemetry to Penpot
|
||||
PENPOT_TELEMETRY_ENABLED=false
|
||||
|
||||
# --- Email (SMTP) Configuration ---
|
||||
# Required for user registration, password resets, and team invites
|
||||
PENPOT_SMTP_DEFAULT_FROM=penpot@yourdomain.com
|
||||
PENPOT_SMTP_DEFAULT_REPLY_TO=penpot@yourdomain.com
|
||||
PENPOT_SMTP_HOST=smtp.yourprovider.com
|
||||
PENPOT_SMTP_PORT=587
|
||||
PENPOT_SMTP_USERNAME=your_smtp_username
|
||||
PENPOT_SMTP_PASSWORD=your_smtp_password
|
||||
PENPOT_SMTP_TLS=true
|
||||
PENPOT_SMTP_SSL=false
|
||||
17
.gitignore
vendored
Normal file
17
.gitignore
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
# Ignore environment variables containing secrets
|
||||
.env
|
||||
|
||||
# Ignore persistent data volumes
|
||||
volumes/
|
||||
*/volumes/
|
||||
*data/
|
||||
assets/
|
||||
|
||||
# Ignore backups
|
||||
backups/
|
||||
*.tar.gz
|
||||
*.sql
|
||||
|
||||
# OS generated files
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
21
README.md
Normal file
21
README.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Self-Hosted Penpot Deployment
|
||||
|
||||
This repository contains the infrastructure configuration to run Penpot via Docker Compose.
|
||||
|
||||
## Deployment Instructions
|
||||
|
||||
1. **Clone the repository:**
|
||||
git clone http://git.amiirkhl.ir/interanet/penpot-deployment.git
|
||||
cd penpot-deployment
|
||||
|
||||
2. **Setup Environment Variables:**
|
||||
cp .env.example .env
|
||||
# Edit the .env file and add your secret keys, passwords, and SMTP details
|
||||
nano .env
|
||||
|
||||
3. **Start the Services:**
|
||||
docker compose up -d
|
||||
|
||||
4. **Create the First Admin User:**
|
||||
Once the containers are running, you need to create your main admin account via the command line:
|
||||
docker exec -it penpot-backend ./manage.sh create-profile
|
||||
4
config/caddy/Caddyfile
Normal file
4
config/caddy/Caddyfile
Normal file
@@ -0,0 +1,4 @@
|
||||
{$DOMAIN} {
|
||||
tls {$TLS_EMAIL}
|
||||
reverse_proxy penpot-frontend:80
|
||||
}
|
||||
77
docker-compose.yml
Normal file
77
docker-compose.yml
Normal file
@@ -0,0 +1,77 @@
|
||||
version: "3.8"
|
||||
|
||||
networks:
|
||||
penpot:
|
||||
|
||||
volumes:
|
||||
penpot_postgres_v15:
|
||||
penpot_tenant_assets:
|
||||
caddy_data:
|
||||
caddy_config:
|
||||
|
||||
services:
|
||||
caddy:
|
||||
image: caddy:2
|
||||
restart: always
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./config/caddy/Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
environment:
|
||||
- CADDY_SITE_ADDRESS=${CADDY_SITE_ADDRESS}
|
||||
- TLS_EMAIL=${TLS_EMAIL}
|
||||
networks:
|
||||
- penpot
|
||||
depends_on:
|
||||
- penpot-frontend
|
||||
|
||||
penpot-frontend:
|
||||
image: "penpotapp/frontend:latest"
|
||||
restart: always
|
||||
volumes:
|
||||
- penpot_tenant_assets:/opt/data/assets
|
||||
depends_on:
|
||||
- penpot-backend
|
||||
networks:
|
||||
- penpot
|
||||
|
||||
penpot-backend:
|
||||
image: "penpotapp/backend:latest"
|
||||
restart: always
|
||||
volumes:
|
||||
- penpot_tenant_assets:/opt/data/assets
|
||||
depends_on:
|
||||
- penpot-postgres
|
||||
- penpot-redis
|
||||
networks:
|
||||
- penpot
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
penpot-exporter:
|
||||
image: "penpotapp/exporter:latest"
|
||||
restart: always
|
||||
networks:
|
||||
- penpot
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
penpot-postgres:
|
||||
image: "postgres:15"
|
||||
restart: always
|
||||
stop_signal: SIGINT
|
||||
volumes:
|
||||
- penpot_postgres_v15:/var/lib/postgresql/data
|
||||
networks:
|
||||
- penpot
|
||||
env_file:
|
||||
- .env
|
||||
|
||||
penpot-redis:
|
||||
image: redis:7
|
||||
restart: always
|
||||
networks:
|
||||
- penpot
|
||||
29
scripts/backup.sh
Normal file
29
scripts/backup.sh
Normal file
@@ -0,0 +1,29 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit immediately if a command exits with a non-zero status
|
||||
set -e
|
||||
|
||||
BACKUP_DIR="./backups"
|
||||
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
|
||||
DB_BACKUP_FILE="${BACKUP_DIR}/penpot_db_${TIMESTAMP}.sql"
|
||||
ASSETS_BACKUP_FILE="${BACKUP_DIR}/penpot_assets_${TIMESTAMP}.tar.gz"
|
||||
|
||||
echo "=== Starting Penpot Backup ($TIMESTAMP) ==="
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
|
||||
# Backup PostgreSQL Database
|
||||
echo "Backing up Database..."
|
||||
docker compose exec -T penpot-postgres pg_dump -U penpot -d penpot -c > "$DB_BACKUP_FILE"
|
||||
echo "Database backed up to $DB_BACKUP_FILE"
|
||||
|
||||
# Backup Assets Volume
|
||||
echo "Backing up Assets..."
|
||||
docker compose run --rm \
|
||||
-v $(pwd)/backups:/backups \
|
||||
penpot-backend \
|
||||
tar czvf /backups/penpot_assets_${TIMESTAMP}.tar.gz -C /opt/data/assets .
|
||||
|
||||
echo "Assets backed up to $ASSETS_BACKUP_FILE"
|
||||
|
||||
echo "=== Backup Complete! ==="
|
||||
51
scripts/restore.sh
Normal file
51
scripts/restore.sh
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Exit immediately if a command exits with a non-zero status
|
||||
set -e
|
||||
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "Usage: $0 <path_to_db_backup.sql> <path_to_assets_backup.tar.gz>"
|
||||
echo "Example: $0 backups/penpot_db_20231026_120000.sql backups/penpot_assets_20231026_120000.tar.gz"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DB_FILE=$1
|
||||
ASSETS_FILE=$2
|
||||
|
||||
# Verify files exist
|
||||
if [ ! -f "$DB_FILE" ]; then
|
||||
echo "Error: Database backup file '$DB_FILE' not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ ! -f "$ASSETS_FILE" ]; then
|
||||
echo "Error: Assets backup file '$ASSETS_FILE' not found."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "=== Starting Penpot Restore ==="
|
||||
|
||||
echo "Stopping frontend, backend, and exporter..."
|
||||
docker compose stop penpot-frontend penpot-backend penpot-exporter
|
||||
|
||||
echo "Restoring Database from $DB_FILE..."
|
||||
cat "$DB_FILE" | docker compose exec -T penpot-postgres psql -U penpot -d penpot
|
||||
echo "Database restored."
|
||||
|
||||
# We spin up a temporary container, delete current assets, and extract the backup
|
||||
# Convert relative path of ASSETS_FILE to absolute path for the volume mount
|
||||
echo "Restoring Assets from $ASSETS_FILE..."
|
||||
ABS_ASSETS_FILE=$(realpath "$ASSETS_FILE")
|
||||
ABS_ASSETS_DIR=$(dirname "$ABS_ASSETS_FILE")
|
||||
ASSETS_FILENAME=$(basename "$ABS_ASSETS_FILE")
|
||||
|
||||
docker compose run --rm \
|
||||
-v "$ABS_ASSETS_DIR":/backups \
|
||||
penpot-backend \
|
||||
sh -c "rm -rf /opt/data/assets/* && tar xzvf /backups/$ASSETS_FILENAME -C /opt/data/assets/"
|
||||
echo "Assets restored."
|
||||
|
||||
echo "Restarting all Penpot services..."
|
||||
docker compose start
|
||||
|
||||
echo "=== Restore Complete! ==="
|
||||
12
scripts/update.sh
Normal file
12
scripts/update.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
echo "Pulling latest Penpot images..."
|
||||
docker compose pull
|
||||
|
||||
echo "Recreating containers..."
|
||||
docker compose up -d
|
||||
|
||||
echo "Removing old unused images..."
|
||||
docker image prune -f
|
||||
|
||||
echo "Penpot update complete!"
|
||||
Reference in New Issue
Block a user