Files
MobilityOps/deploy/unraid/README.md
T
NuklearRabbit acd8b82b09
MobilityOps acceptance / backend (push) Failing after 20s
MobilityOps acceptance / frontend (push) Successful in 26s
MobilityOps acceptance / e2e (push) Skipped
M44: harden release integrity and assurance
2026-08-21 18:32:02 +02:00

95 lines
3.9 KiB
Markdown

# Unraid deployment
MobilityOps is deployed from a committed source archive; the server does not need Gitea
credentials. The portable `compose.yaml` is combined with `compose.unraid.yaml`; of the
MobilityOps-owned services, only the web application is reachable from the LAN. The host's
existing shared n8n remains available on its established port 5678.
## Server layout
- Directory: `/mnt/user/appdata/mobilityops`
- Compose project: `mobilityops`
- Public web: `https://fleetops.itworx.tech` (TLS reverse proxy to host port `1236`)
- API and PostgreSQL: Compose network only
- Shared n8n: `http://192.168.10.150:5678` (outside the MobilityOps Compose project)
## Deploy
Create `.env` from `.env.example`, replace every placeholder secret, set
`MOBILITYOPS_ENV=production`, set both public URLs to
`https://fleetops.itworx.tech`, set `SESSION_COOKIE_SECURE=true`, and configure
`KNOWLEDGE_PROVIDER=ragcore` only after the RAGcore health and source inventory checks pass.
The internal `1236` listener is
an upstream for the TLS proxy, not a user-facing URL.
```bash
cd /mnt/user/appdata/mobilityops
./deploy/unraid/configure-env.sh \
https://fleetops.itworx.tech \
https://n8n.itworx.tech/webhook/mobilityops-return
git archive --format=tar.gz -o /tmp/mobilityops-source.tar.gz HEAD
sha256sum /tmp/mobilityops-source.tar.gz
# Copy the archive and run deploy-release.sh with its SHA-256 and full Git SHA.
```
`deploy-release.sh` stages a clean, commit-named release, builds OCI-labelled immutable
API/web images, promotes without a seed/reset, and verifies migrations, readiness,
backups and observability. Run `python -m app.cli seed --reset` only for initial setup or
an explicit synthetic-demo reset; it is never part of a routine deployment.
Migrations run automatically in the API entrypoint. Import and publish the MobilityOps
workflow into the existing n8n container:
```bash
./deploy/unraid/setup-existing-n8n.sh \
n8n \
https://fleetops.itworx.tech/api/v1/integrations/n8n/return-callback
```
The callback token remains server-side and is never written to the repository. The
bundled n8n service is retained only as a standalone fallback behind the explicit
`bundled-n8n` Compose profile; it is not started in this deployment.
## Operate
```bash
cd /mnt/user/appdata/mobilityops
docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml ps
docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml logs --tail=200
docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml exec api alembic current
docker logs --tail=200 n8n
```
## Backup and restore
The `backup` service creates a backup immediately and then every 24 hours. Every dump is
checked by SHA-256 and `pg_restore --list`; at least weekly the newest dump is also restored
into a disposable database and its migration revision and core table counts are verified.
Backups are retained for 30 days with at least seven copies protected from pruning. Its
healthcheck becomes unhealthy when the daily backup or eight-day restore-drill SLA is missed. Configure
`BACKUP_SECONDARY_DESTINATION=/offsite` plus an independently mounted
`MOBILITYOPS_BACKUP_SECONDARY_DIR` for a second copy.
Create an additional on-demand backup, verify the newest backup, or execute the isolated
restore drill:
```bash
./deploy/unraid/backup-postgres.sh
./deploy/unraid/verify-postgres-backups.sh
docker compose -p mobilityops -f compose.yaml -f compose.unraid.yaml exec -T backup \
/opt/mobilityops/restore-drill-postgres.sh /backups/<backup>.dump
```
A restore is deliberately guarded and creates an additional safety backup before
replacing the database:
```bash
./deploy/unraid/restore-postgres.sh \
backups/postgres/mobilityops-YYYYMMDDTHHMMSSZ.dump \
RESTORE-MOBILITYOPS
```
The restore stops the API, recreates only the configured MobilityOps database, restarts
API/web and verifies the active Alembic revision. Test restores in a disposable environment
before using a production backup for incident recovery.