Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.signalium.site/llms.txt

Use this file to discover all available pages before exploring further.

Production runs on a single VPS behind nginx, two pm2 processes:
DomainProcessLocal port
signalium.sitesignalium-web8040
api.signalium.sitesignalium-api8041

CI/CD

Push to main triggers .github/workflows/cd.yml:
  1. verify job (GitHub-hosted Ubuntu): pnpm install --frozen-lockfile, then pnpm typecheck and pnpm lint scoped to runtime packages (skips @signalium/contracts which needs Foundry and @signalium/subgraph which needs graph-cli codegen).
  2. deploy job: SSHes to the VPS using a deploy-only ed25519 key, runs git fetch && reset --hard origin/main, pnpm install --frozen-lockfile --prefer-offline, pnpm build --filter=@signalium/web --filter=@signalium/api, then pm2 reload ecosystem.config.cjs --update-env.
End-to-end: ~1.5 min from push to live.

Required GitHub Actions secrets

SecretValue
VPS_HOSThostname or IP of the VPS
VPS_USERssh user
VPS_SSH_KEYfull contents of an ed25519 private key whose pub key is in ~/.ssh/authorized_keys on the VPS
VPS_PATHabsolute repo path on the VPS, e.g. /home/cuyvps/signalium

First-time bootstrap

Walks through cloning, env setup, pm2 init, nginx vhosts, and certbot. Lives in deploy/README.md. Highlights:
# Tools
curl -fsSL https://get.pnpm.io/install.sh | sh -
curl -fsSL https://bun.sh/install | bash

# Code
git clone https://github.com/rstfulzz/signalium.git ~/signalium
cd ~/signalium
pnpm install --frozen-lockfile
pnpm build --filter=@signalium/web --filter=@signalium/api

# Drop in the production .env (rsync from local — never commit)
scp ./.env vpsuser@vps:~/signalium/.env

# Start
pm2 start ecosystem.config.cjs
pm2 save

# nginx vhosts
sudo ln -sf ~/signalium/deploy/nginx/signalium.site.conf      /etc/nginx/sites-enabled/
sudo ln -sf ~/signalium/deploy/nginx/api.signalium.site.conf  /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx

# SSL
sudo certbot --nginx -d signalium.site -d www.signalium.site
sudo certbot --nginx -d api.signalium.site

pm2 ecosystem

ecosystem.config.cjs declares both processes. Key gotcha: interpreter: 'none' is required so pm2 doesn’t try to fork the pnpm shell wrapper as a Node script.

SQLite cache

The API’s SQLite db lives at apps/api/data/signalium.db and holds the X post metadata cache, AI proposals (keyed by judgeStorageRoot), and the 0G/USD price cache. The CD workflow never touches this directoryapps/api/data/ is gitignored, so production state is preserved across deploys. If the production DB needs a backfill (e.g., proposals created locally need to flow to prod), checkpoint the local WAL with sqlite3 apps/api/data/signalium.db "PRAGMA wal_checkpoint(TRUNCATE);" and scp the file after stopping the API process.