ajoute le portail Laravel : connexion prof/élève, session unique, gestion de classe, salle d'attente

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Adam Belkacemi 2026-10-08 02:01:58 +02:00
parent aa31b6112f
commit 30e14b1c54
191 changed files with 25324 additions and 0 deletions

View file

@ -0,0 +1,91 @@
---
- name: installer les prérequis pour le dépôt PHP Sury
ansible.builtin.apt:
name: [lsb-release, ca-certificates, curl, gnupg, rsync]
state: present
update_cache: true
cache_valid_time: 3600
- name: télécharger le trousseau de clés du dépôt Sury
ansible.builtin.get_url:
url: https://packages.sury.org/debsuryorg-archive-keyring.deb
dest: /tmp/debsuryorg-archive-keyring.deb
mode: "0644"
- name: installer le trousseau de clés Sury
ansible.builtin.apt:
deb: /tmp/debsuryorg-archive-keyring.deb
state: present
- name: ajouter le dépôt PHP Sury
ansible.builtin.apt_repository:
repo: "deb [signed-by=/usr/share/keyrings/debsuryorg-archive-keyring.gpg] https://packages.sury.org/php/ {{ ansible_distribution_release }} main"
filename: php
state: present
update_cache: true
- name: installer PHP {{ portail_php_version }}, Nginx et les extensions nécessaires
ansible.builtin.apt:
name:
- "php{{ portail_php_version }}-fpm"
- "php{{ portail_php_version }}-cli"
- "php{{ portail_php_version }}-mysql"
- "php{{ portail_php_version }}-redis"
- "php{{ portail_php_version }}-mbstring"
- "php{{ portail_php_version }}-xml"
- "php{{ portail_php_version }}-curl"
- "php{{ portail_php_version }}-zip"
- "php{{ portail_php_version }}-bcmath"
- "php{{ portail_php_version }}-gd"
- "php{{ portail_php_version }}-intl"
- "php{{ portail_php_version }}-opcache"
- nginx
state: present
update_cache: true
- name: installer Composer (avec vérification de la somme d'installation officielle)
block:
- name: télécharger le programme d'installation de Composer
ansible.builtin.get_url:
url: https://getcomposer.org/installer
dest: /tmp/composer-setup.php
mode: "0644"
- name: récupérer la somme SHA384 officielle
ansible.builtin.uri:
url: https://composer.github.io/installer.sig
return_content: true
register: portail_composer_signature
when: not (ansible_check_mode | default(false))
- name: calculer la somme SHA384 du fichier téléchargé
ansible.builtin.stat:
path: /tmp/composer-setup.php
checksum_algorithm: sha384
register: portail_composer_setup_stat
- name: vérifier que la somme correspond (sinon, installateur corrompu)
ansible.builtin.fail:
msg: "La somme de l'installateur Composer ne correspond pas à la signature officielle : installation interrompue."
when:
- portail_composer_signature is defined
- portail_composer_setup_stat.stat.checksum != portail_composer_signature.content.strip()
- name: installer Composer (dernière version stable)
ansible.builtin.command:
cmd: php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
args:
creates: /usr/local/bin/composer
- name: installer Node.js 22 LTS (dépôt NodeSource)
block:
- name: ajouter le dépôt NodeSource
ansible.builtin.shell:
cmd: curl -fsSL https://deb.nodesource.com/setup_22.x | bash -
creates: /etc/apt/sources.list.d/nodesource.list
- name: installer nodejs
ansible.builtin.apt:
name: nodejs
state: present
update_cache: true

View file

@ -0,0 +1,63 @@
---
- name: créer le dossier de configuration Docker du portail
ansible.builtin.file:
path: "{{ portail_dossier_docker }}"
state: directory
owner: root
group: root
mode: "0750"
# Un seul fichier de secrets, nommé .env : docker compose le charge
# automatiquement pour les substitutions ${...} de docker-compose.yml, et une
# tâche plus loin le relit pour remplir le .env de Laravel avec les mêmes
# valeurs (une seule source de vérité, jamais dans Git).
- name: générer les secrets MariaDB/Redis de l'app (première fois seulement)
ansible.builtin.copy:
dest: "{{ portail_dossier_docker }}/.env"
content: |
MYSQL_ROOT_PASSWORD={{ lookup('community.general.random_string', length=32, special=false) }}
MYSQL_PASSWORD={{ lookup('community.general.random_string', length=32, special=false) }}
REDIS_PASSWORD={{ lookup('community.general.random_string', length=32, special=false) }}
owner: root
group: root
mode: "0600"
force: false
register: portail_secrets_generes
- name: lire les secrets générés
ansible.builtin.slurp:
src: "{{ portail_dossier_docker }}/.env"
register: portail_secrets_brut
- name: "exposer les secrets comme variables (jamais affichées, no_log)"
ansible.builtin.set_fact:
portail_secrets: "{{ dict(portail_secrets_lignes | map('split', '=', 1)) }}"
vars:
portail_secrets_lignes: "{{ (portail_secrets_brut.content | b64decode).splitlines() | select('string') | list }}"
no_log: true
- name: déployer docker-compose.yml (MariaDB + Redis de l'app)
ansible.builtin.template:
src: docker-compose.yml.j2
dest: "{{ portail_dossier_docker }}/docker-compose.yml"
owner: root
group: root
mode: "0640"
vars:
portail_mysql_root_password: "${MYSQL_ROOT_PASSWORD}"
portail_mysql_password: "${MYSQL_PASSWORD}"
portail_redis_password: "${REDIS_PASSWORD}"
register: portail_compose_deploye
- name: démarrer MariaDB et Redis (app)
community.docker.docker_compose_v2:
project_src: "{{ portail_dossier_docker }}"
state: present
register: portail_compose_resultat
- name: attendre que MariaDB (app) accepte les connexions
ansible.builtin.wait_for:
host: 127.0.0.1
port: "{{ portail_mysql_port }}"
delay: 2
timeout: 60

View file

@ -0,0 +1,113 @@
---
- name: créer le dossier de l'application
ansible.builtin.file:
path: "{{ portail_dossier_app }}"
state: directory
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: "0755"
# storage/ et bootstrap/cache/ sont de l'état et du cache runtime, jamais du
# code : on ne les synchronise jamais depuis le Mac (un rsync --delete les
# effacerait sinon, y compris storage/app/ où atterriront plus tard les
# travaux d'élèves). On crée leur structure une fois, puis on laisse
# www-data (PHP-FPM) les posséder en continu.
- name: créer la structure storage/ et bootstrap/cache/ (une seule fois)
ansible.builtin.file:
path: "{{ portail_dossier_app }}/{{ item }}"
state: directory
owner: www-data
group: www-data
mode: "0775"
loop:
- storage/app/public
- storage/framework/cache/data
- storage/framework/sessions
- storage/framework/views
- storage/logs
- bootstrap/cache
- name: synchroniser le code du portail (sans vendor/node_modules/.env/storage)
become: false
ansible.posix.synchronize:
src: "{{ playbook_dir }}/../portail/"
dest: "{{ portail_dossier_app }}/"
delete: true
rsync_opts:
- "--exclude=/vendor"
- "--exclude=/node_modules"
- "--exclude=/.env"
- "--exclude=/database/database.sqlite"
- "--exclude=/storage"
- "--exclude=/bootstrap/cache"
- "--exclude=/public/build"
- "--exclude=/public/hot"
- "--exclude=/.git"
register: portail_code_synchronise
- name: installer les dépendances PHP (composer)
ansible.builtin.command:
cmd: composer install --no-dev --optimize-autoloader --no-interaction
args:
chdir: "{{ portail_dossier_app }}"
environment:
COMPOSER_ALLOW_SUPERUSER: "1"
register: portail_composer_install_app
changed_when: "'Nothing to install' not in portail_composer_install_app.stdout"
- name: vérifier si .env existe déjà
ansible.builtin.stat:
path: "{{ portail_dossier_app }}/.env"
register: portail_env_stat
- name: générer une clé d'application (une seule fois)
ansible.builtin.command:
cmd: php artisan key:generate --show
args:
chdir: "{{ portail_dossier_app }}"
register: portail_app_key_generee
when: not portail_env_stat.stat.exists
changed_when: true
- name: déployer .env de production (une seule fois, jamais réécrit ensuite)
ansible.builtin.template:
src: env.production.j2
dest: "{{ portail_dossier_app }}/.env"
owner: "{{ ansible_user }}"
group: www-data
mode: "0640"
vars:
portail_app_key: "{{ portail_app_key_generee.stdout }}"
portail_app_url: "http://{{ ansible_host }}"
when: not portail_env_stat.stat.exists
- name: installer les dépendances JS (npm)
ansible.builtin.command:
cmd: npm ci
args:
chdir: "{{ portail_dossier_app }}"
register: portail_npm_ci
changed_when: true
- name: compiler les assets (vite build)
ansible.builtin.command:
cmd: npm run build
args:
chdir: "{{ portail_dossier_app }}"
register: portail_npm_build
changed_when: true
- name: appliquer les migrations
ansible.builtin.command:
cmd: php artisan migrate --force
args:
chdir: "{{ portail_dossier_app }}"
register: portail_migrate
changed_when: "'Nothing to migrate' not in portail_migrate.stdout"
- name: mettre en cache la configuration et les routes
ansible.builtin.shell:
cmd: php artisan config:cache && php artisan route:cache && php artisan view:cache
args:
chdir: "{{ portail_dossier_app }}"
changed_when: true

View file

@ -0,0 +1,29 @@
---
- name: déployer le vhost Nginx du portail
ansible.builtin.template:
src: nginx-portail.conf.j2
dest: /etc/nginx/sites-available/portail.conf
mode: "0644"
notify: recharger nginx
- name: activer le vhost
ansible.builtin.file:
src: /etc/nginx/sites-available/portail.conf
dest: /etc/nginx/sites-enabled/portail.conf
state: link
notify: recharger nginx
- name: désactiver le vhost par défaut de Nginx
ansible.builtin.file:
path: /etc/nginx/sites-enabled/default
state: absent
notify: recharger nginx
- name: activer et démarrer php-fpm et nginx
ansible.builtin.systemd:
name: "{{ item }}"
enabled: true
state: started
loop:
- "php{{ portail_php_version }}-fpm"
- nginx

View file

@ -0,0 +1,12 @@
---
- name: système (PHP, Nginx, Composer, Node)
ansible.builtin.import_tasks: 01-systeme.yml
- name: bases de données de l'app (MariaDB, Redis)
ansible.builtin.import_tasks: 02-bases-donnees.yml
- name: code de l'application
ansible.builtin.import_tasks: 03-code.yml
- name: Nginx
ansible.builtin.import_tasks: 04-nginx.yml