Operations Deployment Single Server - osama1998H/Moca GitHub Wiki

Single Server Deployment

Deploy all Moca processes on a single Linux server behind a reverse proxy. Suitable for small teams, staging environments, and cost-sensitive production workloads.

Prerequisites

  • Ubuntu 22.04 or 24.04 (LTS recommended)
  • PostgreSQL 16+
  • Redis 7+
  • Meilisearch v1.12
  • A domain name pointing to the server's public IP

Step 1: Install Moca

Download and run the official install script. It places the five Moca binaries (moca, moca-server, moca-worker, moca-scheduler, moca-outbox) into /usr/local/bin:

curl -fsSL https://install.moca.dev | bash

Verify the installation:

moca version

Step 2: Initialize a Project

Create a new Moca project directory:

moca init my-project
cd my-project

Step 3: Configure moca.yaml

Edit the generated moca.yaml to point at your database, Redis, and search services:

database:
  host: localhost
  port: 5432
  user: moca
  password: your-db-password
  name: moca

redis:
  addr: localhost:6379
  password: ""
  db: 0

search:
  host: http://localhost:7700
  api_key: your-meilisearch-master-key

Step 4: Create a Site

Create your first tenant site:

moca site create mysite

This provisions the PostgreSQL schema, seeds built-in doctypes, and registers the site in the site registry.

Step 5: Deploy with moca deploy setup

Run the automated setup pipeline. This single command handles the full production configuration:

moca deploy setup \
  --domain mysite.example.com \
  --email [email protected] \
  --proxy caddy \
  --process systemd \
  --tls \
  --firewall \
  --fail2ban

The 14-step pipeline performs the following in order:

  1. Validates prerequisites (binaries, services, OS version)
  2. Checks PostgreSQL connectivity and applies migrations
  3. Checks Redis connectivity
  4. Checks Meilisearch connectivity and creates indexes
  5. Generates a Caddy reverse proxy configuration
  6. Generates systemd service units for all four server processes
  7. Installs and enables the systemd units
  8. Configures UFW firewall rules (open 80, 443; restrict 5432, 6379, 7700)
  9. Installs and configures fail2ban for Moca's access log
  10. Obtains TLS certificates via Caddy's built-in ACME client
  11. Reloads Caddy
  12. Starts all Moca systemd services
  13. Runs smoke tests (health endpoint, WebSocket probe, job queue ping)
  14. Prints a deployment summary with service URLs and status

Step 6: Post-Setup

Verify all services are running:

moca deploy status

Set up an automated backup schedule (runs daily at 2 AM):

moca backup schedule --cron "0 2 * * *" --dest /var/backups/moca

Enable monitoring metrics export:

moca monitor enable --prometheus --port 9090

Updating

Apply a new Moca release with zero downtime:

moca deploy update

This performs a rolling restart: drains connections from each process, updates the binary, restarts, and verifies health before proceeding to the next process.

Troubleshooting

Symptom Likely Cause Fix
Port not reachable (80/443) UFW blocking or Caddy not started sudo ufw status; sudo systemctl status caddy
TLS certificate failed Domain not pointing to server IP Verify DNS A record; check moca deploy status for ACME errors
Service won't start Missing env variable or config error journalctl -u moca-server -n 50; check moca.yaml
DB connection refused PostgreSQL not listening or wrong credentials pg_isready -h localhost; verify moca.yaml database section

See also: Common startup issues — quick-reference for auth, scaffold, and background-job issues seen during the v1.0.4 DX test session.