npm package: @it-club/provisor
Description: Server provisioning and deployment CLI tool
Latest version: 0.5.3

# @it-club/provisor

Interactive CLI tool for server provisioning and deployment with automatic deploy support.

## Installation

```bash
# Install globally
npm install -g @it-club/provisor

# Or run directly with npx
npx @it-club/provisor
```

## Interactive Dashboard

Run without arguments to launch the interactive dashboard:

```bash
provisor
```

The dashboard provides:
- **Server Management**: Initialize new servers, add existing servers, remove saved servers
- **App Management**: Provision, deploy, view logs, edit config, and delete applications
- **Server Diagnostics**: Check Caddy status, firewall, ports, and logs
- **Caddy Management**: View/edit config, view logs, restart service
- **SSH Key Management**: Add and list authorized keys
- **Security Actions**: Migrate runtime user and harden SSH access

For menu structure and keyboard navigation, see [`docs/CLI_NAVIGATION.md`](docs/CLI_NAVIGATION.md).
For a full code-derived command reference, see [`docs/CLI_REFERENCE.md`](docs/CLI_REFERENCE.md).
For security posture and hardening status, see [`docs/SECURITY_HARDENING.md`](docs/SECURITY_HARDENING.md).
For day-to-day operating workflow, see [`docs/OPERATIONS_PLAYBOOK.md`](docs/OPERATIONS_PLAYBOOK.md).

## Commands

### `provisor init` - Initialize Server

Sets up a new server with user management, SSH hardening, and firewall configuration.

```bash
provisor init -h <server-ip>

# Options
-h, --host <host>   Server hostname or IP (required)
-u, --user <user>   Username to create (default: "deploy")
-k, --key <path>    Path to SSH private key
-p, --port <port>   SSH port (default: "22")
```

**What it does:**
1. Connects as root
2. Updates system packages
3. Creates a new user with sudo access
4. Copies root's SSH keys to new user
5. Configures UFW firewall (SSH, HTTP, HTTPS)
6. Hardens SSH (disables root login, password auth)

---

### `provisor migrate-user` - Migrate Runtime User

Migrate existing managed apps/processes from one server user to another (for example, `root` to `deploy`) on an already-running server.

```bash
provisor migrate-user -h <server-ip> --from-user root --to-user deploy

# Optional hardening after migration
provisor migrate-user -h <server-ip> --from-user root --to-user deploy --harden-ssh
```

---

### `provisor harden-ssh` - Harden SSH Access

Run lockout prechecks and then disable root SSH login/password auth.

```bash
provisor harden-ssh -h <server-ip> --target-user deploy
```

---

### `provisor app` - Provision Application

Sets up Caddy, Node.js, PM2, and git-based deployment with static/proxy routing modes.

```bash
provisor app -h <server-ip> -n myapp

# Options
-h, --host <host>      Server hostname or IP (required)
-u, --user <user>      Username to connect as (default: "deploy")
-k, --key <path>       Path to SSH private key
-p, --port <port>      SSH port (default: "22")
-b, --branch <branch>  Deploy branch (default: "main")
-n, --name <name>      Application name (default: "app")
-r, --repo <url>       Clone from repository URL (GitHub, GitLab, etc.)
--build-cmd <cmd>      Build command
--start-cmd <cmd>      Start command for PM2 mode
--site-mode <mode>     Site mode: proxy or static
--app-port <port>      Reverse proxy target port for PM2 mode
--tls-mode <mode>      TLS mode: ondemand, specific, none
--domains <domains>    Domains for specific TLS
--auto-deploy <mode>   Auto-deploy mode: polling or none
--deploy-method <m>    Deploy method: clone-public, clone-private, push
--dry-run              Preview provisioning changes without applying them
-y, --yes              Run non-interactively using provided flags
```

**What it does:**
1. Installs Caddy web server
2. Installs Node.js LTS and PM2
3. Sets up deployment (choose from 3 methods):
   - **Push-to-deploy**: Creates bare git repo for `git push` deployments
   - **Clone from public repo**: Clones HTTPS repository
   - **Clone from private repo**: Generates deploy key, clones SSH repository
4. Sets up auto-deploy:
   - **Git polling**: Checks for new commits every N seconds
   - **Manual only**: Use `provisor deploy` command
5. Configures Caddy routing:
   - **Static mode**: `file_server` from `/var/www/<app>`
   - **Proxy mode**: `reverse_proxy` to `127.0.0.1:<app-port>` with PM2-managed process

**Routing/TLS options:**

| Option | Description |
|--------|-------------|
| On-demand TLS | Catch-all cert flow for domains pointed at the server (one catch-all app at a time) |
| Specific domain(s) | Traditional cert for specified domains |
| No TLS | HTTP only |

---

### `provisor deploy` - Trigger Deployment

Manually trigger a deployment for an application.

```bash
provisor deploy -h <server-ip> -n myapp
provisor deploy -h <server-ip> -n myapp --dry-run
```

---

### `provisor config` - Manage Configuration

View and manage app runtime/deploy/routing configuration.

```bash
provisor config -h <server-ip> -n myapp --show
provisor config -h <server-ip> -n myapp --dry-run --proxy-port 4000
provisor config -h <server-ip> -n myapp --proxy-port 4000
provisor config -h <server-ip> -n myapp --tls-mode specific --domains "api.example.com"
provisor config -h <server-ip> -n myapp --sync-caddy
```

---

### `provisor status` - Check Server Status

Display server health and service status.

```bash
provisor status -h <server-ip>
```

---

### `provisor doctor` - Run Readiness/Security Checks

Run a consolidated readiness check for:
- SSH connectivity
- sudo readiness
- SSH hardening policy
- firewall + fail2ban
- tailscale status
- Caddy validation
- PM2 startup resilience
- managed app footprint integrity
- reboot-required state

```bash
provisor doctor -h <server-ip> -u deploy
provisor doctor -h <server-ip> -u deploy --json
provisor doctor -h <server-ip> -u deploy --json --fail-on-warning
```

---

### `provisor ssh-key` - Manage SSH Keys

Add or list SSH keys on the server.

```bash
provisor ssh-key -h <server-ip> --list
provisor ssh-key -h <server-ip> --add "ssh-ed25519 AAAA..."
```

---

## System Architecture

```mermaid
graph TD
    subgraph "Your Machine"
        CLI[Provisor CLI]
        Conf[Local Config<br/>~/.provisor/servers.json]
    end

    subgraph "Remote Server"
        Caddy[Caddy Web Server]
        PM2[PM2 Process Manager]
        
        subgraph "App 1"
            Repo1[Git Repo]
            Process1[Node Process]
        end
    end

    CLI -->|SSH| Caddy
    CLI -->|SSH| PM2
    Caddy -->|Reverse Proxy| Process1
    PM2 -->|Manages| Process1
```

---

## On-Demand TLS (Caddy v2.10+)

The on-demand TLS option allows automatic certificate provisioning for any domain pointed at your server. Caddy v2.10+ requires a permission endpoint for abuse prevention.

**How it works:**
- An internal endpoint (`:5555`) acts as a permission check
- Caddy requests a certificate only after this endpoint approves
- By default, all domains are approved

Use this as a catch-all route for a single app per server.

---

## Auto-Deploy Options

### Git Polling (Recommended)
- Checks repository at configurable intervals
- Works behind NAT/firewalls
- No webhook setup required

### Manual
- Trigger deploys explicitly with `provisor deploy`

---

## File Locations on Server

| File | Purpose |
|------|---------|
| `/var/www/<app>/` | Application directory |
| `/var/repo/<app>.git/` | Bare git repo (push-to-deploy) |
| `/usr/local/bin/update-<app>` | Deploy script |
| `/etc/provisor/apps/<app>.json` | App configuration (centralized) |
| `/var/log/provisor/<app>/build-deploy.log` | Build and deploy logs |
| `/etc/caddy/Caddyfile` | Caddy configuration |

---

## Security model and operational guardrails

- Provisor is designed for **non-root** day-to-day operations.
- In command mode, high-risk commands (`app`, `deploy`, `config`, `caddy`, `ssh-key`) refuse to run as root unless `--allow-root` is provided.
- In interactive dashboard mode, those same actions are blocked when the saved server user is `root`.
- Recommended flow:
  1. Bootstrap with `provisor init` (root only)
  2. Move runtime ownership with `provisor migrate-user`
  3. Operate using non-root user (`deploy`)

### Deploy SSH preflight

Before running deploy updates, Provisor now:
- ensures git host trust in `known_hosts`
- verifies remote SSH access with deploy key
- attempts conservative auto-repair for unresolved alias hosts (`github-*`, `gitlab-*`, `bitbucket-*`) by creating managed `~/.ssh/config` host entries

For hardening details and roadmap, see `docs/SECURITY_HARDENING.md`.

---

## Requirements

- Node.js 20+
- SSH key pair for server access
- Target server running Debian/Ubuntu

---

## License

MIT