- Rootless Podman + Quadlet is used to run the API, frontend, and Postgres in a single pod.
- Default exposed ports are 10101 (API) and 10102 (web).
- Run everything as a non-root user and put a reverse proxy (Caddy/Traefik/NGINX) in front. If you want to use Caddy using rootless Podman, check this repository.
- The frontend proxies traffic to the API inside the pod, so only the web port needs to be published for a functional app.
All paths below assume you run commands from
deploy/so the hostPath mounts inapp-pod.yamlresolve correctly.
- Podman with Quadlet support (systemd user services enabled).
sudo loginctl enable-linger <user>so the pod can start automatically at boot.sudo systemctl enable tmp.mountto avoid Podman boot ID errors.
./build.sh [api|web|all] (default all) builds images tagged app_api:latest and app_web:latest.
- Copy and lock down secrets:
cp app-secrets{.example,}.yaml && chmod 600 app-secrets.yaml - Edit
app-secrets.yaml:POSTGRES_USER,POSTGRES_PASSWORD,POSTGRES_DB: Postgres credentials and database name.DATABASE_URL: Full SQLAlchemy URL (e.g.,postgresql+asyncpg://pguser:pgsecret@db:5432/app).
- Create the secret:
podman kube play app-secrets.yaml
- Copy API config:
cp ../app_api/config.example.toml api-config.tomland set at leastsecret_key(plus any other overrides you need). - Optional DB seed/restore: create
./db_init/and drop SQL files there; Podman runs them on first start.
- Start the pod for a test run:
podman kube play app-pod.yaml - Check if the containers are running with
podman ps - Stop the test pod once verified:
podman kube down app-pod.yaml
- Edit
app-pod.kubesoYaml=points to your actual repo path (current value is a placeholder). - Copy
app-pod.kubeandapp.networkinto~/.config/containers/systemd(create the directory if needed). - Reload systemd:
systemctl --user daemon-reload - Start and enable the service:
systemctl --user start app-pod.service - If the unit doesn't appear, inspect the generated systemd with
/usr/libexec/podman/quadlet --user --dryrun
- Check status/logs:
systemctl --user status app-pod.serviceandjournalctl --user -u app-pod.service -f - Default ports: API
10101, web10102; adjust host ports inapp-pod.yamlif needed. - If you change image tags, also update the
image:fields inapp-pod.yaml.