Workflow automation — the integration hub between every other PMA service. Visual editor for drag-and-drop pipelines, plus code nodes for arbitrary JS/Python. Most cross-service magic in PMA is an n8n workflow.
n8n is the wiring between everything else. Redmine ticket
created → n8n picks it up → posts to Mattermost. Stripe webhook
arrives → n8n updates ERPNext customer. Cron fires → n8n cleans
stale records. Mattermost slash command → n8n webhook → Redmine
API.
Out of the box PMA ships ~20 workflows in
packages/n8n/workflows/ covering common integrations. You add
your own through the n8n web UI (and export them to git for
versioning).
Upstream: n8n.io. Image: n8nio/n8n:latest (or
pinned version). Backend: SQLite by default, can be switched to
postgres for high-throughput setups.
| Use case | Verdict |
|---|---|
| Cross-service automation ("X happens in A → do Y in B") | ✓ — n8n's sweet spot |
| Scheduled jobs (cron with conditional logic + retries) | ✓ — first-class cron trigger |
| Webhook receiver + transformer | ✓ — webhook node + code node |
| ETL between databases | ✓ — Postgres / MariaDB / MongoDB / etc. nodes |
| Long-running batch jobs | △ — works, but consider a dedicated worker for >5 min jobs |
| Real-time event streaming | ✗ — n8n polls; for true streaming use a message bus |
For "this should happen when that happens", reach for n8n first.
The visual editor is faster than writing code for ~80% of cases;
drop to a code node when the logic gets complex.
Already in every profile (enterprise, development, support,
data, full).
just status n8n
# [asd-dev-n8n] ✓ healthy
grep ^N8N_URL= .env
# N8N_URL=https://n8n-xyz1.eu2.tn.example.com
The standard PMA workflows are imported during bootstrap. To see
them:
just n8n-list-workflows
# Lists all imported workflows + their active status
Manifest declares sso.type: oidc. n8n's OIDC strategy redirects
to Authentik for login. After auth, the user lands on n8n's
workflow list.
packages/n8n/workflows/ contains the canonical PMA workflows.
Categorised:
Notifications (PMA → Mattermost):
redmine-ticket-to-mattermost.json — new Redmine ticket → channel postgrafana-alert-to-mattermost.json — Grafana alert → #alertsrelease-run-to-mattermost.json — release-run status → #releasesCross-service sync:
redmine-to-erpnext-customer-sync.json — Redmine project → ERPNext customerzammad-to-redmine-handoff.json — escalate Zammad ticket → Redminemailpit-to-redmine.json — incoming dev email → file as ticketScheduled / cron:
cron-stale-ticket-purge.json — close untouched tickets dailycron-superset-dataset-refresh.json — refresh dashboards nightlycron-backup-verify.json — daily check that all just backup succeededMattermost slash commands (in → webhooks):
slash-ticket-create.json — /ticket create <subj> → Redmineslash-standup.json — /standup → posts structured templateslash-oncall.json — /oncall → pings on-call rotationEach is a JSON file you can import into n8n manually (via the UI)
or have bootstrap import (the default).
# 1. Build the workflow in n8n's web UI
# 2. Export it (3-dot menu → Download)
# 3. Save to packages/n8n/workflows/<descriptive-name>.json
# 4. Commit + push
# 5. Next bootstrap (or just n8n-import-workflow <name>) imports it
git add packages/n8n/workflows/my-workflow.json
git commit -m "feat(n8n): #1234 add my-workflow"
Workflows in git = workflows in your dev env = workflows
deployed to prod via the next just release-run.
n8n MCP tools are available to AI agents:
| MCP tool | What it does |
|---|---|
n8n_list_workflows |
List all workflows |
n8n_get_workflow |
Get one by id |
n8n_create_workflow |
Create from JSON |
n8n_update_workflow |
Update |
n8n_delete_workflow |
Delete |
n8n_activate_workflow / _deactivate_workflow |
Toggle active state |
n8n_trigger_workflow |
Manually trigger |
n8n_workflow_executions |
List recent executions |
n8n_execution_details |
Inspect one execution |
n8n_delete_execution |
Clean up |
Useful when an agent needs to "look at the workflow that should
have run when X happened" — call n8n_workflow_executions filter
by status=failed.
just n8n-status # container health
just n8n-restart # restart n8n
just n8n-logs # follow container logs
just n8n-list-workflows # list workflows + active state
just n8n-import-workflow PATH # import a JSON workflow file
just n8n-export-workflow ID # export one workflow to JSON
just backup n8n # snapshot workflows + execution history
just restore n8n TIMESTAMP # restore from backup
For deeper admin (user management, credentials, settings), n8n's
web UI is the path.
Manifest declares backup.type: workspace (default — backs up
/home/node/.n8n/ which contains the SQLite DB + credentials).
If you've switched to postgres backend (via env var override),
the manifest's backup.type should switch to database.
Post-restore quirks for n8n:
fixes:
post_restore:
functions:
- name: re_encrypt_credentials
description: Credentials in DB are encrypted with N8N_ENCRYPTION_KEY; restored DB needs the same key
targets: container
- name: reactivate_workflows
description: Restored workflows are imported as inactive; re-activate per the manifest
targets: container
The encryption key thing is the trap to remember: the
N8N_ENCRYPTION_KEY in .env must match the one that was set
when the backup was taken. Lose the key, lose access to stored
credentials. Back up N8N_ENCRYPTION_KEY separately (via vault
or password manager).
DB_TYPE=postgresdb env var. PMA's manifest accommodatesN8N_ENCRYPTION_KEY. The.env. Back itid field withSQLITE_CONSTRAINT: NOT NULL. PMA'sreleases/3921-restore-workflows-via-cli.ts works around this/pma/learn/02-add-a-service — how to add a service that n8n then connects to./pma/services/redmine — primary tickets target for n8n flows./pma/services/mattermost — primary notifications target.