- Jinja 37.9%
- Go Template 24%
- HTML 23%
- Python 15.1%
| files | ||
| group_vars | ||
| host_vars | ||
| roles | ||
| .gitignore | ||
| afpy.org.yml | ||
| alain.yml | ||
| ansible.cfg | ||
| backup.yml | ||
| bye_bbb.yml | ||
| discord-irc-sync.yml | ||
| discuss.yml | ||
| dl.yml | ||
| forgejo.yml | ||
| inventory | ||
| inventory.py | ||
| logs.afpy.org.yml | ||
| makemake.yml | ||
| munin.yml | ||
| pafpy.yml | ||
| pretalx.yml | ||
| pycon.fr.yml | ||
| pyproject.toml | ||
| README.md | ||
| Vagrantfile | ||
| woodpecker-agent.yml | ||
| woodpecker.yml | ||
Playbooks Ansible de l’AFPy
Récupérez le secret dans afpy/pass:
git clone https://github.com/AFPy/pass/
PASSWORD_STORE_DIR=pass/infra pass Ansible-Vault > ~/.ansible-afpy-vault
Puis pour jouer les playbooks :
- Pour tout relancer :
ansible-parallel *.yml - Pour configurer les PyCons :
ansible-playbook pycon.fr.yml
Faire, ne pas faire dans les playbooks
Faire : Configurer les machines :
apt install,- fichiers de configuration,
- créer les utilisateurs,
- éventuellement un premier
git clonepour que ça marche si c’est un site statique.
Ne pas faire :
- Deployer. En dehors de l’éventuel premier git clone, c’est le rôle de la CI (woodpecker du Forgejo, Github Actions, ...), pas de nos playbooks.
Nommage
La distinction services/serveurs :
- Un serveur contient un nombre dans son nom :
- rainette2.afpy.org,
- forgejo1.afpy.org,
- woodpecker1.afpy.org,
- …
- Un service ne contient pas de chiffre dans son nom :
- www.afpy.org,
- git.afpy.org,
- woodpecker.afpy.org,
- …
Une machine peut contenir un ou plusieurs services (un s’il est "gros", plusieurs s’ils sont « néglibeables » (comme plusieurs sites statiques).
Certificats HTTPS
Tous les noms de domaines sont chez lebureau.coop. Pour générer les certificats nous utilisons certbot-dns-rfc2136.
Servers
Résumé des serveurs :
| KVM name | Domain name | hostname | OS | IPv4 | IPv6 | Reverse IPv4 | Reverse IPv6 |
|---|---|---|---|---|---|---|---|
| afpy-pretalx | pretalx2.afpy.org | pretalx2 | Debian GNU/Linux 13 (trixie) | 185.34.33.82 | 2a00:99a0:0:2000::82 | pretalx2.afpy.org. | pretalx2.afpy.org. |
| afpy-git | forgejo1.afpy.org | forgejo1 | Debian GNU/Linux 13 (trixie) | 185.34.33.83 | 2a00:99a0:0:2000::83 | forgejo1.afpy.org. | forgejo1.afpy.org. |
| afpy-discourse | discourse2.afpy.org | discourse2 | Debian GNU/Linux 13 (trixie) | 185.34.33.84 | 2a00:99a0:0:2000::84 | discourse2.afpy.org. | discourse2.afpy.org. |
| afpy-web | rainette2.afpy.org | rainette2 | Debian GNU/Linux 13 (trixie) | 185.34.33.85 | 2a00:99a0:0:2000::85 | rainette2.afpy.org. | rainette2.afpy.org. |
| afpy-genepy | django1.genepy.org | django1 | Debian GNU/Linux 13 (trixie) | 185.34.33.86 | 2a00:99a0:0:2000::86 | django1.genepy.org. | django1.genepy.org. |
| afpy-woodpecker | woodpecker2.afpy.org | woodpecker2 | Debian GNU/Linux 13 (trixie) | 185.34.33.162 | 2a00:99a0:0:2000::1000 | ||
| afpy-woodpecker-agent1 | woodpecker-agent1.afpy.org | woodpecker-agent1 | Debian GNU/Linux 13 (trixie) | 2a00:99a0:0:2000::1001 | |||
| afpy-genepy-bot1 | bot1.genepy.org | bot1 | Debian GNU/Linux 13 (trixie) | 2a00:99a0:0:2000::1002 | |||
| afpy-genepy-bot2 | bot2.genepy.org | bot2 | Debian GNU/Linux 13 (trixie) | 2a00:99a0:0:2000::1003 | |||
| backup2.afpy.org | backup2 | Debian GNU/Linux 13 (trixie) | 45.13.107.8 | mail.gentilsnuages.io. |
pretalx2.afpy.org
♥ Machine sponsorisée par Octopuce ♥
ED25519 key fingerprint is SHA256:vpiNQclG1JF8FAapH335tad3Oh8xpnOPIB+wIZR5F84
C’est un KVM sur un BiXeon L5630 16 threads, 48G de RAM, 900Go de SSD en RAID5.
Pretalx se sauvegarde dans /var/backups/, et rsnapshot récolte ce dossier tous les jours.
Mettre à jour
J'ai suivi cette doc : https://docs.pretalx.org/administrator/maintenance/#performing-updates
root@pretalx2:/home/pretalx/src# git checkout v2025.1.0
root@pretalx2:/home/pretalx/src# ../pretalx_main/venv/bin/python -m pip install --upgrade-strategy eager -U .
pretalx@pretalx2:~$ ./pretalx_main/venv/bin/python -m pretalx check --deploy
pretalx@pretalx2:~$ ./pretalx_main/venv/bin/python -m pretalx migrate
pretalx@pretalx2:~$ ./pretalx_main/venv/bin/python -m pretalx rebuild --npm-install
root@pretalx2:/home/pretalx/src# systemctl restart pretalx@main.service
root@pretalx2:/home/pretalx/src# systemctl restart pretalx-worker@main.service
Problèmes : le rebuild a besoin de compiler des .po dans src/
mais le git clone est fait en root alors il n'a pas les droits, j'ai
du faire :
chown pretalx:www-data /home/pretalx/src/src/pretalx/locale/*/LC_MESSAGES
chown pretalx:www-data /home/pretalx/src/build/lib/pretalx/locale/*/LC_MESSAGES
Aussi il serait intéressant qu'Ansible s'occupe de la mise à jour, il me semble que 90% du travail est fait.
Restaurer une sauvegarde
D’abord, si nécessaire, aller récupérer le fichier sur le serveur de sauvegarde :
$ rsync root@backup2.afpy.org:/srv2/backups/rsnapshot_afpy/daily.0/cfp.pycon.fr/var/backups/pretalx-2024-11-23-main/ ./
$ rsync pretalx-2024-11-23-main root@pretalx2.afpy.org:/var/backups/
Ensuite, charger la sauvegarde :
$ ssh root@pretalx2.afpy.org
# gunzip /var/backups/pretalx-2024-11-23/db.sql.bz2
# sudo -u pretalx psql pretalx_main --file /var/backups/pretalx-2024-11-23.sql
# rsync -a /var/backups/pretalx-2024-11-23/medias/ /home/pretalx/pretalx-main/medias/
rainette2.afpy.org
♥ Machine sponsorisée par Octopuce ♥
C’est un KVM sur un BiXeon L5630 16 threads, 48G de RAM, 900Go de SSD en RAID5.
Elle héberge surtout des sites statiques, mais pas que :
https://www.afpy.org
Lors d’un déplacement de machine ou d’une restauration de sauvegarde, ce service a besoin de :
rsync -vah root@deb2.afpy.org:/home/afpy-org/afpy.db /home/afpy-org/
rsync -vah root@deb2.afpy.org:/home/afpy-org/images /home/afpy-org/
https://pycon.fr
Et ses domaines alternatifs (2010.pycon.fr, 2011.pycon.fr, ...).
Le playbook configure nginx mais lors d’un déplacement de machine ou d’une restauration de sauvegarde, ce service a besoin de :
rsync -vah deb2.afpy.org:/var/www/pycon.fr/ /var/www/pycon.fr/
Alain
Alain le bot IRC du canal #afpy (source).
Lors d’un déplacement de machine ou d’une restauration de sauvegarde, ce service a besoin de :
rsync -vah root@deb2.afpy.org:/var/www/logs.afpy.org /var/www/
rsync -vah root@deb2.afpy.org:/home/alain/.irc3/ /home/alain/.irc3/
La gate IRC—discord
La gate entre IRC et Discord est un discord-irc-sync, le playbook s’occupe de tout.
https://dl.afpy.org
C’est un directory listing nginx des vidéos de nos conférences.
Lors d’un déplacement de machine ou d’une restauration de sauvegarde, ce service a besoin de :
rsync -vah deb2.afpy.org:/var/www/dl.afpy.org/ /nfs/dl.afpy.org/
https://salt-fr.afpy.org
Ansible s’occupe de nginx, il faut copier les donnəs :
rsync -vah deb2.afpy.org:/var/www/salt-fr.afpy.org/ /var/www/salt-fr.afpy.org/
https://nantes.afpy.org
Ansible s’occupe de nginx, il faut copier les donnəs :
rsync -vah deb2.afpy.org:/var/www/nantes.afpy.org/ /var/www/nantes.afpy.org/
https://photos.afpy.org
Ansible s’occupe de nginx, il faut copier les donnəs :
rsync -vah deb2.afpy.org:/var/www/photos.afpy.org/ /var/www/photos.afpy.org/
https://logs.afpy.org
Les logs du salon IRC #afpy (source).
Ils utilisent les logs générés par Alain, donc pas de donnée à copier,
le rsync de /var/www/logs.afpy.org/ fait pour Alain est le même.
https://munin.afpy.org
C’est un munin, ansible s’occupe de tout.
https://p.afpy.org
C’est une pasthèque (un pastebin-like) uniquement utilisable en ligne de commande, source.
Lors d’un déplacement de machine ou d’une restauration de sauvegarde, ce service a besoin de :
rsync -vah root@deb2.afpy.org:/home/pafpy/src/webtools.sqlite3 /home/pafpy/src/
https://paullaroid.pycon.fr
Ansible s’occupe de nginx, il faut copier les donnəs :
rsync -vah deb2.afpy.org:/var/www/paullaroid.pycon.fr /var/www/
https://woodpecker.afpy.org
C’est Woodpecker CI lié à notre forge.
Il ne fait tourner aucune tâche, ce sont les agents qui font tourner les tâches. Si vous avez une machine de libre, vous êtes invités à proposer un agent. Il suffit de :
- Installer une Debian.
- Y ajouter nos authorized_keys.
- Nous donner son IP.
Un agent n’a pas besoin d’IPv4, donc une vieille machine recyclée planquée chez vous sans NAT mais avec de l’IPv6 ça suffit. Pas de Raspberry PI par contre, nous n’avons pour le moment pas de tâches à faire tourner sur arm64.
Ne pas oublier de relancer le playbook de woodpecker pour ajouter
l’IP de l’agent dans nftables. Il n’y a pas de fichier à modifier, la
configuration nftables est basée sur l’inventaire.
Restaurer une sauvegarde
Woodpecker sauvegarde dans /var/backups/, pour restaurer une
sauvegarde il faut donc :
systemctl stop woodpecker.service
cp /var/backups/woodpecker-2024-11-25/woodpecker.sqlite.bak /var/lib/woodpecker/woodpecker.sqlite
systemctl start woodpecker.service
backup2.afpy.org
♥ Machine sponsorisée par Gentils Nuages ♥
C’est un Intel(R) Xeon(R) E5520, 64 GB de RAM, 3 TB de disque en
raid 1 sur /srv2/.
Il sauvegarde (via rsnapshot) les autres machines (voir backup.yml).
Dernière vérification de backup2.afpy.org le 20 novembre 2025 via :
ssh root@backup2.afpy.org sh check-backups.sh
Dernière vérification de silence (chez Julien) le 20 novembre 2025 via :
ssh root@silence.local sh check-backups.sh
En cas de problème avec cette machine, contacter arthur at gentilsnuages.fr.
forgejo1.afpy.org
♥ Machine sponsorisée par Octopuce ♥
C’est un KVM sur un BiXeon L5630, 16 threads, 48G de RAM, 900Go de
SSD en RAID 5.
C’est la machine derrière git.afpy.org, déployée via forgejo.yml.
PostgreSQL
Le Postgres est configuré pour logger toutes les requêtes de manière à utiliser pgbadger pour y voir plus clair sur les perfs.
Mise à jour
cf. https://forgejo.org/docs/latest/admin/upgrade/
Pour faire une mise à jour, se connecter en root à la machine puis commencer par faire une sauvegarde :
systemctl start forgejo-backup.service
S'assurer que tout est vert pour forgejo doctor :
sudo -u git forgejo doctor --config /etc/forgejo/app.ini check --all --log-file /tmp/doctor.log
Exécutez :
sudo -u git forgejo --config /etc/forgejo/app.ini manager flush-queues
Mettre à jour le numéro de version dans ./forgejo.yml.
Lancer le playbook : ansible-playbook forgejo.yml.
Une fois terminé, relancer le forgejo doctor pour vérifier que tout roule.
Sauvegardes
Les données sont sauvegardées automatiquement via rsync sur
backup2.afpy.org (voir backup.yml).
Restaurer une sauvegarde
Procédure testée en 2024 par mdk.
Voici la procédure pour restaurer une sauvegarde sur une nouvelle machine « from scratch ».
Commander une nouvelle machine
De préférence une Debian avec 2 CPU et >= 2 GB de RAM.
Nommer la machine
Typiquement forgejoNEW.afpy.org, configurer les DNS, en profiter pour
réduire le TTL de git.afpy.org puisqu’il faudra le changer à la fin.
Ajouter la machine dans l’inventaire Ansible
Ça devra donc ressembler à :
[forgejo]
forgejoNEW.afpy.org
On peut probablement supprimer l’autre si elle ne marche plus.
Lancer Ansible
ansible-playbook forgejo.yml
rsync la sauvegarde
J’utilise du ssh agent forwarding, si vous n’en utilisez-pas vous
aurez peut-être à rsync sur votre machine d’abord.
Adapté de : https://docs.forgejo.io/en-us/backup-and-restore/#restore-command-restore
Donc, depuis le nouveau forgejo :
cd /var/lib/forgejo/
rsync -vah backup2.afpy.org:/srv2/backups/rsnapshot_afpy/daily.0/git.afpy.org/var/backups/forgejo/ ./
systemctl stop forgejo
rm -fr data custom
unzip forgejo.zip
rm forgejo.zip
mv app.ini /etc/forgejo/app.ini
mv repos data/forgejo-repositories
chown -R git:git .
sudo --user git psql -d forgejo < forgejo.sql
rm forgejo.sql
Copiez aussi, si vous voulez, les host keys (/etc/ssh/ssh_host*)
afin que la fingerprint du serveur ne change pas, les fichiers sont
dans la sauvegarde.
Si l’ancien serveur est toujours accessible, il est possible copier plutôt que partir d’une sauvegarde, commencer par un rsync à chaud, c’est la seule opération lente :
rsync -vah --delete root@forgejo1.afpy.org:/var/lib/forgejo/ /var/lib/forgejo/
Une fois terminé, sur l’ancien serveur :
systemctl stop forgejo
sudo --user git pg_dump --clean forgejo > /var/backups/forgejo/latest.sql
Sur le nouveau serveur :
systemctl stop forgejo
rsync -vah root@forgejo1.afpy.org:/var/backups/forgejo/latest.sql /var/backups/forgejo/
sudo --user git psql -d forgejo < /var/backups/forgejo/latest.sql
rsync -vah --delete root@forgejo1.afpy.org:/var/lib/forgejo/ /var/lib/forgejo/
systemctl start forgejo
Puis passer le playbook forgejo.yml pour remettre les bons droits partout (le playbook démarrera aussi forgejo).
Tester et mettre à jour git.afpy.org
Un rapide test peut être effectué via :
curl --resolve git.afpy.org:IP_DE_LA_NOUVELLE_MACHINE https://git.afpy.org
Puis il faut mettre à jour le CNAME de git.afpy.org pour le faire pointer vers la nouvelle machine.
woodpecker2.afpy.org
♥ Machine sponsorisée par Octopuce ♥
C’est un KVM sur un BiXeon L5630 16 threads, 48G de RAM, 900Go de SSD en RAID5.
woodpecker-agent1.afpy.org
♥ Machine sponsorisée par Octopuce ♥
C’est un KVM sur un BiXeon L5630 16 threads, 48G de RAM, 900Go de SSD en RAID5.
discourse2.afpy.org
♥ Machine sponsorisée par Octopuce ♥
C’est un KVM sur un BiXeon L5630 16 threads, 48G de RAM, 900Go de SSD en RAID5.
Elle héberge https://discuss.afpy.org une instance Discourse.
Déplacement du Discourse vers une nouvelle machine
Le 25 novembre 2024 Julien a déplacé le Discourse de discourse1 à discourse2.
Voici la procédure
- Ajouter les enregistrements A et AAAA de la machine.
- Baisser le TTL du CNAME
discuss.afpy.org. - Mettre à jour le SPF pendant qu’on y est.
- Configurer le reverse DNS de la nouvelle machine.
- Côté Ansible, ajouter la machine au groupe
[discourse]dans le fichierinventory. - Copier sa clé ssh sur la machine dans
/root/.ssh/authorized_keys. - Lancer
ansible-playbook discuss.yml. - Lancer à la main dans
/var/discourse/:./launcher rebuild app(ça prend ~19 min). - Sur l’ancienne machine, faire une sauvegarde, soit via https://discuss.afpy.org/admin/backups, soit :
./launcher enter app discourse backup exit - Copier une sauvegarde dans
/var/discourse/shared/standalone/backups/default/. - Restaurer la sauvegarde :
cd /var/discourse ./launcher enter app discourse enable_restore discourse restore afpy-2023-01-31-215204-v20230130053144.tar.gz exit
Bien tester l’envoi d’emails.
bot1.genepy.org, bot2.genepy.org
♥ Machine sponsorisée par Octopuce ♥
Ce sont deux KVM sur un BiXeon L5630 16 threads, 48G de RAM, 900Go de SSD en RAID5.
Ils sont utilisés par genepy pour corriger les exercices, ils n’ont pas d’état local, pas besoin de sauvegarde.
Ils sont déployés par les playbooks ansible du dossier deploy/ de
https://git.afpy.org/mdk/genepy/.
Rôles utilisés
On utilies ces rôles Ansible :
roles/nginx
Ce rôle configure un nginx avec Letsencrypt en RFC2136 (les domaines sont chez lebureau.coop.
L’avantage de la validation par RFC2136 c’est qu’on peut configurer un nouveau serveur avant que le DNS ne pointe sur lui (comme en DNS01, mais en se basant sur une RFC propre plutôt qu’une API snowflake).
common
common est un rôle "de base" permettant d’avoir une conf "normale" sur toutes nos machines (emacs et vim installés, nos authorized-keys, pas de mlocate, hostname propre, firewall, ce genre de broutilles).
exim
Le playbook exim configure une clé DKIM et signe les mails avec. Mais un humain doit la propager sur les DNS, à chaque passage du playbook l’enregistrement DNS à effectuer est affiché :
TASK [exim4 : Print the DKIM DNS TXT record] **************************************************************************
ok: [forgejo1.afpy.org] => {
"msg": "forgejo1-afpy-org._domainkey.forgejo1.afpy.org. IN TXT \"v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC+uzip6I/d3J5kOwQ/951Je2019wPtikKJ95z0I8eFrOwlDspqhP/IctPlIwl9XOtg6f6OjGrCB9d0W+cZQx8DCdgz0d9CLeWH0jeZWPrmCl1z0XjOnaW7b9QWYR4dVmUVrGPUZwwcCpdiI4jBqumOgyvzMPhWvENRUdiCmIbIgwIDAQAB"
Emails
Les emails sont hébergés chez Galae.
Les mots de passe pour les comptes sont dans le passwordstore.
La doc : https://community.galae.net/ui/workspaces/4/contents/html-document/8
Tâches
Redimentionner un disque sur un VPS
- Agrandir le volume via l'interface web,
- agrandir la partition via
growpart /dev/xvda 1, - agrandir le filesystem via
resize2fs /dev/xvda1.