
Some time ago I vibe-coded a project management app (which i still use today) because pretty much all the existing options like Monday, Asana, and MS Project suck in one way or another, or paywall the features I needed. I remember searching for the easiest, most painless way to deploy it and it turned out containers were the answer. Super straightforward.
Docker or Podman?

There are many options to run containers but it usually comes down to Docker or Podman.
Docker works great, but Docker needs a daemon (dockerd) running at all times, and I don’t want another background service in my system. For a personal server I don’t fully trust myself, so the less the better.
Podman doesn’t have a daemon. You run podman run and the container is just a process. That’s a model I like.
If you’re on Fedora or any RHEL-based distro, Podman is already installed. If not, just install it from source or your distro repo. If you already use Docker, Podman will work the same, same syntax, registries, and images work.
You can even alias docker to podman:
alias docker=podman
Quadlets vs Compose
For running a full stack app with multiple services you have: podman-compose (or docker-compose) or Quadlets.
podman-compose
Most guides and tutorials show you how to run stacks with docker-compose and podman-compose works the same.
This works fine. The downside is that there are some “features” that may not work as well in podman-compose and something could silently break. Also every time you want automated restarts, update hooks, or boot persistence, you’re bolting things on top. All the “how do I make this run on reboot” guides in the Docker world are basically gluing compose to systemd with duct tape. It sucks.
Quadlets
Quadlets are a way to run Podman containers with native systemd integration. You only have to write a .container file and reload the systemd daemon to run the container as a systemd service. Natively.
The only thing that sucks is that every “component” (container, network, volume) needs its own file, so multi-service stacks get verbose and clunky. There are also way fewer guides for this compared to compose, which is annoying. But it’s a one-time setup and you never have to think about it again.
To use Quadlets, create a .container file in ~/.config/containers/systemd/ (for rootless containers):
[Container]
Image=localhost/myapp:latest
PublishPort=3000:3000
Environment=NODE_ENV=production
[Service]
Restart=always
[Install]
WantedBy=default.target
Then reload the systemd daemon to implement the changes:
systemctl --user daemon-reload
systemctl --user enable --now myapp
Now your app starts on boot, restarts on failure, and logs go to the journal (you can even configure it to pull updates automatically from a container registry):
journalctl --user -u myapp -f
Again, the thing that I love about Quadlet is that you get the “pain” (not really) in the initial setup only and forget about it.
Exposing Your App With Caddy
If you’re using Caddy as a reverse proxy (which I recommend), nothing special is needed. Container exposes a port, Caddy proxies to it, business as usual:
myapp.yourdomain.com {
reverse_proxy localhost:3000
}
One thing: rootless containers can’t bind to ports below 1024. Expose something in the 3000s and let Caddy handle 80 and 443.
The SELinux Pain
If you are using SELinux, you might get some errors when running containers. Keep it enabled though.
Volume Mounts: SELinux silently blocks containers from reading mounted host directories. To fix it just add :Z to your volume mounts:
podman run -v ./data:/app/data:Z myapp
Rootless Permission Errors: Some images were built assuming they run as root and throw weird permission errors in rootless mode. Fix it with --userns=keep-id, which maps your UID into the container so file permissions line up:
podman run --userns=keep-id -v ./data:/app/data:Z myapp
To Recap?

Create a vibe-coded app, run it as container, build the image, drop a Quadlet file, enable the “container” service, point Caddy at the port, access the app from the exposed port or DNS name (if configured). No Docker daemon, no root processes, no compose files.
I’ve been running all my personal projects this way and once the workflow is setup it becomes very easy to maintain, secure, and rollouts become super easy and fast. Maybe I’ll do more posts about Podman containers? Maybe not?