Files
factory/vibe/guidebooks/erp
Gabriel Radureau 7bf83e75ed docs(vibe): add erp/ guidebook (Dolibarr deployment + backup/recovery + ops)
Dedicated tree-docs guidebook under vibe/guidebooks/erp/ for the lab's most
data-critical app, cross-linked from the applications hub (bidirectional):

- README.md             : Dolibarr 22.0.4 on Postgres; data-criticality; overview
  diagram; the Vault-unseal-before-scale recovery ordering (CAUTION).
- deployment.md         : upstream image + custom entrypoint (MySQL->psql), the
  50Gi Longhorn RWX documents PVC, Vault CRDs + the shared app_roles iac, init
  scripts (conf.php creds, table-ownership), ingress, CI.
- backup-and-recovery.md: the Ansible CronJob pg_dump (daily 04:00, 15-day
  retention) + restore Job (scale-0 -> restore -> scale-1); the cluster recovery
  ordering (Longhorn -> Vault unseal -> erp scale-up).
- operations.md         : the read-only bin/arcodange CLI, static/company.json,
  Deno+Playwright tests, day-2 ops.

erp code via full gitea URLs; CLUSTER_RECOVERY.md by name; 2 mermaid diagrams
MCP-validated; zero dead links.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-23 22:12:11 +02:00
..

vibe > Guidebooks > ERP

ERP

Status: Active Last Updated: 2026-06-23 Upstream: Applications hub · 01 · factory Downstream: Deployment · Backup & recovery · Operations Related: tools secrets-and-vso · factory postgres-iac · storage concept · factory recover playbooks · safe-prod-like-environment ADR

This guidebook maps erp — the lab's Dolibarr 22.0.4 accounting/business ERP and its single most data-critical application. It is a PHP/Apache workload built from the upstream dolibarr/dolibarr image, served internally at erp.arcodange.lab (Traefik websecure + localIp@file + a letsencrypt-resolver cert). Everything a reader needs to deploy it, keep its data safe, and operate it lives in the three child pages below; this page is the orientation map.

What makes erp special

erp is the complex sibling of the webapp / url-shortener archetypes. It carries the same four-ingredient app pattern (Dockerfile-less reuse of an upstream image, a chart/, an iac/, .gitea/workflows) but layers several things on top that the archetypes do not:

Trait erp specifics Why it matters
Upstream image dolibarr/dolibarr:22.0.4 — not a repo-built image No custom Dockerfile; the chart adapts the upstream container at runtime
Postgres, not MySQL Dolibarr classically assumes MySQL; erp runs on PostgreSQL (DOLI_DB_TYPE: pgsql) A custom entrypoint rewrites the upstream docker-run.sh mysql invocation into psql before launch
DB path pod → pgbouncer.tools:5432 → the erp Postgres database on pi2 Shares the tools pgbouncer pooler like the webapp archetype
Vault wiring dynamic rotating DB creds (postgres/creds/erp) + static KV config (kvv2 erp/config) via the shared app_roles module The pod cannot start without VSO-injected DOLI_DB_USER / DOLI_DB_PASSWORD
Document persistence a 50Gi Longhorn RWX PVC (storageClassName: longhorn, accessModes: ReadWriteMany, helm.sh/resource-policy: keep) mounting /var/www/documents, /var/www/html/custom, and /var/backups Uploaded invoices/PDFs/attachments are real business records — losing them is the worst case
Backup + ops its own backup/restore subsystem plus a read-only ops CLI (bin/arcodange) Data-criticality demands both an escape hatch for restores and a safe way to inspect live state

Overview — how erp is wired

%%{init: {'theme': 'base'}}%%
flowchart LR
    classDef src fill:#2563eb,stroke:#1e40af,color:#fff
    classDef proc fill:#059669,stroke:#047857,color:#fff
    classDef store fill:#7c3aed,stroke:#6d28d9,color:#fff
    classDef net fill:#b45309,stroke:#92400e,color:#fff

    CI["factory / erp CI<br>tofu apply (iac/)"]:::src
    VAULT["Vault<br>postgres/creds/erp (dynamic)<br>kvv2 erp/config (static)"]:::store
    ARGO["ArgoCD<br>syncs chart/ (ns erp)"]:::proc
    POD["Dolibarr pod<br>dolibarr/dolibarr:22.0.4<br>custom entrypoint → psql"]:::proc
    VSO["VSO<br>VaultAuth + VaultDynamicSecret<br>+ VaultStaticSecret"]:::proc
    PGB["pgbouncer.tools:5432"]:::net
    PG["Postgres erp db<br>(pi2)"]:::store
    PVC["50Gi Longhorn RWX PVC<br> /var/www/documents"]:::store
    BK["backup CronJob / runner<br>pg_dump → documents/admin/backup"]:::proc

    CI --> VAULT
    ARGO --> POD
    VAULT -. "creds + config" .-> VSO
    VSO -- "vso-db-credentials + secretkv" --> POD
    POD --> PGB --> PG
    PVC -- "mounts /var/www/documents" --- POD
    BK -- "dumps DB + writes to" --> PVC
  1. factory / erp CI runs tofu apply over iac/ to declare erp's Vault objects — a Postgres dynamic-secret role and a Kubernetes auth role — through the shared app_roles module, and seeds the static kvv2 erp/config KV (admin login, instance UUID).
  2. ArgoCD (factory's app-of-apps) syncs the chart/ into the erp namespace.
  3. The Dolibarr pod comes up from dolibarr/dolibarr:22.0.4; its custom entrypoint rewrites the upstream docker-run.sh so SQL runs through psql instead of mysql.
  4. VSO authenticates to Vault (the auth VaultAuth CRD), materialising vso-db-credentials (dynamic, rotating DB user/password from postgres/creds/erp) and secretkv (static config from kvv2 erp/config); both are injected into the pod, and a credential rotation triggers a rollout restart.
  5. The pod connects to the erp Postgres database through the tools pgbouncer.tools:5432 pooler.
  6. A 50Gi Longhorn RWX PVC mounts /var/www/documents (plus /var/www/html/custom and /var/backups), holding every uploaded document and generated PDF.
  7. The backup subsystem dumps the erp database with a version-matched pg_dump and lands the archive under documents/admin/backup on that same PVC — see Backup & recovery.

Caution

Recovery ordering: Vault MUST be unsealed before erp is scaled up. The Dolibarr pod has no usable DB credentials of its own — it depends entirely on VSO materialising vso-db-credentials from postgres/creds/erp. If erp is scaled up while Vault is still sealed, the pod crash-loops with no database access. During a cluster rebuild, unseal Vault first, confirm VSO has reconciled the erp secrets, and only then scale erp. The full sequence (cluster bring-up → Vault unseal → storage → apps) is covered by Backup & recovery, the storage concept, the factory recover playbooks, and the cluster-wide CLUSTER_RECOVERY.md runbook.

Index

Page What it covers Status
Deployment The chart, the upstream image + custom entrypoint, the Postgres-over-pgbouncer wiring, the Vault CRDs (dynamic creds + static config), and the ingress Active
Backup & recovery The document PVC, the pg_dump-based backup subsystem, restore procedure, and where erp sits in cluster-recovery ordering Active
Operations The read-only bin/arcodange ops CLI and day-to-day operational tasks (table-ownership fix-ups, liveness checks, audits) Active

Maintenance rule

Important

When the erp repo changes shape, these pages change in the same PR. If you alter the chart structure, the custom entrypoint, the Vault wiring, the document PVC, the backup subsystem, or the ops CLI, update this hub and the relevant child page in the same change. A reference map that drifts from the real chart/, iac/, and backup/ sends agents confidently down dead paths — and for the lab's most data-critical app that risk is highest here.

Cross-references

  • Applications hub — the common four-ingredient app pattern; erp is its complex sibling, beside the webapp and url-shortener archetypes.
  • 01 · factory — the ArgoCD app-of-apps that emits erp's Application CRD.
  • tools secrets-and-vso — the app_roles module + VSO runtime that delivers erp's dynamic DB creds and static config, and the pgbouncer pooler the pod connects through.
  • factory postgres-iac — the per-app erp PostgreSQL database + role erp runs on.
  • storage concept — how the 50Gi Longhorn RWX document PVC is provisioned and recovered.
  • factory recover playbooks — the Ansible recovery steps that must precede scaling erp back up.
  • safe-prod-like-environment ADR — why the lab keeps erp deployed prod-like and the data-criticality trade-offs behind it.