Not released yet. PeltyCMS is under development and not released yet; these docs describe the upcoming release and may change.
PeltyCMS User docs
User docsDevelopers
v0.1.0

User docs/Administrator guide

Planned installation (not released)

PeltyCMS is not released yet. There is no public download, image or installer today. This page describes how installation is planned to work at release, and the details may change.

At release, PeltyCMS is planned to be one server binary, pelty-server, plus a PostgreSQL 16+ database. The binary serves the API, the built frontend and these docs, runs the database migrations on start and runs the background scheduler, so no separate cron or worker is needed.

#Requirements

#Docker Compose (planned)

The repository ships a Dockerfile and a docker-compose.yml. Put the secrets in a .env file next to the compose file (never commit it), then start it and create the first admin:

Shell
docker compose up -d
docker compose run --rm app admin create [email protected]
docker-compose.ymlYAML
# UNVERIFIED: statically reviewed, never run (no Docker on the dev box).
# Put secrets in a .env file next to this file (never commit it):
#   POSTGRES_PASSWORD=<long random>
#   PELTY_ENCRYPTION_KEY=<32-byte key, base64>   # encrypts server API keys / gateway secrets
#   PELTY_PUBLIC_URL=https://billing.example.com
# Optional: PELTY_SMTP_URL, PELTY_MAIL_FROM, PELTY_COOKIE_SECURE (default true here),
#   PELTY_AUTH_RATE_PER_MINUTE, PELTY_PROVISION_ALLOW_LINK_LOCAL (keep unset).
# First admin: docker compose run --rm app admin create [email protected]
services:
  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_USER: pelty
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
      POSTGRES_DB: peltycms
    volumes: [pgdata:/var/lib/postgresql/data]
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U pelty -d peltycms"]
      interval: 5s
      retries: 10
  app:
    build: .
    restart: unless-stopped
    depends_on:
      db: { condition: service_healthy }
    environment:
      DATABASE_URL: postgres://pelty:${POSTGRES_PASSWORD}@db:5432/peltycms
      PELTY_ENCRYPTION_KEY: ${PELTY_ENCRYPTION_KEY:-}
      PELTY_PUBLIC_URL: ${PELTY_PUBLIC_URL:-http://localhost:8080}
      PELTY_SMTP_URL: ${PELTY_SMTP_URL:-}
      PELTY_MAIL_FROM: ${PELTY_MAIL_FROM:-}
      PELTY_COOKIE_SECURE: ${PELTY_COOKIE_SECURE:-true}   # set false only for plain-HTTP local testing
    read_only: true
    tmpfs: [/tmp]
    security_opt: ["no-new-privileges:true"]
    cap_drop: [ALL]
    # Bind to localhost; put a TLS reverse proxy in front.
    ports: ["127.0.0.1:8080:8080"]
volumes:
  pgdata:

The image runs pelty-server serve, listens on 0.0.0.0:8080 (PELTY_BIND), and has a health check on /healthz. The compose file binds it to 127.0.0.1:8080 so only your reverse proxy can reach it.

#From source

Shell
make build      # frontend, server binary, addon zips and these docs
./target/release/pelty-server migrate
./target/release/pelty-server admin create [email protected]
./target/release/pelty-server serve

admin create reads the password from PELTY_ADMIN_PASSWORD or the first line of standard input. make help lists every target; see CLI for all commands, including the WHMCS, Blesta and Paymenter importers.

#Required configuration

Only a few environment variables are needed to run in production:

VariableDefaultDescription
DATABASE_URLPostgreSQL connection URL (postgres://…). Required.
PELTY_BIND"0.0.0.0:8080"Listen address.
PELTY_COOKIE_SECUREtrueSet the Secure flag on cookies. Must be true behind HTTPS.
PELTY_ENCRYPTION_KEYBase64 32-byte key for secrets at rest (TOTP). No default: 2FA enrolment is refused while unset.
PELTY_PUBLIC_URL"http://localhost:8080"Absolute base URL used in email links, e.g. https://billing.example.com.

PELTY_ENCRYPTION_KEY encrypts stored secrets (server API keys, gateway and addon secrets). Keep it safe and keep it the same across restarts: secrets saved with one key cannot be read with another.

Everything else (company details, currencies, mail, gateways, tax, security policy) is configured in the admin area and stored in the database. Continue with First-run setup.

#All environment variables

VariableDefaultDescription
DATABASE_URLPostgreSQL connection URL (postgres://…). Required.
PELTY_ADDONS_DIRDefault data/addons; an existing ./addons (the pre-restructure default) keeps working so older installs are not orphaned.
PELTY_ADDONS_DIST"extensions/addons/dist"Directory with the bundled first-party addon zips (default extensions/addons/dist).
PELTY_ADDON_DATA_DIR"data/addons"Root of per-addon data directories (default data/addons), one <root>/<id> each.
PELTY_ADDON_MAX_FUELAdmin caps for addon limits: memory MiB, timeout seconds, fuel (defaults: the built-in maxima).
PELTY_ADDON_MAX_MEMORY_MIBAdmin caps for addon limits: memory MiB, timeout seconds, fuel (defaults: the built-in maxima).
PELTY_ADDON_MAX_TIMEOUT_SECSAdmin caps for addon limits: memory MiB, timeout seconds, fuel (defaults: the built-in maxima).
PELTY_ADMIN_PASSWORDPassword for admin create (otherwise the first line of stdin).
PELTY_AUTH_RATE_PER_MINUTE10Max auth attempts per IP per minute.
PELTY_BACKUP_DIR"backups"Where database backups are written (default backups).
PELTY_BIND"0.0.0.0:8080"Listen address.
PELTY_COOKIE_SECUREtrueSet the Secure flag on cookies. Must be true behind HTTPS.
PELTY_DB_MAX_CONNECTIONS10Database pool size.
PELTY_DEFAULT_LOCALE"en"Language for visitors without a preference.
PELTY_DOCKERPELTY_DOCKER=1 marks a container: addon exec is disabled.
PELTY_DOCS_DIR"target/docs"Folder written by make docs (default target/docs).
PELTY_DOCS_PUBLICtrue/1 makes /docs readable without signing in (default: staff only).
PELTY_ENCRYPTION_KEYBase64 32-byte key for secrets at rest (TOTP). No default: 2FA enrolment is refused while unset.
PELTY_FRONTEND_DIR"frontend/dist"Built frontend served as the SPA.
PELTY_LOCALES_DIR"locales"Translation JSON files.
PELTY_LOG_JSONfalseLog as JSON lines instead of text.
PELTY_MAIL_FROM"PeltyCMS <no-reply@localhost>".to_stringFrom address for outgoing mail.
PELTY_PG_DUMP"pg_dump"pg_dump binary used for backups (default pg_dump on PATH).
PELTY_PLUGINS_DIR"extensions/plugins"Webhook plugin manifests.
PELTY_PROVISION_ALLOW_LINK_LOCAL1/true lets provisioning modules reach link-local addresses (off by default).
PELTY_PUBLIC_URL"http://localhost:8080"Absolute base URL used in email links, e.g. https://billing.example.com.
PELTY_SESSION_ABSOLUTE_HOURS24 * 30Sessions end after this many hours regardless of activity.
PELTY_SESSION_IDLE_MINUTES60 * 24Sign out after this many idle minutes.
PELTY_SMTP_URLSMTP URL (smtps://user:pass@host:465). Unset: mail is logged, not sent.
PELTY_THEMES_DIR"extensions/themes"Theme folders (theme.json).
PELTY_VIES_URLEU VIES VAT check API base URL (default: the public EU endpoint).
PELTY_WASM_CACHE_DIRCompiled-module cache directory (default <tmp>/pelty-wasm-cache).

Generated from the code; the developer reference Configuration also shows which file reads each variable.