docs: sync getting-started + README with install UX improvements
Updates the user-facing docs to match the install flow after the friction fixes landed: README.md Quick Start block now reflects reality: install.sh host-port check, test-deployment.sh verify step, password file location, and the useful-tools block (validate-env, test-deployment, pangolin-teardown, ccp-deregister). mkdocs prerequisites.md New warning block under Linux Server covering the cockpit-on-9090 class of port collisions, pointing at the installer's ss-based preflight and validate-env.sh for manual checks. Checklist gains a host-port line. mkdocs installation.md "What install.sh does" now enumerates the new port check and disk check. Configuration Wizard Step 4 notes the data/admin-credentials.txt persistence for auto-generated passwords. "Verifying Installation" rewritten around test-deployment.sh. New "Clean reset before reinstall" block with the teardown sequence. mkdocs first-steps.md Log In step tells users where to find the generated password when they ran config.sh -y without --admin-password. mkdocs control-panel.md New "Registering an Existing Install (Phone-Home)" section covering invite code, --ccp-* flags, approval, rate-limit + backoff behaviour, and the ccp-deregister.sh teardown path with the slug-conflict rationale. Bunker Admin
This commit is contained in:
parent
d2da13929a
commit
450b5ad4ba
24
README.md
24
README.md
@ -103,15 +103,22 @@ Send SMS campaigns via an Android bridge, sync subscribers to Listmonk for newsl
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Production (pre-built images)
|
||||
|
||||
```bash
|
||||
# One-command install (downloads pre-built images, runs config wizard)
|
||||
# 1. One-command install: checks host ports, downloads tarball, runs config wizard
|
||||
curl -fsSL https://gitea.bnkops.com/admin/changemaker.lite/raw/branch/main/scripts/install.sh | bash
|
||||
|
||||
cd ~/changemaker.lite
|
||||
docker compose up -d
|
||||
# 2. Start services (first pull ~3 min + ~90s stabilization)
|
||||
cd ~/changemaker.lite && docker compose up -d
|
||||
|
||||
# 3. Verify the install
|
||||
bash scripts/test-deployment.sh --wait 60
|
||||
```
|
||||
|
||||
Or clone and build from source:
|
||||
The installer checks your host's port availability before extracting — no more half-started stacks from cockpit on `:9090` or other surprises. The generated admin password is printed to stdout **and** saved to `data/admin-credentials.txt` (mode 0600). See [Prerequisites](https://cmlite.org/docs/getting-started/prerequisites/) for what you need lined up first.
|
||||
|
||||
### Development (source)
|
||||
|
||||
```bash
|
||||
git clone <repo-url> changemaker.lite
|
||||
@ -127,6 +134,15 @@ docker compose exec api npx prisma db seed
|
||||
|
||||
Then open **http://localhost:3000** and log in with the admin credentials from your `.env`.
|
||||
|
||||
### Useful tools
|
||||
|
||||
```bash
|
||||
bash scripts/validate-env.sh # re-check .env + host ports
|
||||
bash scripts/test-deployment.sh # full deployment health sweep
|
||||
bash scripts/pangolin-teardown.sh # wipe tunnel org before reinstall (dry-run by default)
|
||||
bash scripts/ccp-deregister.sh # deregister from Changemaker Control Panel (dry-run by default)
|
||||
```
|
||||
|
||||
## Documentation
|
||||
|
||||
**Full documentation is available at [cmlite.org/docs/getting-started](https://cmlite.org/docs/getting-started/).**
|
||||
|
||||
@ -271,6 +271,83 @@ CCP-level configuration:
|
||||
|
||||
---
|
||||
|
||||
## Registering an Existing Install (Phone-Home)
|
||||
|
||||
Instead of provisioning from scratch, CCP can adopt a Changemaker Lite install that already runs elsewhere. The target host's `ccp-agent` container phones home with an invite code, you approve the registration in CCP, and CCP issues an mTLS cert bundle for ongoing management.
|
||||
|
||||
### 1. Generate an invite code in CCP
|
||||
|
||||
```bash
|
||||
curl -s -X POST $CCP_URL/api/invite-codes \
|
||||
-H "Authorization: Bearer $ADMIN_TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"expiryHours":48}'
|
||||
```
|
||||
|
||||
The response contains a `code` like `KNZH-B6WW`. Invite codes are single-use and expire.
|
||||
|
||||
### 2. Install the target with `--ccp-*` flags
|
||||
|
||||
On the host that will be registered:
|
||||
|
||||
```bash
|
||||
bash config.sh -y --enable-all \
|
||||
--domain yourdomain.org \
|
||||
--admin-password 'StrongPassword1' \
|
||||
--ccp-url https://ccp.example.com \
|
||||
--ccp-invite-code KNZH-B6WW \
|
||||
--ccp-agent-url https://100.90.78.47:7443 \
|
||||
# ... tunnel, SMTP, and other flags
|
||||
```
|
||||
|
||||
All three CCP flags are required together. The wizard:
|
||||
|
||||
- Sets `ENABLE_CCP_AGENT=true` in `.env`
|
||||
- Appends `ccp-agent` to `COMPOSE_PROFILES` (without clobbering `monitoring`)
|
||||
- On `docker compose up -d`, the `ccp-agent` container starts and phones home
|
||||
|
||||
### 3. Approve in CCP
|
||||
|
||||
```bash
|
||||
# List pending registrations
|
||||
curl -s $CCP_URL/api/agents/registrations -H "Authorization: Bearer $ADMIN_TOKEN"
|
||||
|
||||
# Approve one
|
||||
curl -s -X POST $CCP_URL/api/agents/registrations/$REG_ID/approve \
|
||||
-H "Authorization: Bearer $ADMIN_TOKEN" -d '{}'
|
||||
```
|
||||
|
||||
On approval, CCP issues a mTLS cert bundle. The agent picks it up on its next poll, writes certs to disk, and restarts into mTLS mode. The instance then shows as `RUNNING` in CCP with live container status via `docker compose ps` proxied through the agent.
|
||||
|
||||
!!! info "Approval SLA and rate limits"
|
||||
The agent polls `/api/agents/poll` every 30s while waiting. The endpoint accepts up to 180 polls per 15 minutes (one every ~5s upper bound), so the agent comfortably handles human-paced approval times. If the agent does hit HTTP 429, it backs off exponentially (30s → 60s → 120s → 300s cap) and resets on the next successful poll — no manual restart required.
|
||||
|
||||
### 4. Deregister on teardown
|
||||
|
||||
When you wipe the target host (`docker compose down -v` + `sudo rm -rf`), also deregister the instance from CCP. Otherwise the stale Instance row blocks re-registration of the same slug, and CCP will return HTTP 409 `SLUG_CONFLICT` on the next approval.
|
||||
|
||||
```bash
|
||||
# From the target host (or anywhere with network access to CCP):
|
||||
bash scripts/ccp-deregister.sh \
|
||||
--ccp-url https://ccp.example.com \
|
||||
--token $ADMIN_TOKEN \
|
||||
--yes
|
||||
```
|
||||
|
||||
Defaults: matches by `CCP_AGENT_URL` from `.env`. Use `--slug` or `--instance-id` for explicit targeting. Dry-run by default.
|
||||
|
||||
The teardown sequence for a registered instance is therefore:
|
||||
|
||||
```bash
|
||||
cd ~/changemaker.lite
|
||||
bash scripts/ccp-deregister.sh --token $ADMIN_TOKEN --yes # CCP-side
|
||||
bash scripts/pangolin-teardown.sh --yes # Pangolin-side
|
||||
docker compose --profile monitoring down -v --remove-orphans # Docker
|
||||
sudo rm -rf ~/changemaker.lite # Filesystem
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
- [Services Overview](services.md) — learn about the services CCP provisions for each instance
|
||||
|
||||
@ -26,8 +26,17 @@ Open the admin panel at `http://localhost:3000` (or `app.DOMAIN` in production)
|
||||
|
||||
{ loading=lazy }
|
||||
|
||||
!!! info "Where's the password if I let the wizard generate one?"
|
||||
If you ran `config.sh -y` without `--admin-password`, the generated password was printed once to stdout **and** saved to `data/admin-credentials.txt` (mode 0600). Retrieve it with:
|
||||
|
||||
```bash
|
||||
cat ~/changemaker.lite/data/admin-credentials.txt
|
||||
```
|
||||
|
||||
Delete the file once you've saved the password elsewhere (e.g. in Vaultwarden).
|
||||
|
||||
!!! warning "Change your password"
|
||||
If you used the wizard's generated password, change it immediately from **Settings > Organization**.
|
||||
Whatever password you're logging in with first, change it immediately from **Settings > Organization**.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -80,11 +80,13 @@ curl -fsSL https://gitea.bnkops.com/admin/changemaker.lite/raw/branch/main/scrip
|
||||
This script:
|
||||
|
||||
1. Checks prerequisites (Docker, Docker Compose, OpenSSL)
|
||||
2. Downloads the latest release package from Gitea
|
||||
3. Extracts to `~/changemaker.lite/`
|
||||
4. Launches the configuration wizard (`config.sh`)
|
||||
2. **Checks host port availability** — aborts early if any of the ~14 required ports (3000, 4000, 9090, 3030, etc.) are already in use. Prints culprit-specific hints (e.g. cockpit.socket on :9090)
|
||||
3. Verifies at least 10 GB free disk
|
||||
4. Downloads the latest release package from Gitea
|
||||
5. Extracts to `~/changemaker.lite/`
|
||||
6. Launches the configuration wizard (`config.sh`)
|
||||
|
||||
After the wizard completes, start everything with `docker compose up -d`.
|
||||
After the wizard completes, start everything with `docker compose up -d`, then verify with `bash scripts/test-deployment.sh --wait 60`.
|
||||
|
||||
### Manual Download
|
||||
|
||||
@ -161,6 +163,9 @@ Prompts for the initial super-admin email and password. The password is validate
|
||||
- At least one **digit**
|
||||
- Requires password confirmation
|
||||
|
||||
!!! info "Non-interactive password"
|
||||
If you run with `-y` and omit `--admin-password`, the wizard generates a strong password and **also writes it to `data/admin-credentials.txt` with mode 0600**. Delete the file after saving the password elsewhere. Explicit `--admin-password` is never persisted to disk by `config.sh`.
|
||||
|
||||
### Step 5: Secret Generation
|
||||
|
||||
Auto-generates **21 unique secrets** — no placeholder passwords remain after this step:
|
||||
@ -370,23 +375,41 @@ See [Services Overview](services.md) for the complete service catalog.
|
||||
|
||||
## Verifying Installation
|
||||
|
||||
After starting services, verify everything is healthy:
|
||||
Changemaker Lite ships a one-shot deployment verifier. Run it after `docker compose up -d`:
|
||||
|
||||
```bash
|
||||
# Check running containers
|
||||
docker compose ps
|
||||
|
||||
# API health check
|
||||
curl -s http://localhost:4000/api/health | python3 -m json.tool
|
||||
|
||||
# View API logs
|
||||
docker compose logs api --tail 20
|
||||
|
||||
# Check for containers in restart loops
|
||||
docker compose ps | grep -i restarting
|
||||
bash scripts/test-deployment.sh --wait 60
|
||||
```
|
||||
|
||||
You should see the API return `{"status":"ok"}` and all started containers in a "running" state.
|
||||
`--wait 60` gives services time to pass their healthchecks on a cold start (first-run image pulls take ~3 min and health stabilization ~90s — brief unhealthy states during this window are expected). The script checks:
|
||||
|
||||
- All containers running with healthy healthchecks
|
||||
- API `/api/health` returns `"healthy"` with database + Redis OK
|
||||
- Admin and media API endpoints respond
|
||||
- (If `--domain yourdomain.org` passed) tunnel subdomains return 200/302/403
|
||||
|
||||
Any failure is printed with the failing component. If everything passes, your install is ready.
|
||||
|
||||
### Manual checks
|
||||
|
||||
```bash
|
||||
docker compose ps # container status
|
||||
curl -s http://localhost:4000/api/health | python3 -m json.tool # API health
|
||||
docker compose logs api --tail 20 # API startup logs
|
||||
bash scripts/validate-env.sh # re-check .env + host ports
|
||||
```
|
||||
|
||||
### Clean reset before reinstall
|
||||
|
||||
If you need to wipe and start over:
|
||||
|
||||
```bash
|
||||
docker compose --profile monitoring down -v --remove-orphans
|
||||
bash scripts/pangolin-teardown.sh --yes # wipes the tunnel org (dry-run by default)
|
||||
sudo rm -rf ~/changemaker.lite
|
||||
```
|
||||
|
||||
For CCP-registered instances, also run `bash scripts/ccp-deregister.sh --yes` before removing the project directory — otherwise the CCP retains a stale Instance row that blocks re-registration of the same slug.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -101,6 +101,13 @@ Changemaker Lite runs on any Linux server with Docker. Minimum specs:
|
||||
|
||||
**Options:** A VPS from DigitalOcean, Hetzner, Linode, or a spare machine on your network. If using a tunnel (Pangolin), the server doesn't need a public IP.
|
||||
|
||||
!!! warning "Watch out for host-level services on our ports"
|
||||
Changemaker Lite binds ~14 host ports including `9090` (Prometheus), `3000` (admin), `4000` (API), `3030` (Gitea), and `8091` (NocoDB). If another service on your host already uses any of these, `docker compose up -d` will partially succeed and leave the stack in a broken state.
|
||||
|
||||
**Common culprit:** `cockpit.socket` — Ubuntu Server's web admin UI — binds `:9090` by default. Disable it with `sudo systemctl disable --now cockpit.socket` before installing, or reconfigure cockpit to a different port.
|
||||
|
||||
The installer runs `ss -Htln` against the required ports before downloading the tarball and aborts with specific remediation hints if any are bound. You can also run the check manually after install with `bash scripts/validate-env.sh`.
|
||||
|
||||
---
|
||||
|
||||
## Optional (Enhance Your Deployment)
|
||||
@ -144,7 +151,8 @@ Use this checklist to make sure you're ready:
|
||||
- [ ] **Tunnel or public IP** — Pangolin credentials (API key + Org ID), or server with public IP + SSL
|
||||
- [ ] **SMTP credentials** — host, port, username, password from your email provider
|
||||
- [ ] **Linux server** with Docker 24+ and Docker Compose v2 installed
|
||||
- [ ] **OpenSSL** installed (for generating secrets during setup)
|
||||
- [ ] **OpenSSL** + **ss** (from `iproute2`) installed (for secret generation + host port check)
|
||||
- [ ] **Host ports free** — if cockpit is enabled, `sudo systemctl disable --now cockpit.socket`
|
||||
- [ ] *(Optional)* Stripe account for payments
|
||||
- [ ] *(Optional)* Mapbox or Google Maps API key for geocoding
|
||||
- [ ] *(Optional)* MaxMind account for geographic analytics
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user