Watch
1
0
Fork
You've already forked infra
0
forked from AFPy/infra
Documenting the server infrastructure.
  • Jinja 49.8%
  • HTML 30.3%
  • Python 19.9%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2025-11-22 18:53:18 +01:00
files fix title 2024-02-02 09:04:16 +01:00
group_vars Forgejo: Blocking an AS that bumped loadavg to 5 with random user agents. 2025-11-20 23:35:12 +01:00
host_vars Hop, new Woodpecker agent. 2025-10-17 19:31:57 +02:00
roles Forgejo: No longer needed with our current denylist. 2025-11-18 21:30:09 +01: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 Strikwerda Investments killed Gandi. 2025-09-26 14:01:21 +02:00
forgejo.yml Bump forgejo. 2025-11-22 18:53:18 +01: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 I do no longer use julienpalard.nginx. 2025-11-04 09:05:40 +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. 2025-11-18 21:30:22 +01:00

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 clone pour 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

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

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