Ansible + Podman/systemd Guide¶
Manage containers as systemd services with Ansible automation.
Why This Approach¶
- Standard Linux tools (systemd, journalctl)
- GitOps via Ansible + GitHub Actions
- Multi-server ready
- Rootless containers (better security)
- No daemon overhead
- Easy client handoffs
Architecture¶
Git Repository
├── ansible/
│ ├── inventory/production.yml
│ ├── playbooks/site.yml
│ └── roles/
│ ├── umami/
│ ├── grafana/
│ └── postgres/
└── .github/workflows/deploy.yml
↓ (CI/CD runs Ansible)
VPS Servers
├── systemd services
└── Podman containers
Example: Umami Service¶
systemd unit file:
[Unit]
Description=Umami Analytics
After=network.target
[Service]
Type=simple
Restart=always
ExecStartPre=/usr/bin/podman pull ghcr.io/umami-software/umami:v2.10.0
ExecStart=/usr/bin/podman run --rm --name umami \
-p 3000:3000 \
-e DATABASE_URL=postgresql://... \
ghcr.io/umami-software/umami:v2.10.0
ExecStop=/usr/bin/podman stop umami
[Install]
WantedBy=multi-user.target
Ansible role:
- name: Install Podman
apt:
name: podman
state: present
- name: Create systemd service
template:
src: umami.service.j2
dest: /etc/systemd/system/umami.service
- name: Enable and start service
systemd:
name: umami
enabled: yes
state: started
Deployment¶
# Deploy everything
ansible-playbook playbooks/site.yml
# Deploy specific service
ansible-playbook playbooks/site.yml --tags umami
# Update version
ansible-playbook playbooks/site.yml -e "umami_version=v2.11.0"
CI/CD (GitHub Actions)¶
name: Deploy to Production
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Install Ansible
run: sudo apt install -y ansible
- name: Deploy
run: ansible-playbook playbooks/site.yml
Monitoring¶
# Service status
systemctl status umami
# Logs
journalctl -u umami -f
# Resource usage
podman stats
When to Use¶
- 5-20 services
- Want simplicity over features
- Comfortable with Linux/systemd
- Easy client handoffs important
- Don't need auto-scaling yet