Architecture & ownership
Your Own Servers in an Afternoon: One File, Every Container
Self-hosting a business application usually means weeks of work. Somebody reads a long installation manual, wires up a database, a backend, a website and a proxy by hand, and types the same address into a dozen settings files. Then a second environment needs the same work again, and every server drifts a little from the last one.
The Timebars suite ships with a deployment package, tbown, that removes that work. You describe every environment in one file. The package builds everything else from it.
One file describes every environment
You fill in tbapps.conf on a workstation, with one section for each environment:
DEV, STAGING, PROD, TRAINING, or whatever you call yours. Each section needs:
- the six addresses your users will type (the three products, the backend, the website and Timebars Cloud)
- the server's IP address
- how HTTPS is handled
Then you run one command:
bash scripts/apply.sh
It writes a complete, ready-to-deploy package for each environment. Every address, route, browser setting and proxy rule is already in place. Nothing is left for someone to type on the server.
Numbered scripts on the server
The package goes to its server with one command, over SSH or as a single archive you carry yourself. On the server a DevOps person runs short numbered scripts:
| Step | Script | What it does |
|---|---|---|
| 1 | 01-install-docker.sh |
installs Docker |
| 2 | 02-create-volumes.sh |
creates the private network and the data volumes |
| 3 | 03-make-passwords.sh |
generates every database password and sign-in secret, on the server |
| 4 | 04-restore.sh |
loads the starting data |
| 5 | 05-backup.sh |
backs up the database, uploads and settings |
| 6 | 06-health-check.sh |
checks every container from inside the server |
| 7 | 07-check-urls.sh |
checks every address through the proxy |
Or, after Docker is installed and the keys are pasted in, one command runs the whole deployment:
cd $TB && ./deploy-all.sh
It is safe to run again. It keeps your passwords and your data, and it recreates only the containers whose image or settings changed.
What you end up running
Six containers on one Docker network:
| Container | What it is |
|---|---|
| tbrun | Agilebars, Timebars and Costbars: one app, three addresses |
| tbbe | the backend: logins, licences, publishing |
| tbpgdb | PostgreSQL, the backend's database |
| tbwwwp | your website: registration, accounts, orders |
| tbhelpapp | Timebars Cloud: dashboards, the help assistant and the AI services |
| tbproxy | Caddy, which serves every address over HTTPS |
Use Caddy with real certificates from Let's Encrypt, or with its own certificates on an internal network. Or skip it and put your existing proxy or load balancer in front: the package writes out the exact routes your network team needs.
Secrets never travel
The package holds addresses and settings, not secrets. Database passwords are generated on each server and never leave it. API keys (AI, email, payments) are pasted on the server into one file. Nothing sensitive goes into email or git.
Updates and rollback are one line
Every release lists the exact image versions it was tested with. To update, you pull
the new release, rebuild the package, back up, and run deploy-all.sh. To roll a single
container back, run its deploy.sh and type the previous version. Each environment
runs on its own server, so you can prove a release in STAGING before PROD ever sees it.
Built for ownership
The same package deploys the images we build and the images you build. If you own the code, your team changes the source, builds its own images, puts their versions in the release file, and deploys them with exactly the same scripts. There is no second process to learn and no gap between our infrastructure and yours.
It works just as well inside a closed network. The package travels as an archive, the images travel as files, and nothing on the server needs to call out.