From 616d4d10a738c9345683a98fc337eb727728ed43 Mon Sep 17 00:00:00 2001 From: Thomas MALGOUYRES Date: Mon, 20 Jul 2026 14:39:30 +0000 Subject: [PATCH] add tracearr --- playbooks/deploy-tracearr.yml | 106 ++++++++++++++++++++++ playbooks/install-docker.yml | 97 ++++++++++++++++++++ services/tracearr/docker-compose.yml | 128 +++++++++++++++++++++++++++ 3 files changed, 331 insertions(+) create mode 100644 playbooks/deploy-tracearr.yml create mode 100644 playbooks/install-docker.yml create mode 100644 services/tracearr/docker-compose.yml diff --git a/playbooks/deploy-tracearr.yml b/playbooks/deploy-tracearr.yml new file mode 100644 index 0000000..33ade9f --- /dev/null +++ b/playbooks/deploy-tracearr.yml @@ -0,0 +1,106 @@ +--- +# Playbook: deploy-tracearr.yml +# +# But: +# - Copier le docker-compose.yml Tracearr sur le LXC +# - Generer les secrets si absents +# - Demarrer la stack Tracearr +# - Verifier que le port 3000 repond +# +# Les secrets sont crees directement sur le LXC. +# Ils ne sont pas stockes dans Git. + +- name: Deploy Tracearr stack + hosts: tracearr_servers + become: true + gather_facts: false + + vars: + stack_name: tracearr + stack_path: /opt/stacks/tracearr + + tasks: + - name: Create stack directory + file: + path: "{{ stack_path }}" + state: directory + owner: root + group: root + mode: "0750" + + - name: Create secrets directory + file: + path: "{{ stack_path }}/secrets" + state: directory + owner: root + group: root + mode: "0700" + + - name: Copy Docker Compose file + copy: + src: "{{ playbook_dir }}/../services/tracearr/docker-compose.yml" + dest: "{{ stack_path }}/docker-compose.yml" + owner: root + group: root + mode: "0644" + + - name: Generate Tracearr secrets if missing + shell: | + set -e + umask 077 + + if [ ! -s "{{ stack_path }}/secrets/db_password" ]; then + openssl rand -hex 32 > "{{ stack_path }}/secrets/db_password" + fi + + if [ ! -s "{{ stack_path }}/secrets/jwt_secret" ]; then + openssl rand -hex 32 > "{{ stack_path }}/secrets/jwt_secret" + fi + + if [ ! -s "{{ stack_path }}/secrets/cookie_secret" ]; then + openssl rand -hex 32 > "{{ stack_path }}/secrets/cookie_secret" + fi + + if [ ! -s "{{ stack_path }}/secrets/better_auth_secret" ]; then + openssl rand -hex 32 > "{{ stack_path }}/secrets/better_auth_secret" + fi + + if [ ! -s "{{ stack_path }}/secrets/database_url" ]; then + DB_PASSWORD="$(cat "{{ stack_path }}/secrets/db_password")" + printf "postgres://tracearr:%s@timescale:5432/tracearr" "$DB_PASSWORD" > "{{ stack_path }}/secrets/database_url" + fi + + chown -R root:root "{{ stack_path }}/secrets" + chmod 700 "{{ stack_path }}/secrets" + chmod 644 "{{ stack_path }}/secrets/"* + args: + executable: /bin/bash + no_log: true + changed_when: true + + - name: Pull Tracearr stack images + command: docker compose pull + args: + chdir: "{{ stack_path }}" + + - name: Start Tracearr stack + command: docker compose up -d + args: + chdir: "{{ stack_path }}" + + - name: Wait for Tracearr port + wait_for: + host: 127.0.0.1 + port: 3000 + timeout: 180 + + - name: Show Tracearr containers + command: docker compose ps + args: + chdir: "{{ stack_path }}" + register: compose_ps + changed_when: false + + - name: Show compose status + debug: + var: compose_ps.stdout_lines diff --git a/playbooks/install-docker.yml b/playbooks/install-docker.yml new file mode 100644 index 0000000..687b309 --- /dev/null +++ b/playbooks/install-docker.yml @@ -0,0 +1,97 @@ +--- +# Playbook: install-docker.yml +# +# But: +# - Installer Docker Engine dans un LXC Debian +# - Installer le plugin Docker Compose +# - Activer le service Docker +# - Ajouter l utilisateur ansible au groupe docker + +- name: Installer Docker Engine + hosts: "{{ target_group | default('docker_hosts') }}" + become: true + gather_facts: true + + tasks: + - name: Supprimer les paquets Docker conflictuels + apt: + name: + - docker.io + - docker-compose + - docker-doc + - podman-docker + state: absent + failed_when: false + + - name: Installer les paquets requis + apt: + name: + - ca-certificates + - curl + - gnupg + state: present + update_cache: true + + - name: Creer le dossier apt keyrings + file: + path: /etc/apt/keyrings + state: directory + mode: "0755" + + - name: Telecharger la cle GPG Docker + get_url: + url: https://download.docker.com/linux/debian/gpg + dest: /etc/apt/keyrings/docker.asc + mode: "0644" + + - name: Ajouter le depot apt Docker + copy: + dest: /etc/apt/sources.list.d/docker.sources + mode: "0644" + content: | + Types: deb + URIs: https://download.docker.com/linux/debian + Suites: {{ ansible_distribution_release }} + Components: stable + Signed-By: /etc/apt/keyrings/docker.asc + + - name: Installer les paquets Docker + apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + state: present + update_cache: true + + - name: Activer et demarrer Docker + service: + name: docker + enabled: true + state: started + + - name: Ajouter ansible au groupe docker + user: + name: ansible + groups: docker + append: true + + - name: Verifier la version Docker + command: docker --version + register: docker_version + changed_when: false + + - name: Afficher la version Docker + debug: + var: docker_version.stdout + + - name: Verifier la version Docker Compose + command: docker compose version + register: compose_version + changed_when: false + + - name: Afficher la version Docker Compose + debug: + var: compose_version.stdout diff --git a/services/tracearr/docker-compose.yml b/services/tracearr/docker-compose.yml new file mode 100644 index 0000000..0f8f7ad --- /dev/null +++ b/services/tracearr/docker-compose.yml @@ -0,0 +1,128 @@ +--- +# Stack: tracearr +# +# But: +# - Deployer Tracearr avec TimescaleDB et Redis +# - Eviter les mots de passe en clair dans Git +# - Stocker les secrets dans /opt/stacks/tracearr/secrets +# +# Notes: +# - Le fichier .env de production n est pas utilise +# - Les secrets sont lus depuis des fichiers Docker secrets + +services: + tracearr: + image: ghcr.io/connorgallopo/tracearr:latest + container_name: tracearr + restart: unless-stopped + + depends_on: + timescale: + condition: service_healthy + redis: + condition: service_healthy + + ports: + - "3000:3000" + + environment: + NODE_ENV: production + PORT: "3000" + HOST: 0.0.0.0 + TZ: Europe/Paris + DATABASE_URL_FILE: /run/secrets/database_url + REDIS_URL: redis://redis:6379 + JWT_SECRET_FILE: /run/secrets/jwt_secret + COOKIE_SECRET_FILE: /run/secrets/cookie_secret + BETTER_AUTH_SECRET_FILE: /run/secrets/better_auth_secret + CORS_ORIGIN: https://tracearr.thomasmlg.fr + LOG_LEVEL: info + + secrets: + - database_url + - jwt_secret + - cookie_secret + - better_auth_secret + + volumes: + - tracearr_backups:/data/backup + + networks: + - tracearr_network + + timescale: + image: timescale/timescaledb-ha:pg18.1-ts2.25.0 + container_name: tracearr-db + restart: unless-stopped + shm_size: 512mb + + ulimits: + nofile: + soft: 65536 + hard: 65536 + + command: > + postgres + -c timescaledb.license=timescale + -c timescaledb.max_tuples_decompressed_per_dml_transaction=0 + -c max_locks_per_transaction=4096 + -c timescaledb.telemetry_level=off + + environment: + POSTGRES_USER: tracearr + POSTGRES_PASSWORD_FILE: /run/secrets/db_password + POSTGRES_DB: tracearr + + secrets: + - db_password + + volumes: + - timescale_data:/home/postgres/pgdata/data + + healthcheck: + test: ["CMD-SHELL", "pg_isready -U tracearr"] + interval: 10s + timeout: 5s + retries: 5 + + networks: + - tracearr_network + + redis: + image: redis:8-alpine + container_name: tracearr-redis + restart: unless-stopped + command: redis-server --appendonly yes + + volumes: + - redis_data:/data + + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + + networks: + - tracearr_network + +secrets: + db_password: + file: ./secrets/db_password + database_url: + file: ./secrets/database_url + jwt_secret: + file: ./secrets/jwt_secret + cookie_secret: + file: ./secrets/cookie_secret + better_auth_secret: + file: ./secrets/better_auth_secret + +networks: + tracearr_network: + driver: bridge + +volumes: + tracearr_backups: + timescale_data: + redis_data: