Skip to content

Installation

This guide walks through the baseline install for a Diadem instance.

  1. Set up the directory

    Terminal window
    git clone https://github.com/ccev/diadem
    cd diadem
    ./setup.sh

    Diadem’s config files need to sit in specific places. setup.sh sets up syslinks to centralize them all in /config for your convenience.

  2. Configure

    Open config/config.toml and fill out as needed. Find the reference here.

  3. Install dependencies and build

    Terminal window
    pnpm install
    pnpm run build
  4. Push the internal DB schema

    Terminal window
    pnpm run db:push

    This initializes Diadem tables (users/sessions) in server.internalDb.

  5. Run

    You may want to run Diadem using pm2.

    Terminal window
    PORT=3900 HOST=127.0.0.1 FORCE_COLOR=1 pm2 start build/index.js -n "diadem"

    For multi-core production servers, run the cluster entrypoint instead. DIADEM_WORKERS=auto starts one worker per available CPU core; you can also set a fixed number such as DIADEM_WORKERS=4.

    Terminal window
    PORT=3900 HOST=127.0.0.1 FORCE_COLOR=1 DIADEM_WORKERS=auto node cluster.mjs
  6. Reverse Proxy (optional)

    For production use, it’s probably a good idea to set up Diadem behind a reverse proxy. Here’s a configuration for Caddy that works.

    example.com {
    root * /path/to/diadem/build
    reverse_proxy * 127.0.0.1:3900
    }

For a systemd deployment, point ExecStart at the cluster entrypoint to distribute requests across CPU cores while keeping a single service and port.

[Unit]
Description=Diadem
After=network.target
[Service]
Type=simple
WorkingDirectory=/path/to/diadem
Environment=NODE_ENV=production
Environment=HOST=127.0.0.1
Environment=PORT=3900
Environment=FORCE_COLOR=1
Environment=DIADEM_WORKERS=auto
ExecStart=/usr/bin/node cluster.mjs
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target

After changing the unit, reload and restart it:

Terminal window
sudo systemctl daemon-reload
sudo systemctl restart diadem

Cluster mode starts multiple Diadem processes. Each worker has its own in-memory caches, rate limit counters, and MySQL pools. If strict rate limits matter, account for the worker count or use one worker until rate limiting is backed by shared storage.

  1. Pull the latest changes

    Terminal window
    git pull
  2. Install dependencies and build

    Terminal window
    pnpm install
    pnpm run build
  3. Restart

    Terminal window
    pm2 restart diadem

For containerized setup using the published ghcr.io/ccev/diadem:latest image:

Terminal window
cp config/config.example.toml config/config.toml
cp docker-compose.example.yml docker-compose.yml
docker compose pull
docker compose up -d

Then edit config/config.toml to point to the correct DB and API hosts for your environment.

To update an existing Docker install:

Terminal window
docker compose pull
docker compose up -d

By default Docker uses the optimized published image. To debug an issue with readable, unminified code and source maps in your browser devtools, build the local dev target with a compose override:

Terminal window
cat > docker-compose.override.yml <<'EOF'
services:
diadem:
build:
context: .
dockerfile: Dockerfile
target: dev
image: diadem:dev
EOF
echo "DIADEM_TARGET=dev" >> .env
docker compose up -d --build

This runs the Vite dev server (with its error overlay) instead of node build/index.js. Remove docker-compose.override.yml, set DIADEM_TARGET=runtime (or remove the line), and run docker compose pull && docker compose up -d to return to the published image.