Documenting the server infrastructure.
  • Jinja 37.9%
  • Go Template 24%
  • HTML 23%
  • Python 15.1%
Find a file
2026-05-03 19:42:42 +02:00
files fix title 2024-02-02 09:04:16 +01:00
group_vars Actualiser group_vars/all/authorized_keys 2026-02-02 07:32:06 +01:00
host_vars Hop, new Woodpecker agent. 2025-10-17 19:31:57 +02:00
roles forgejo: Putting some other URLs behind anubis. 2026-05-03 19:42:42 +02:00
.gitignore Pretalx role 2024-04-03 21:11:29 +02:00
afpy.org.yml Strikwerda Investments killed Gandi. 2025-09-26 14:01:21 +02:00
alain.yml When Python changes, venv break. It should help. 2023-03-30 14:52:05 +02:00
ansible.cfg Pretalx role 2024-04-03 21:11:29 +02:00
backup.yml Disk change. 2025-04-17 18:57:14 +02:00
bye_bbb.yml Strikwerda Investments killed Gandi. 2025-09-26 14:01:21 +02:00
discord-irc-sync.yml Hello discord sync to python-docs-fr. 2025-11-12 18:58:13 +01:00
discuss.yml Strikwerda Investments killed Gandi. 2025-09-26 14:01:21 +02:00
dl.yml Actualiser dl.yml 2026-02-02 07:28:15 +01:00
forgejo.yml Forgejo: Protecting /blame/ behind Anubis. Fuck LLMs. 2026-05-03 19:06:59 +02:00
inventory Removing the woodpecker agent from the backup server, don't feel safe about it. 2025-11-09 11:55:02 +01:00
inventory.py Faster inventory.py using threading. 2025-11-10 10:13:43 +01:00
logs.afpy.org.yml Proofreading logs.afpy.org.yml 2025-11-12 18:58:42 +01:00
makemake.yml Enabling pagination on makemake. 2025-11-10 11:11:33 +01:00
munin.yml Bump genepy's Django to Trixie. 2025-11-09 10:39:43 +01:00
pafpy.yml Strikwerda Investments killed Gandi. 2025-09-26 14:01:21 +02:00
pretalx.yml Strikwerda Investments killed Gandi. 2025-09-26 14:01:21 +02:00
pycon.fr.yml Mise en place de la redirection pycon.fr → pycon.fr/2026 2026-01-29 12:04:13 +01:00
pyproject.toml Hello cog. 2025-11-04 09:58:22 +01:00
README.md Checked backups. 2025-11-20 14:55:39 +01:00
Vagrantfile Moved pretalx vagrant file and remove meta 2024-04-04 08:33:20 +02:00
woodpecker-agent.yml Bump woodpecker. 2025-11-18 21:30:22 +01:00
woodpecker.yml Bump Woodpecker. 2026-05-03 19:07:12 +02:00

Playbooks Ansible de lAFPy

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 clone pour que ça marche si cest un site statique.

Ne pas faire :

  • Deployer. En dehors de léventuel premier git clone, cest 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 sil est "gros", plusieurs sils 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

Cest 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

Dabord, 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

Cest 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

source

Lors dun déplacement de machine ou dune 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 dun déplacement de machine ou dune 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 dun déplacement de machine ou dune 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 soccupe de tout.

https://dl.afpy.org

Cest un directory listing nginx des vidéos de nos conférences.

Lors dun déplacement de machine ou dune 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 soccupe 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 soccupe 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 soccupe 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

Cest un munin, ansible soccupe de tout.

https://p.afpy.org

Cest une pasthèque (un pastebin-like) uniquement utilisable en ligne de commande, source.

Lors dun déplacement de machine ou dune 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 soccupe de nginx, il faut copier les donnəs:

rsync -vah deb2.afpy.org:/var/www/paullaroid.pycon.fr /var/www/

https://woodpecker.afpy.org

Cest 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 :

Un agent na pas besoin dIPv4, donc une vieille machine recyclée planquée chez vous sans NAT mais avec de lIPv6 ça suffit. Pas de Raspberry PI par contre, nous navons pour le moment pas de tâches à faire tourner sur arm64.

Ne pas oublier de relancer le playbook de woodpecker pour ajouter lIP de lagent dans nftables. Il ny a pas de fichier à modifier, la configuration nftables est basée sur linventaire.

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

Cest un Intel(R) Xeon(R) E5520, 64GB de RAM, 3TB 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

Cest un KVM sur un BiXeon L5630, 16 threads, 48G de RAM, 900Go de SSD en RAID 5.

Cest 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 >=2GB de RAM.

Nommer la machine

Typiquement forgejoNEW.afpy.org, configurer les DNS, en profiter pour réduire le TTL de git.afpy.org puisquil faudra le changer à la fin.

Ajouter la machine dans linventaire Ansible

Ça devra donc ressembler à :

[forgejo]
forgejoNEW.afpy.org

On peut probablement supprimer lautre si elle ne marche plus.

Lancer Ansible

ansible-playbook forgejo.yml

rsync la sauvegarde

Jutilise du ssh agent forwarding, si vous nen utilisez-pas vous aurez peut-être à rsync sur votre machine dabord.

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 lancien serveur est toujours accessible, il est possible copier plutôt que partir dune sauvegarde, commencer par un rsync à chaud, cest la seule opération lente:

rsync -vah --delete root@forgejo1.afpy.org:/var/lib/forgejo/ /var/lib/forgejo/

Une fois terminé, sur lancien 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

Cest 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

Cest un KVM sur un BiXeon L5630 16 threads, 48G de RAM, 900Go de SSD en RAID5.

discourse2.afpy.org

♥ Machine sponsorisée par Octopuce

Cest 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 quon y est.
  • Configurer le reverse DNS de la nouvelle machine.
  • Côté Ansible, ajouter la machine au groupe [discourse] dans le fichier inventory.
  • 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 ~19min).
  • Sur lancienne 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 lenvoi demails.

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 nont 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.

Lavantage de la validation par RFC2136 cest quon 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 quune API snowflake).

common

common est un rôle "de base" permettant davoir 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 lenregistrement 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.