https://accounts.veripath.co.uk (ERPNext site on the shared VPS3 stack).
healthcare_accounting| Item | Value |
|---|---|
| URL | https://accounts.veripath.co.uk |
| Login | Keycloak SSO (enabled 2026-08-25) — "Login with Keycloak" button on the login page (auth.veripath.co.uk, realm veripath, client erpnext) |
| Fallback | Administrator password — stored locally at /root/work/erpnext-deploy/veripath-accounting-creds.txt (mode 600). Never publish on the wiki. |
| SSO setup | Keycloak erpnext client gained an explicit https://accounts.veripath.co.uk/* redirect URI (wildcards don't match the bare domain) + Social Login Key on the site. Verified 2026-08-25: button renders, authorize URL accepted (200), invalid URIs rejected (400). |
| Users | matthew@veripath.co.uk and admin@veripath.co.uk (Keycloak realm veripath). Roles expanded 2026-08-28 to full access — both users now hold: System Manager, Item Manager, Sales Manager, Sales Master Manager, Purchase Manager, Purchase Master Manager, Stock Manager + the original Accounts Manager, Accounts User, Desk User. This was prompted by permission errors in the UI (e.g. no "+ New" on Item). ERPNext v15 permission model (verified 2026-08-28): System Manager does NOT cover business doctypes — create rights come from functional roles (Customer/Price List → Sales Master Manager; Item/Item Group/UOM → Item Manager; Supplier → Purchase Master Manager; etc.), so "admin" users need the manager-role set above. Desk User is required — it's the only non-System-Manager role with read on the Workspace doctype; without it the desk 403s ("You do not have enough permissions..."). Further users: create the frappe User with the same email + the roles matching their job (Accounts Manager + Accounts User + Desk User for accounts-only; the full set above for admins). |
accounts.veripath.co.ukThe accounts.* vhost (DNS wildcard, TLS cert, nginx → ERPNext :8005) already existed,
so claiming the bare domain for VeriPath's own site required zero DNS/TLS changes (it
returned 404 before). One nginx addition was needed (2026-08-25): a location /assets/
block serving /var/www/erpnext-assets — without it the vhost proxied CSS/JS bundles to
gunicorn, which 404'd them and the login page rendered as raw HTML. The block mirrors the
test-client.accounts.* vhosts and serves all *.accounts.* tenants from that vhost.
A separate accounting.veripath.co.uk was considered but would have needed a new DNS
record + cert for no functional gain.
accounts.veripath.co.uk on the shared VPS3 ERPNext stackerpnext_web / erpnext_worker / erpnext_scheduler, image erpnext_v15:latest).erpnext_veripath_postgres (postgres:15-alpine, --restart unless-stopped)172.18.0.1:5438:5432 (docker-bridge only — same pattern as client-VPS DBs)erpnext_veripath_pg_datapg_hba.conf hardened: only 127.0.0.1/32 + 172.17.0.0/16 + 172.18.0.0/16veripath_accountingVP), country United Kingdom, currency GBP,gb_uk_healthcare_clinic etc. — so the generic Standardcompany default at all — workspace charts (e.g. "Sales Order Trends" on thefrappe.db.set_default("company", "<company>") +frappe.defaults.set_user_default("Company", "<company>", user) per user +default_company + clear cache + web restart (same recipedesktop:home_page = "setup-wizard" (install.py seeds it; only the wizardPage record named setup-wizard exists,boot.add_home_page resolves it and desk.js then skips creating thefrappe.db.set_default("desktop:home_page", "workspace") (the wizard's standard value) + set User default_workspace = Home on each user + clear cache + web restart. Applied 2026-08-28.Consulting Services (sales item, non-stock).# 1. local postgres (VPS3)
docker run -d --name erpnext_veripath_postgres -p 172.18.0.1:5438:5432 \
-v erpnext_veripath_pg_data:/var/lib/postgresql/data \
-e POSTGRES_PASSWORD='<generated>' --restart unless-stopped postgres:15-alpine
# ... then harden pg_hba (docker bridges + localhost only) and reload
# 2. site (detached — ~10-20 min; log /tmp/bench-new-site.log)
docker exec -d -e DB_ROOT_PW=... -e ADMIN_PW=... erpnext_web bash -c \
'cd /home/frappe/frappe-bench && bench new-site accounts.veripath.co.uk \
--db-type postgres --db-name veripath_accounting \
--db-host 172.18.0.1 --db-port 5438 --db-root-username postgres \
--db-root-password "$DB_ROOT_PW" --admin-password "$ADMIN_PW" \
--install-app erpnext > /tmp/bench-new-site.log 2>&1'
# 3. company bootstrap (scripts/bootstrap_veripath_company.py, in-container)
docker exec -e FRAPPE_SITE=accounts.veripath.co.uk erpnext_web bash -c \
'cd /home/frappe/frappe-bench && ./env/bin/python /tmp/bootstrap_veripath_company.py'
Notes:
db_host 172.18.0.1 — both bridge ranges must stay in pg_hba.__default | currency | INRtabDefaultValue, and frappe.db.get_default("currency") prefers that row over thefrappe.db.set_default("currency", "GBP") + clear cache
erpnext.accounts.party.set_price_listdefault_price_list = Standard Selling on the Customer Groups (Commercial /selling_price_list / price_list_currency / plc_conversion_rate check. (The GP/dentalencryption_key in site_configFernet.generate_key().decode()) — a 64-char hexcryptography isn't in the container's system python).is_setup_complete() readsInstalled Application rows' is_setup_complete flag for frappe + erpnext —UPDATE "tabInstalled Application" SET is_setup_complete=1 WHERE app_name IN ('frappe','erpnext') + clear cache. (System Settings setup_complete/country/language/66c391e, 2026-08-25): two ERPNext/MySQL-isms thatgunicorn_app.py patch module (patches/gunicorn_app.py), then rebuilt/recreated:
CAST(... AS UNSIGNED),SUBSTRING_INDEX, REGEXP — duplicate customer names returned HTTP 500type "unsigned" does not exist). Added _replace_mysql_funcs."delinked"=true but frappe mapssmallint (no field maps to boolean) —DatatypeMismatch. Added _replace_bool_literals (=true/=false → =1/=0,175eebc, a97c084, 2cf6639). The item searcherpnext.controllers.queries.item_query) failed on PostgreSQL with threeLIMIT start, count → LIMIT count OFFSET start_replace_limit_comma, LIMIT #,# syntax is not supported);tabItem.name vsfrom "tabItem") → quoted (_quote_table_refs, missing FROM-clause entry);'0000-00-00' → '0001-01-01' (_replace_zero_dates,date/time field value out of range). Verified by replaying the exactsearch_link API call (HTTP 200, item returned) + 22 regression tests inpatches/test_gunicorn_patches.py.599af55).erpnext/controllers/ trends.py) builds MAX(t2.item_name) t2.item_name — MySQL allows qualifiedsyntax error at or near "."). Added_quote_dotted_aliases () <ident>.<ident> → ) AS "<ident>.<ident>",query_report.run call (HTTP 200) + item-search regression; 26 tests.frappe/erpnext:v15scripts/smoke_test_accounting.py (dummy customer →frappe.ping → pong over the public URL.Consulting Services item retained.test-client.accounts.gp|dental.*) unaffected — verified healthyerpnext_veripath_pg_data is not yet covered by the/opt/kcadmin.sh contains a plaintext Keycloak admin password (master realm) —→ Accounting App index
→ ERPNext deployment & implementation
→ Module rationalisation plan (hide surplus modules — applied 2026-08-27)
============================================================
Page: https://wiki.veripath.co.uk/development/projects/accounting/veripath-accounting
============================================================
Page: https://wiki.veripath.co.uk/development/projects/accounting/veripath-accounting
============================================================
Page: https://wiki.veripath.co.uk/development/projects/accounting/veripath-accounting
============================================================
Page: https://wiki.veripath.co.uk/development/projects/accounting/veripath-accounting
============================================================
Page: https://wiki.veripath.co.uk/development/projects/accounting/veripath-accounting