# org.alpinux.owni Accueil des projets de l'association **Alpinux** (le LUG de Savoie). Chaque sous-dossier est un dépôt git indépendant avec son propre remote sur Gitea. Ce dossier racine est l'espace de travail : son dépôt [alpinux-owni](https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-owni) ne versionne que ce `README.md` et le `.gitignore` — le contenu des sous-dossiers appartient à leur dépôt. --- ## Projets | Dossier | Domaine | Technologie | Dépôt Gitea | |---------|---------|-------------|-------------| | `feedback/` | feedback.alpinux.org | à construire | [alpinux-feedback](https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-feedback) | | `home/` | alpinux.org | HTML statique | [alpinux-home](https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-home) | | `portail/` | portail.alpinux.org | en construction | [alpinux-portail](https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-portail) | ### Sortis de cet espace Ces projets ont leur propre dossier, au même niveau que celui-ci — un dépôt, un dossier : | Dossier | Domaine | Dépôt Gitea | |---------|---------|-------------| | `~/Projects/alpinux.wiki` | wiki.alpinux.org | [alpinux-wiki](https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-wiki) | | `~/Projects/alpinux.admin` | admin.alpinux.org | [alpinux-admin](https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-admin) | | `~/Projects/alpinux.dynamic` | dynamic.alpinux.org | [alpinux-dynamic](https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-dynamic) | | `~/Projects/alpinux.static` | static.alpinux.org | [alpinux-static](https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-static) | | `~/Projects/alpinux.gitea` | gitea.alpinux.org | [alpinux-gitea](https://gitea.alpinux.org/alpinux.cedrica5l/alpinux-gitea) | | `~/Projects/alpinux.messagerie` | messagerie.alpinux.org | [alpinux.messagerie](https://gitea.alpinux.org/alpinux.cedrica5l/alpinux.messagerie) | Leurs procédures de déploiement sont décrites dans leur propre README. Gitea : **https://gitea.alpinux.org/alpinux.cedrica5l** ISPConfig : **https://owni.alpinux.org:8080** AlpID (SSO) : **https://alpid.alpinux.org** — realm `master` --- ## Déployer un site **Chaque projet décrit son déploiement dans son propre dépôt.** Ce dépôt-ci parle du serveur, pas des sites qu'il héberge : dupliquer les procédures ici garantirait qu'elles divergent. | Projet | Où est la procédure | |---|---| | `static` | `alpinux-static/README.md` et `INFRASTRUCTURE.md` | | `wiki` | `alpinux-wiki/docs/deploiement.md` ; webhook Gitea à chaque push | | `messagerie` | `alpinux.messagerie/docs/installation.md` — **copie de fichiers, base d'abord** | | `admin` | `alpinux-admin/DEPLOIEMENT.md` | | `dynamic` | `alpinux-dynamic/DEPLOIEMENT.md` | | `home` | `git pull` sur le serveur ; le proxy de calendrier est décrit dans `alpinux-home/PROXY-CALENDRIER.md` | | autres | le README du dépôt concerné | Dans tous les cas : versionner avec `git push` **avant** de déployer. --- ## Authentification AlpID Tous les projets Flask utilisent **AlpID** (SSO Keycloak). - Chaque projet a son propre client Keycloak (`admin`, `dynamic`, `static-cdn`, …) - Scopes : `openid profile email` - Autorisation : claim `groups` → sinon `ADMIN_EMAILS` → sinon tout utilisateur AlpID - Discovery URL : `https://alpid.alpinux.org/realms/master/.well-known/openid-configuration` --- ## Credentials locaux Le fichier **`.credentials`** (ignoré par git) centralise les accès à renseigner localement : ``` .credentials ← à compléter manuellement, jamais commité ``` Il contient : token Gitea API, accès ISPConfig, accès AlpID admin, secrets clients Keycloak. Utiliser `source .credentials` dans un script pour charger les variables. --- ## Règle Claude Code Lancer Claude depuis le sous-dossier du projet pour limiter le contexte : ```bash cd ~/Projects/alpinux.static && claude cd ~/Projects/alpinux.wiki && claude ``` --- ## Comptes personnels vs comptes de service Alias SSH : `alpinux.org` → compte `abonnelc`. ### Règle absolue Un compte personnel (`abonnelc` ou tout autre) ne doit jouer **aucun rôle dans le fonctionnement à long terme** des services : - pas `User=` dans un unit systemd - pas propriétaire des fichiers de l'app ou des logs - pas dans la liste des groupes dont dépend un service en production - pas référencé dans un `chown`, `setfacl`, ou cron de production Si un service dépend d'un compte personnel, sa disparition (départ, suppression du compte, changement de login) fait tomber le service en production. ### Rôle d'abonnelc `abonnelc` est un **compte d'administration ponctuelle**, limité à : - créer ou modifier les fichiers `.env` sur le serveur - redémarrer un service après un déploiement - effectuer des opérations admin exceptionnelles ### Comptes de service Chaque service tourne sous son propre utilisateur système dédié (ex. `static-cdn` pour `static-cdn.service`). C'est ce compte qui possède les fichiers, les logs, et les droits nécessaires — pas `abonnelc`. --- ## Fichiers de référence Ce dépôt ne contient pas seulement de la documentation : il garde les configurations telles qu'elles devraient être, pour auditer et reconstruire. > **ISPConfig gère les vhosts Apache réels — ne jamais déployer `conf/` > directement.** Ces fichiers sont des références, pas des sources : ISPConfig > régénère les siens et écraserait toute modification à la main. ## Structure ``` ├── conf/ → VirtualHost Apache (référence, un fichier par service) ├── dns/ → Zone DNS (export daté, l'autorité est chez OVH) ├── services/ → Units systemd (à déployer dans /etc/systemd/system/) └── docs/ → Documentation déploiement par service ``` --- ## Services | Domaine | Port interne | Service systemd | Répertoire serveur | |---------|-------------|-----------------|-------------------| | alpinux.org | — (statique) | — | ISPConfig web root | | wiki.alpinux.org | — (statique rsync) | — | `/var/www/clients/client1/web2/web/wiki-static` | | admin.alpinux.org | `127.0.0.1:5002` | `alpinux-admin` | `/home/alpinux/site/admin` | | dynamic.alpinux.org | `127.0.0.1:5001` | `dynamic-alpinux` | `/home/alpinux/dynamic` | | static.alpinux.org | `127.0.0.1:5003` | `static-cdn` | `/opt/static-cdn` | --- ## DNS `dns/alpinux.org.zone` est un **export daté** de la zone `alpinux.org` — dernier relevé le **2026-05-05** (serial `2026050501`). L'autorité est chez OVH : ce fichier ne pilote rien, il sert à reconstituer la zone si elle est perdue ou écrasée. Il contient les MX, SPF, DMARC, MTA-STS, DKIM (clé publique), les SRV CalDAV/CardDAV et les CNAME de tous les sous-domaines. Le réexporter après toute modification chez OVH, sinon il décrit un état qui n'existe plus. --- --- ## Documentation d'exploitation | Document | Sujet | |---|---| | [`docs/courrier-sortant.md`](docs/courrier-sortant.md) | relais, SPF/DKIM/DMARC, plafonds, boîtes du service | | [`docs/certificats.md`](docs/certificats.md) | les deux mécanismes TLS, leurs pièges, les réparations | | [`docs/sauvegardes.md`](docs/sauvegardes.md) | sauvegarder les bases, et surtout les restaurer | --- ## Serveur | | | |---|---| | **Hostname** | `owni.alpinux.org` | | **OS** | Debian 12 (bookworm) | | **IPv4** | `51.91.79.148` | | **IPv6** | `2001:41d0:404:200::3f85/128` | | **Passerelle IPv6** | `2001:41d0:404:200::1` | | **SSH** | `ssh alpinux.org` (alias → `abonnelc@owni.alpinux.org`) | Config IPv6 persistante : `/etc/network/interfaces.d/60-ipv6.cfg` Cloud-init réseau désactivé : `/etc/cloud/cloud.cfg.d/99-disable-network-config.cfg` --- ## Courrier sortant Tout le courrier de la machine passe par un relais depuis les 25-26/09/2026 (`mail.acemail.fr`), et l'IP qui parle aux destinataires n'est plus celle d'owni. SPF, DKIM, DMARC, les plafonds de Postfix, les boîtes du service et les pièges qui vont avec : → **[`docs/courrier-sortant.md`](docs/courrier-sortant.md)** --- ## Certificats TLS Deux mécanismes coexistent — un certificat certbot multi-domaines pour huit sites, un certificat par site émis par ISPConfig via acme.sh — avec un piège qui a déjà cassé deux fois le HTTPS d'un site pendant plusieurs semaines. → **[`docs/certificats.md`](docs/certificats.md)** --- ## Bases de données Six bases applicatives, déclarées dans ISPConfig, plus celles du système. | Base | Service | Sauvegarde | |---|---|---| | `c1_messagerie_db` | messagerie.alpinux.org | quotidienne, **1 copie** | | `c1dolibarr` | dolibarr.alpinux.org — fichier des adhérents | **aucune** | | `c1gitea` | gitea.alpinux.org — tous les dépôts | **aucune** | | `c1alpid` | alpid.alpinux.org — le SSO | **aucune** | | `c1_installparty` | installparty.alpinux.org | **aucune** | | `c1_evenements` | événements | **aucune** | S'y ajoutent `dbispconfig`, `roundcube` et `phpmyadmin`. `sudo mysql` passe par le socket unix, sans mot de passe. --- ## Sauvegardes Les sept bases sont tirées chaque nuit vers le poste par `scripts/sauvegarder-owni.sh`. La procédure de **restauration** — et ses pièges, dont le worker de la messagerie qui réexpédierait une campagne — est écrite à côté : → **[`docs/sauvegardes.md`](docs/sauvegardes.md)** Ce qui n'est **pas** sauvegardé : les fichiers des sites, les boîtes mail, `/etc`. Ce sont des choix, écrits comme tels dans le document. ---