The hard part
Open source is great. Running it in production was brutal.
The tools themselves worked. The real problem started when we tried to treat
the stack like production software:
What we want from our business software:
- Easy to install and make it work.
- Keep it up to date and healthy.
- Recover quickly when something inevitably breaks.
The first install was already more work than it looked.
Every tool came with its own setup quirks: storage, SMTP, reverse proxy
rules, background jobs, permissions, environment variables.
One app was manageable. A whole stack meant lots of little
moving parts that all had to line up.
What kept breaking the flow:
- Install pain: every tool had its own setup assumptions, and they all had to fit together.
- Update pain: a routine version bump could trigger migrations, config drift, or failed containers.
- Maintenance pain: you were maintaining the whole stack, not just one app at a time.
- Recovery pain: having a backup still did not mean the system would come back online without a lot of manual work and hope.
Updates were not just a button click. A version bump could
change an env var, require a manual migration, break a plugin, or silently
stop a container from coming back up.
A backup is not the same as recovery, either. We didn't just
need the data back. We needed the services, the configs, the volumes, the
automations — everything, exactly as it had been.
# fresh install on a clean machine
~ docker compose up -d
ERROR SMTP_HOST is not set
ERROR ./proxy/conf.d/default.conf not found
# later, routine updates
~ docker compose pull && docker compose up -d
ERROR Notifuse exited after migration step
ERROR worker healthcheck failed
# restoring the stack onto a replacement machine
~ restic restore latest --target /srv/restore
database dump restored
uploads volume restored
ERROR env file .env.production not found
→ software works, but the stack still does not
Without a repeatable install, predictable updates, and a real
recovery path, maintenance meant rebuilding by hand and hoping
nothing subtle was missing. And while that was happening, this is what my team saw in the browser:
https://crm.yourdomain.com
This page isn't working
crm.yourdomain.com is currently unable to handle this request.
HTTP ERROR 503 Reload
That was the part that made open source feel risky, even when the software
itself was good. The apps were not the issue. Installing them, updating them, and keeping the whole stack healthy was.