KLEINUILTIES-WEBAPP/DEPLOY.md
Slim Uiltjies App 1939bf2ef4 Initial commit: Slim Uiltjies AfterCare invoice system
- 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
2026-08-08 09:25:17 +02:00

6.8 KiB
Raw Permalink Blame History

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)

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_PIN from the default 847291 to something only you know
  • Enable HTTPS (Coolify does this automatically via Let's Encrypt)
  • Set up backups — either n8n (see below) or periodic cp of /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.

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).


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

  1. In n8n, create a new workflow
  2. 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)
  3. Add a Set node to capture the body data
  4. Add a Postgres / MySQL / NocoDB node to insert the data into a table
  5. 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:

  1. In Coolify, change ADMIN_PIN to a new value
  2. Click Redeploy
  3. Log in with the new PIN

If you forgot the PIN entirely:

  1. SSH into the Coolify host
  2. docker exec -it slimuiltjies sh
  3. cat /data/data.json to confirm data is there (don't lose it!)
  4. Redeploy with a new ADMIN_PIN via Coolify

"Data disappeared after redeploy"

You forgot the Persistent Volume. To recover:

  1. SSH into the host and check /data/ — if it's empty, data is gone
  2. Restore from your most recent backup (cp backup.json /data/data.json)
  3. 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

  1. Push changes to your Git repo
  2. Click Redeploy in Coolify
  3. The Persistent Volume preserves /data/data.json across deploys

To verify the data is preserved, SSH in and cat /data/data.json before and after a redeploy.