- Progressive Web App with Express + JSON backend - PIN-based auth, multi-device sync - Invoice + Statement PDF generation (branded, Grandstander + Nunito) - Mobile + Desktop responsive layouts - n8n backup integration - Custom logo upload - Settings for business info, fees, banking - Bulk invoice generation - Web Share API integration
6.8 KiB
Deploying Slim Uiltjies AfterCare on Coolify
Step-by-step guide for hosting on Coolify (self-hosted PaaS).
Prerequisites
- A running Coolify instance (v4.x)
- A Git repository with this code (GitHub, GitLab, Gitea, etc.)
- A domain you control (optional but recommended for HTTPS)
Option A — One-click: Git repository (recommended)
1. Push your code
cd /Volumes/EXT/DEVELOPMENT/SLIMUILTIES
git init
git add .
git commit -m "Initial Slim Uiltjies app"
git remote add origin git@github.com:YOUR-USER/slimuiltjies.git
git push -u origin main
2. In Coolify, create a new Application
- Go to Projects → + New → Application
- Choose Private Repository (with deploy key) or Public Repository
- Pick your repo + branch (
main) - Build Pack:
Dockerfile - Port:
3000
3. Add a Persistent Volume (CRITICAL — protects your data)
In the Storage tab of your new service:
| Mount Path | Size |
|---|---|
/data |
1 GB (plenty for years of invoices) |
Without this step, every redeploy will wipe your data.
4. Set Environment Variables
In the Environment Variables tab:
| Key | Value | Notes |
|---|---|---|
ADMIN_PIN |
847291 |
Change this before going live. 6–8 digits recommended. |
N8N_WEBHOOK_URL |
(empty by default) | Optional. Paste your n8n backup webhook URL when ready (see §6). |
N8N_WEBHOOK_TOKEN |
(empty) | Optional auth token if your n8n webhook requires it. |
PORT |
3000 |
Don't change unless you know what you're doing. |
5. Set the domain
In Domains:
- Click + Add Domain
- Enter your domain:
invoices.slimuiltjies.co.za - Coolify auto-provisions Let's Encrypt HTTPS
6. Deploy
Click Deploy. Watch the build logs. When you see [server] Slim Uiltjies listening on :3000, you're live.
7. Test
- Visit
https://invoices.slimuiltjies.co.za - Should see the PIN login screen
- Enter your PIN
- The app opens with the sample data
Option B — Docker Compose
If you prefer compose-style configuration:
Create docker-compose.yml in this directory:
version: "3.8"
services:
slimuiltjies:
build: .
container_name: slimuiltjies
restart: unless-stopped
ports:
- "3000:3000"
volumes:
- ./data:/data
environment:
- ADMIN_PIN=847291
- DATA_FILE=/data/data.json
- NODE_ENV=production
In Coolify: + New → Docker Compose → paste the contents → set up domain → deploy.
This keeps the data file on the host (so cp data/data.json data-2026-08-08.json works for backups).
🔒 Before you go live (security checklist)
- Change
ADMIN_PINfrom the default847291to something only you know - Enable HTTPS (Coolify does this automatically via Let's Encrypt)
- Set up backups — either n8n (see below) or periodic
cpof/data/data.json - Test the PIN lockout — close browser, reopen, confirm login screen appears
- Bookmark the PWA install prompt — on iPhone Safari → Share → Add to Home Screen
💾 Backup strategies
The app stores everything in /data/data.json. Backup options, cheapest to fanciest:
Option 1 — Manual copy
SSH into your Coolify host:
docker cp slimuiltjies:/data/data.json ./slimuiltjies-backup-$(date +%F).json
Run weekly via cron.
Option 2 — n8n auto-backup (recommended)
See §6 below. Every save is POSTed to an n8n webhook, where you can:
- Store in a database
- Email yourself a weekly summary
- Snapshot to Dropbox / S3 / Google Drive
- Pipe to an AI agent for queries
Option 3 — Coolify's built-in storage snapshots
In Storage → /data → Snapshots, enable scheduled snapshots. Simple but coarse (file-level).
🔁 Setting up n8n backup (optional but recommended)
Step 1 — Deploy n8n on Coolify (if you don't have it)
Coolify has a one-click n8n template: + New → Service → n8n. Deploy it as a separate service on the same Coolify instance.
Step 2 — Create the backup workflow in n8n
- In n8n, create a new workflow
- Add a Webhook trigger node:
- HTTP Method:
POST - Path:
slimuiltjies-backup - Authentication: Header Auth (create a credential with a random secret like
n8n-slim-secret-xyz123)
- HTTP Method:
- Add a Set node to capture the body data
- Add a Postgres / MySQL / NocoDB node to insert the data into a table
- Save and copy the webhook URL
Step 3 — Configure in the app
In the Slim Uiltjies app:
- Go to Settings → Data
- Paste your n8n webhook URL into the "Auto-backup to n8n" field
- Paste your auth token
- Tap Test backup — you should see a new record appear in n8n
Every change after that is pushed to n8n within ~30 seconds.
📱 Installing on phones (PWA)
Once deployed at your domain:
- iPhone (Safari): Visit your URL → tap Share → Add to Home Screen
- Android (Chrome): Visit your URL → tap the install banner at the bottom
The app icon is your owl mascot. It opens full-screen like a native app.
🐛 Troubleshooting
"Login screen won't accept my PIN"
The PIN is case-sensitive and must match ADMIN_PIN exactly. To reset:
- In Coolify, change
ADMIN_PINto a new value - Click Redeploy
- Log in with the new PIN
If you forgot the PIN entirely:
- SSH into the Coolify host
docker exec -it slimuiltjies shcat /data/data.jsonto confirm data is there (don't lose it!)- Redeploy with a new
ADMIN_PINvia Coolify
"Data disappeared after redeploy"
You forgot the Persistent Volume. To recover:
- SSH into the host and check
/data/— if it's empty, data is gone - Restore from your most recent backup (
cp backup.json /data/data.json) - Add the Persistent Volume mount before redeploying again
"App won't load — stuck on splash screen"
Check the browser console (F12) for errors. Common causes:
- Old cached SW from before the deploy — clear site data or use incognito
- Wrong domain in
manifest.json— should be auto-relative, but check<base>tag if you added one
"PDF generation is broken"
Check the browser console for jsPDF errors. Usually caused by:
- HTTPS not enabled (jsPDF needs it for some browsers)
- Service worker serving old code — force refresh
📊 Resource requirements
- RAM: ~50 MB idle, ~150 MB peak (during PDF generation)
- CPU: minimal
- Disk: data.json grows ~50 KB/month. 1 GB volume = 20+ years of headroom
- Network: tiny — single JSON sync every change
A free-tier Coolify instance handles this easily.
🔄 Updating the app
- Push changes to your Git repo
- Click Redeploy in Coolify
- The Persistent Volume preserves
/data/data.jsonacross deploys
To verify the data is preserved, SSH in and cat /data/data.json before and after a redeploy.