Skip to content

Deployment

Deploy omnilux.tv to a production server.

Server requirements

  • Linux server (Ubuntu 22.04+ recommended)
  • 2+ CPU cores, 4 GB+ RAM
  • Node.js 22+, pnpm
  • Caddy (for HTTPS and reverse proxy)
  • Domain name with DNS configured

Caddy configuration

txt
omnilux.tv {
    root * /opt/omnilux/apps/web/dist
    file_server

    handle /api/* {
        reverse_proxy localhost:4000
    }

    handle {
        try_files {path} /index.html
    }
}

docs.omnilux.tv {
    root * /opt/omnilux/apps/docs/.vitepress/dist
    file_server

    handle {
        try_files {path} {path}.html /404.html
    }
}

This serves:

  • omnilux.tv — the web app (static files) + API (reverse proxy)
  • docs.omnilux.tv — the documentation site (static files)

Both get automatic HTTPS via Caddy's built-in ACME client.

Build and deploy process

Initial setup

bash
# Clone the repository
git clone https://github.com/omnilux/omnilux.git /opt/omnilux
cd /opt/omnilux

# Install dependencies
pnpm install

# Build everything
pnpm build

# Build docs
pnpm --filter @omnilux/docs build

Deploy script

Create scripts/deploy.sh:

bash
#!/bin/bash
set -euo pipefail

cd /opt/omnilux

# Pull latest changes
git pull

# Install dependencies
pnpm install

# Build
pnpm build
pnpm --filter @omnilux/docs build

# Restart the server
sudo systemctl restart omnilux

echo "Deploy complete"

Remote deploy via rsync

If building locally and deploying to a remote server:

bash
#!/bin/bash
set -euo pipefail

SERVER="user@your-server.com"
REMOTE_PATH="/opt/omnilux"

# Build locally
pnpm build
pnpm --filter @omnilux/docs build

# Sync to server
rsync -avz --delete \
  --exclude=node_modules \
  --exclude=.git \
  --exclude=data \
  ./ "$SERVER:$REMOTE_PATH/"

# Restart on server
ssh "$SERVER" "cd $REMOTE_PATH && pnpm install --prod && sudo systemctl restart omnilux"

CI/CD pipeline

GitHub Actions

Create .github/workflows/deploy.yml:

yaml
name: Deploy

on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - uses: pnpm/action-setup@v4
        with:
          version: 10

      - uses: actions/setup-node@v4
        with:
          node-version: 22
          cache: pnpm

      - run: pnpm install
      - run: pnpm build
      - run: pnpm --filter @omnilux/docs build

      - name: Deploy to server
        env:
          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
          SERVER: ${{ secrets.DEPLOY_SERVER }}
        run: |
          mkdir -p ~/.ssh
          echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_ed25519
          chmod 600 ~/.ssh/id_ed25519
          ssh-keyscan -H "$SERVER" >> ~/.ssh/known_hosts

          rsync -avz --delete \
            --exclude=node_modules \
            --exclude=.git \
            --exclude=data \
            ./ "deploy@$SERVER:/opt/omnilux/"

          ssh "deploy@$SERVER" "cd /opt/omnilux && pnpm install --prod && sudo systemctl restart omnilux"

Docs-only deploys

To deploy only when docs change, add a path filter:

yaml
on:
  push:
    branches: [main]
    paths:
      - 'apps/docs/**'

Verification

After deploying, verify:

bash
# Health check
curl https://omnilux.tv/api/health

# Docs site
curl -I https://docs.omnilux.tv

# Check systemd service
ssh your-server "systemctl status omnilux"

Use OmniLux, run your own server, or build on the platform.