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.