umami analytics play & role

This commit is contained in:
2026-08-05 20:53:08 +02:00
parent c89e8c565a
commit 094d02ff7f
9 changed files with 266 additions and 0 deletions
+37
View File
@@ -0,0 +1,37 @@
---
# ---------------------------------------------------------------------------
# Global variables for the docker + umami deployment
# ---------------------------------------------------------------------------
custom_firewall_ports:
- 3000
description: Umami web analytics
# --- Docker role ---
docker_users_to_add:
- "{{ ansible_user }}" # add the SSH user to the docker group
# --- Umami role ---
umami_base_dir: /opt/umami
umami_image: "ghcr.io/umami-software/umami:latest"
umami_container_name: umami
umami_port: 3000 # host port Umami will be exposed on
# Address the umami_port is bound to on the host.
# - "127.0.0.1" if your reverse proxy runs on this same host (loopback only)
# - "0.0.0.0" if your reverse proxy is elsewhere (another host/container) and
# needs to reach this port over the network
umami_bind_address: "0.0.0.0"
# Postgres settings (used by the umami-db container)
umami_db_container_name: umami-db
umami_db_image: "postgres:15-alpine"
umami_db_name: umami
umami_db_user: umami
# IMPORTANT: override this in inventory/vars, --extra-vars, or (better) Ansible Vault.
# Do not leave the default password in production.
umami_db_password: "fc7tBTxsuAulmYmSl8AE0q13eq3f94f7u3u6"
# A random string used by Umami to encrypt/salt data. Generate your own, e.g.:
# openssl rand -hex 32
# Override this in production via --extra-vars or vault.
umami_app_secret: "dichotomizing-triads-cosmochemistry-amidols"
+10
View File
@@ -0,0 +1,10 @@
---
- name: Install umami using Docker
hosts: all
vars:
umami_version: "9.4.4"
roles:
- role: roles/firewall
- role: roles/docker
- role: roles/env
- role: roles/umami
+7
View File
@@ -0,0 +1,7 @@
---
umami_python_docker_sdk_packages:
- python3-pip
- python3-docker
umami_restart_policy: unless-stopped
umami_docker_network: umami_net
+11
View File
@@ -0,0 +1,11 @@
---
docker_apt_arch: "{{ 'amd64' if ansible_architecture == 'x86_64' else 'arm64' }}"
docker_packages:
- docker-ce
- docker-ce-cli
- containerd.io
- docker-buildx-plugin
- docker-compose-plugin
docker_service_state: started
docker_service_enabled: true
+6
View File
@@ -0,0 +1,6 @@
---
- name: restart docker
ansible.builtin.systemd:
name: docker
state: restarted
daemon_reload: true
+98
View File
@@ -0,0 +1,98 @@
---
- name: Ensure required system packages are present
ansible.builtin.apt:
name:
- ca-certificates
- curl
- gnupg
- lsb-release
state: present
update_cache: true
cache_valid_time: 3600
- name: Ensure /etc/apt/keyrings directory exists
ansible.builtin.file:
path: /etc/apt/keyrings
state: directory
mode: "0755"
- name: Check if Docker GPG key already present
ansible.builtin.stat:
path: /etc/apt/keyrings/docker.asc
register: docker_gpg_key
- name: Download Docker's official GPG key
ansible.builtin.get_url:
url: https://download.docker.com/linux/ubuntu/gpg
dest: /etc/apt/keyrings/docker.asc
mode: "0644"
when: not docker_gpg_key.stat.exists
- name: Add Docker apt repository (deb822 format)
ansible.builtin.deb822_repository:
name: docker
types: [deb]
uris: "https://download.docker.com/linux/ubuntu"
suites: "{{ ansible_distribution_release }}"
components: [stable]
architectures: "{{ docker_apt_arch }}"
signed_by: /etc/apt/keyrings/docker.asc
state: present
register: docker_repo_added
- name: Update apt cache after adding Docker repo
ansible.builtin.apt:
update_cache: true
when: docker_repo_added.changed
- name: Install Docker Engine and plugins
ansible.builtin.apt:
name: "{{ docker_packages }}"
state: present
notify: restart docker
- name: Ensure docker service is started and enabled
ansible.builtin.systemd:
name: docker
state: "{{ docker_service_state }}"
enabled: "{{ docker_service_enabled }}"
- name: Ensure docker group exists
ansible.builtin.group:
name: docker
state: present
- name: Add user(s) to the docker group
ansible.builtin.user:
name: "{{ item }}"
groups: docker
append: true
loop: "{{ docker_users_to_add }}"
register: docker_group_added
- name: Notify about needing to re-login for group changes
ansible.builtin.debug:
msg: >-
User '{{ item.item }}' was added to the docker group. They will need to
log out and back in (or start a new SSH session) for this to take effect
without using sudo for docker commands.
loop: "{{ docker_group_added.results }}"
when: item.changed
- name: Verify Docker is installed and working
ansible.builtin.command: docker --version
register: docker_version_output
changed_when: false
- name: Show installed Docker version
ansible.builtin.debug:
msg: "{{ docker_version_output.stdout }}"
- name: Verify Docker Compose plugin is installed
ansible.builtin.command: docker compose version
register: docker_compose_version_output
changed_when: false
- name: Show installed Docker Compose version
ansible.builtin.debug:
msg: "{{ docker_compose_version_output.stdout }}"
+7
View File
@@ -0,0 +1,7 @@
---
- name: recreate umami stack
community.docker.docker_compose_v2:
project_src: "{{ umami_base_dir }}"
state: present
recreate: always
listen: recreate umami stack
+50
View File
@@ -0,0 +1,50 @@
---
- name: Ensure pip and Docker SDK for Python are installed (needed by community.docker modules)
ansible.builtin.apt:
name: "{{ umami_python_docker_sdk_packages }}"
state: present
update_cache: true
cache_valid_time: 3600
- name: Ensure Umami base directory exists
ansible.builtin.file:
path: "{{ umami_base_dir }}"
state: directory
mode: "0750"
owner: root
group: root
- name: Deploy docker-compose.yml for Umami stack
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ umami_base_dir }}/docker-compose.yml"
mode: "0640"
owner: root
group: root
notify: recreate umami stack
- name: Flush handlers so compose file changes apply before we verify status
ansible.builtin.meta: flush_handlers
- name: Start (or ensure running) the Umami + Postgres stack
community.docker.docker_compose_v2:
project_src: "{{ umami_base_dir }}"
state: present
register: umami_compose_result
- name: Show compose deployment result
ansible.builtin.debug:
var: umami_compose_result.changed
- name: Wait for Umami HTTP endpoint to become available
ansible.builtin.uri:
url: "http://127.0.0.1:{{ umami_port }}/api/heartbeat"
status_code: 200
register: umami_health
until: umami_health.status == 200
retries: 5
delay: 10
- name: Umami health check result
ansible.builtin.debug:
msg: "Umami is up and responding on port {{ umami_port }}."
@@ -0,0 +1,40 @@
{{ ansible_managed | comment }}
# Based on: https://github.com/umami-software/umami/blob/master/docker-compose.yml
services:
umami:
image: "{{ umami_image }}"
container_name: "{{ umami_container_name }}"
ports:
- "{{ umami_bind_address }}:{{ umami_port }}:3000"
environment:
DATABASE_URL: "postgresql://{{ umami_db_user }}:{{ umami_db_password }}@db:5432/{{ umami_db_name }}"
APP_SECRET: "{{ umami_app_secret }}"
depends_on:
db:
condition: service_healthy
init: true
restart: always
healthcheck:
test: ["CMD-SHELL", "curl http://localhost:3000/api/heartbeat"]
interval: 5s
timeout: 5s
retries: 5
db:
image: "{{ umami_db_image }}"
container_name: "{{ umami_db_container_name }}"
environment:
POSTGRES_DB: "{{ umami_db_name }}"
POSTGRES_USER: "{{ umami_db_user }}"
POSTGRES_PASSWORD: "{{ umami_db_password }}"
volumes:
- umami-db-data:/var/lib/postgresql/data
restart: always
healthcheck:
test: ["CMD-SHELL", "pg_isready -U $${POSTGRES_USER} -d $${POSTGRES_DB}"]
interval: 5s
timeout: 5s
retries: 5
volumes:
umami-db-data: