I've always just set everything up via the command line, and it's tedious/not repeatable (and there's also no isolation). I'm sure there's a better way, but usually the solutions I see involve gluing together a bunch of different tools--possibly even more work than I'm already doing (although there are benefits!).
I start with a template docker-compose yaml that contains the barebones: network settings, labels for Traefik (eg. Let’s Encrypt config), placeholders for the image/container name, volumes, env variables, etc. I fill this in based on the container I want to setup. Many self-hosted apps provide example docker-compose configurations - I often just merge them with my template by hand. It’s usually just a couple of lines.
I edit the files in vscode (but directly over ssh). Not a huge fan of editing YAML in the terminal.
Then, I execute an aliased command that goes something like this:
docker-compose down ; docker-compose pull && docker-compose up -d && docker-compose logs -f
to see if the container stands up, and tweak if necessary.1. Copy docker-compose.yml (for my private stuff there is a single one containing all services + traefik) and config files (host-mounted into services from a config dir) to new host.
2. Start services (docker-compose up).
3. Restore runtime data (in my case I mostly pull some db dumps from my restic repos and load them into the db containers).
The backend server is written in Go and after building it only a single binary has to be deployed. A second repository contains the frontend (HTML, JS) which you copy to a path that you make available via your webserver. That's basically it.
[0]: https://github.com/matomo-org/docker/tree/master/.examples/n...
Essentially exactly the same process as LAMP deployment of yesteryear .
I mean, yes you can make it complicated/enterprise with k8s and such.
I found cloudron to be a good middle balance.
I say this as someone running about 250 applications or so. One cloudron vm , one bare Ubuntu server vm with nothing but docker installed.
https://github.com/chaifeng/ufw-docker has a good overview and ufw-specific solution (I use it on my rpi).