From b0ae0efa0586a23dc76e076e55ab1966fc87b752 Mon Sep 17 00:00:00 2001 From: Serreau Jovann Date: Wed, 28 Jan 2026 12:50:15 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(ansible):=20D=C3=A9ploie=20l'a?= =?UTF-8?q?pplication=20avec=20PHP=208.3,=20Symfony,=20PostgreSQL=20et=20c?= =?UTF-8?q?onfigurations=20am=C3=A9lior=C3=A9es.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ansible/playbook.yml | 318 ++++++++++++++++++++++++++++--------------- 1 file changed, 209 insertions(+), 109 deletions(-) diff --git a/ansible/playbook.yml b/ansible/playbook.yml index cd2583f..ace6da1 100644 --- a/ansible/playbook.yml +++ b/ansible/playbook.yml @@ -1,26 +1,49 @@ -# Fichier: deploy_ludikevent_php84.yml -- name: Deploy LudikEvent Application +# Fichier: install_php_83_symfony_pgsql.yml + +- name: Deploy application hosts: webservers become: true gather_facts: true vars: - path: "/var/www/mainframe/app" # Assure-toi que ce chemin est correct - php_bin: "/usr/bin/php8.4" - php_fpm_service: "php8.4-fpm" db_name: "ludikevent" db_user: "ludikevent" db_password: "ludikevent" redis_password: "ludikevent" redis_port: "20110" + # Assurez-vous que 'path' est définie dans votre inventaire ou comme extra-var + # Exemple: path: /var/www/mainframe/app tasks: - - name: Installation des dépôts et dépendances système + - name: Exécuter 'composer install' dans le répertoire de l'application + ansible.builtin.command: composer install --no-dev --optimize-autoloader + become: false # Run as the connection user (e.g., 'bot') + args: + chdir: "{{ path }}" + when: ansible_os_family == "Debian" + - name: Send a message to the Discord channel + community.general.discord: + webhook_id: "1419573620602044518" + webhook_token: "ikAdxWxsrrTqMTb5Gh_8ylcoJHlOnq7aJZvR5udoS_fCK56Jk3qpEnJHVKdD8fwuNJF3" + content: "Mise à jour du intranet ludikevent https://intranet.ludikevent.fr" + + - name: Installer le support ACL pour corriger les permissions de 'become_user' + ansible.builtin.apt: + name: acl + state: present + update_cache: true + when: ansible_os_family == "Debian" + + - name: Installation des dépendances pour le module Ansible PostgreSQL + ansible.builtin.apt: + name: python3-psycopg2 + state: present + update_cache: true + when: ansible_os_family == "Debian" + + - name: Installation de PHP 8.3 et PHP 8.3-FPM avec les dépendances ansible.builtin.apt: name: - - acl - - python3-psycopg2 - - ffmpeg - php8.4 - php8.4-fpm - php8.4-cli @@ -33,26 +56,23 @@ - php8.4-intl - php8.4-gd - php8.4-curl + - php8.4-pdo - php8.4-opcache - php8.4-bcmath - php8.4-redis - php8.4-imagick + - ffmpeg state: present - update_cache: true when: ansible_os_family == "Debian" - - name: Forcer PHP 8.4 par défaut via update-alternatives - ansible.builtin.shell: | - update-alternatives --set php {{ php_bin }} - changed_when: true - - - name: Démarrage et activation de PHP-FPM + - name: Démarrage et activation du service PHP 8.3 FPM ansible.builtin.systemd: - name: "{{ php_fpm_service }}" + name: php8.4-fpm state: started enabled: yes + when: ansible_os_family == "Debian" - - name: Créer le fichier .env.local de production + - name: Créer le fichier .env.local avec les secrets de production ansible.builtin.copy: content: | APP_ENV=prod @@ -73,104 +93,48 @@ DEFAULT_URI=https://reservation.ludikevent.fr INTRANET_LOCK=false dest: "{{ path }}/.env.local" - owner: bot - group: www-data - mode: '0640' + when: ansible_os_family == "Debian" - - name: Configuration des répertoires essentiels (Permissions) + # --- Initial creation of essential directories with correct ownership --- + # These directories should exist before composer runs, but composer might create subdirs. + - name: Ensure app/var and public/media directories exist with correct owner/group + ansible.builtin.file: + path: "{{ item }}" + owner: bot # Assuming 'bot' is your deployment user + group: www-data + mode: '0775' # Allow 'bot' and 'www-data' to read/write/execute + state: directory + recurse: yes # Important to ensure subdirectories created by previous deploys also get permissions + loop: + - "{{ path }}/var" + - "{{ path }}/var/log" # Specific for log, though var/log might be created by composer later + - "{{ path }}/public/media" # For uploads + - "{{ path }}/public/images" # For uploads + - "{{ path }}/public/pdf" # For uploads + - "{{ path }}/public/seo" # For uploads + - "{{ path }}/public/tmp-sign" # For upload + - "{{ path }}/sauvegarde" + + # --- POST-COMPOSER PERMISSION FIXES --- + # This is crucial because composer creates var/cache as the `become: false` user + - name: Set correct permissions for Symfony cache and logs directories ansible.builtin.file: path: "{{ item }}" owner: bot group: www-data - mode: '0775' + mode: '0775' # rwx for owner and group, rx for others state: directory - recurse: yes + recurse: yes # Apply to all contents loop: - - "{{ path }}/var" - - "{{ path }}/public/media" - - "{{ path }}/public/images" - - "{{ path }}/public/pdf" - - "{{ path }}/public/seo" - - "{{ path }}/public/tmp-sign" - - "{{ path }}/sauvegarde" + - "{{ path }}/var/cache" + - "{{ path }}/var/log" + # For web-writable directories created by the app itself (e.g., uploads), you might set ACLs + # or chown to www-data and then your user gets access via group membership. - - name: Exécuter 'composer install' - ansible.builtin.command: composer install --no-dev --optimize-autoloader - become: false - args: - chdir: "{{ path }}" - - - name: Exécuter 'bun install' et 'build' - ansible.builtin.command: "{{ item }}" - become: false - args: - chdir: "{{ path }}" - loop: - - "bun install" - - "bun run build" - - - name: Exécuter les commandes Symfony bin/console (via PHP 8.4) - ansible.builtin.command: "{{ php_bin }} bin/console {{ item }} --no-interaction" - become: false - args: - chdir: "{{ path }}" - loop: - - "doctrine:migrations:migrate" - - "cache:clear" - - "liip:imagine:cache:remove" - - "app:sitemap" - - - name: Exécuter pwa:compile (sans limite mémoire) - ansible.builtin.command: "{{ php_bin }} -d memory_limit=-1 bin/console pwa:compile" - become: false - args: - chdir: "{{ path }}" - - - name: Mise à jour du journal Git (ignore errors) - ansible.builtin.command: "{{ php_bin }} bin/console app:git-log-update" - become: false - args: - chdir: "{{ path }}" - ignore_errors: yes - - - name: Purger Redis - ansible.builtin.command: "redis-cli -p {{ redis_port }} -a {{ redis_password }} FLUSHALL" - - - name: Gestion de Supervisor et Caddy - ansible.builtin.template: - src: "{{ item.src }}" - dest: "{{ item.dest }}" - mode: '0644' - loop: - - { src: 'supervisor.j2', dest: '/etc/supervisor/conf.d/mainframe.conf' } - - { src: 'caddy.j2', dest: '/etc/caddy/sites/ludikevent.conf' } - - - name: Rechargement des services - ansible.builtin.shell: | - supervisorctl reread && supervisorctl update - systemctl reload caddy - changed_when: true - - - name: Notification Discord - community.general.discord: - webhook_id: "1419573620602044518" - webhook_token: "ikAdxWxsrrTqMTb5Gh_8ylcoJHlOnq7aJZvR5udoS_fCK56Jk3qpEnJHVKdD8fwuNJF3" - content: "✅ **Déploiement réussi** sur PHP 8.4 - LudikEvent Intranet" - - - name: Configuration des tâches CRON (via PHP 8.4) - ansible.builtin.cron: - name: "{{ item.name }}" - minute: "{{ item.minute }}" - hour: "{{ item.hour | default('*') }}" - job: "{{ php_bin }} {{ path }}/bin/console {{ item.cmd }}" - user: root - loop: - - { name: "LDK - Search", minute: "*/5", cmd: "app:search" } - - { name: "LDK - Stripe", minute: "0", hour: "1", cmd: "app:stripe:sync" } - - { name: "LDK - Backup", minute: "0", hour: "*/6", cmd: "app:backup" } - - { name: "LDK - Clean", minute: "0", hour: "20", cmd: "app:clean" } - - - name: Permissions finales (Cache & Logs) - Set ACLs + # Alternative for cache/log permissions using ACLs (more robust for mixed ownership) + # This requires 'acl' package installed (which you already do). + # Use this if 'bot' needs to own, but www-data needs to write. + - name: Set ACLs for Symfony cache and logs (recommended for web-writable dirs) ansible.builtin.acl: path: "{{ item }}" entity: www-data @@ -178,7 +142,143 @@ permissions: rwx state: present recursive: yes - default: yes + default: yes # Apply default ACLs for new files/dirs within loop: - "{{ path }}/var/cache" - "{{ path }}/var/log" + when: ansible_os_family == "Debian" # ACLs are Linux-specific + + - name: Exécuter bun install dans le répertoire de l application + ansible.builtin.command: bun install + become: false + args: + chdir: "{{ path }}" + when: ansible_os_family == "Debian" + + - name: Exécuter bun build dans le répertoire de l application + ansible.builtin.command: bun run build + become: false + args: + chdir: "{{ path }}" + when: ansible_os_family == "Debian" + + - name: Supervisor config + ansible.builtin.template: + src: supervisor.j2 + dest: "/etc/supervisor/conf.d/mainframe.conf" + mode: '0644' + + - name: Reread Supervisor configuration + ansible.builtin.command: supervisorctl reread + changed_when: true # Always mark as changed, as output is not always useful for idempotency + + - name: Update Supervisor (add/remove updated programs) + ansible.builtin.command: supervisorctl update + changed_when: true + + - name: Purger la base de données Redis + ansible.builtin.command: "redis-cli -p {{ redis_port }} -a {{ redis_password }} FLUSHALL" + when: ansible_os_family == "Debian" + + - name: Generate Caddy site configuration + ansible.builtin.template: + src: caddy.j2 + dest: "/etc/caddy/sites/ludikevent.conf" + mode: '0644' + + - name: Reload Caddy to apply new configuration + ansible.builtin.systemd: + name: caddy + state: reloaded + enabled: yes + - name: Exécuter doctrine:migration:migrate dans le répertoire de l application + ansible.builtin.command: php bin/console doctrine:migrations:migrate --no-interaction + become: false + args: + chdir: "{{ path }}" + when: ansible_os_family == "Debian" + - name: Exécuter cache:clear dans le répertoire de l application + ansible.builtin.command: php bin/console cache:clear + become: false + args: + chdir: "{{ path }}" + when: ansible_os_family == "Debian" + - name: Exécuter app:git-log-update pour mettre à jour le journal client + ansible.builtin.command: php bin/console app:git-log-update + become: false + args: + chdir: "{{ path }}" + # On ignore les erreurs pour ne pas bloquer le déploiement si l'IA ou Git échoue + ignore_errors: yes + + - name: S'assurer que le fichier update.json a les bonnes permissions + ansible.builtin.file: + path: "{{ path }}/var/update.json" + owner: bot + group: www-data + mode: '0664' + state: file + ignore_errors: yes + - name: Exécuter liip:imagine:cache:remove dans le répertoire de l application + ansible.builtin.command: php bin/console liip:imagine:cache:remove + become: false + args: + chdir: "{{ path }}" + when: ansible_os_family == "Debian" # Added a when condition here, often missed + - name: Exécuter pwa:compile dans le répertoire de l application + ansible.builtin.command: php -d memory_limit=-1 bin/console pwa:compile + become: false + args: + chdir: "{{ path }}" + - name: Exécuter pwa:compile dans le répertoire de l application + ansible.builtin.command: php bin/console app:sitemap + become: false + args: + chdir: "{{ path }}" + - name: "Cron Task Search" + ansible.builtin.cron: + name: "Intranet Ludikevent - Search" + minute: "*/5" + job: "php {{ path }}/bin/console app:search" + user: root + - name: "Cron Task Search" + ansible.builtin.cron: + name: "Intranet Ludikevent - Stripe" + minute: "0" + hour: "1" + job: "php {{ path }}/bin/console app:stripe:sync" + user: root + - name: "Cron Task Search" + ansible.builtin.cron: + name: "Intranet Ludikevent - Backup" + minute: "0" + hour: "*/6" + job: "php {{ path }}/bin/console app:backup" + user: "root" + state: present + - name: "Cron Task - Clean Data (Performance & Tracking)" + ansible.builtin.cron: + name: "Intranet Ludikevent - Clean Data" + minute: "0" + hour: "20" + job: "php {{ path }}/bin/console app:clean" + user: "root" + state: present + - name: Set correct permissions for Symfony cache and logs directories + ansible.builtin.file: + path: "{{ item }}" + owner: bot + group: www-data + mode: '0777' # rwx for owner and group, rx for others + state: directory + recurse: yes # Apply to all contents + loop: + - "{{ path }}/var/cache" + - "{{ path }}/var/log" + - "{{ path }}/public/media" + - "{{ path }}/sauvegarde" + - "{{ path }}/public/images" # For uploads + - "{{ path }}/public/pdf" + - "{{ path }}/public/seo" + - "{{ path }}/public/tmp-sign" # For uploads +