Réglages
Utilisateurs
Comptes Odoo
Compte Claude
Backblaze
Dépôts git
Suivi de tâches
Sous-domaines
Le compte qui fait tourner Claude pour toute l'installation.
Identifiants communs à tous les projets ; chaque projet ne choisit qu'un bucket.
Pour ces hôtes, une adresse collée en https://… est clonée en SSH :
https://gitea.exemple.com/Org/Projet devient
ssh://gitea@gitea.exemple.com:24/Org/Projet.git. La machine s'authentifie alors par sa
clé SSH, au lieu de demander un identifiant et un mot de passe à chaque projet.
L'organisation est celle sous laquelle « Créer un projet vide » ouvre le
dépôt. Laissée vide, elle est demandée au compte : une seule organisation, c'est elle ;
plusieurs, o2Chat ne choisit pas et le dit.
Ajouter un hôte
Le suivi où vivent les tâches, commun à tous les projets : l'adresse de l'Odoo qui
porte le module de suivi. o2Chat y ajoute /o2chat/context et /o2chat/event.
Vide, rien ne sort de cette machine.
Les deux demandes portent X-O2chat-Signature: sha256=<hmac(secret,
"<X-O2chat-Timestamp>.<corps>")>. Un secret enregistré ne se relit pas : le champ
n'en montre que la trace. Un projet peut avoir le sien (Réglages du projet → Notifications ).
Sauvegardes d'un client hors de portée
Ni VPN, ni SSH, ni port ouvert ? On inverse le sens :
c'est le serveur du client qui pousse ses sauvegardes vers Backblaze, et o2Chat
les y lit. Trois gestes, et le premier envoi part ce soir.
Génère la clé du client
Elle écrit sans pouvoir lire ni effacer : même égarée, elle ne donne accès à
aucune sauvegarde. Elle n'est affichée qu'une fois, et elle s'insérera toute seule dans la
commande de l'étape 3.
Va sur le serveur du client
ssh root@serveur-du-client
Colle ceci
Une seule commande, rien à télécharger : elle dépose le script et enregistre la clé, puis
te demande ce qu'il faut sauvegarder — la machine héberge rarement que des
projets qui nous intéressent. Elle liste les projets Docker trouvés, tu choisis lesquels et
quelles bases, puis si les filestores partent avec les bases ou si l'on s'en
tient aux bases seules. Elle vérifie, propose une première sauvegarde et demande enfin
la cadence : un nombre d'heures (« 6 »), une heure fixe quotidienne
(« 02:30 »), ou « non ».
Les questions arrivent à la fin, une fois le collage terminé : une invite au
milieu prendrait les lignes suivantes pour des réponses.
Copier la commande complète
Ajoute le module au projet, et publie
Un seul module pour toutes les versions d'Odoo , de la 13 à la 19 : rien à
choisir ni à faire correspondre. Il fait le même travail que le script — dump de la base et
archive du filestore poussés vers Backblaze, aux mêmes noms — mais depuis l'intérieur d'Odoo,
sans rien demander au système.
Il passe par le dépôt du projet , pas par une archive à transporter : on le
pose ici, on le publie comme n'importe quel module, et le client le tire. C'est ce qui fait
qu'un correctif se propage — une archive téléchargée fige chaque client sur la version qu'il
a prise, et plus personne ne sait laquelle.
Ajouter le module à ce projet
Il apparaît alors dans « Publier » avec le reste du travail, et passe le même
contrôle que tout module Odoo. Reposer le bouton plus tard remplace le module par sa version
du jour : c'est ainsi qu'on le met à jour.
Pas de dépôt au bout — un Odoo posé à la main, hors git ?
Télécharger
mtx_backup_b2.zip et le déballer dans le dossier des modules, celui que nomme
addons_path de son odoo.conf.
Sur le serveur du client
Tire le code, puis redémarre le service — sous Windows, dans une invite ouverte en
administrateur :
git pull
net stop odoo && net start odoo
Puis, dans Odoo : Applications → Mettre à jour la liste des applications ,
cherche « Sauvegarde Backblaze » et installe-la. Le bouton de mise à jour de la liste ne paraît
qu'avec le mode développeur activé.
Règle, vérifie, puis allume
Dans Odoo, Paramètres → Technique → Sauvegarde Backblaze — le menu
« Technique » ne paraît qu'avec le mode développeur activé, celui-là même
qu'il a fallu pour mettre à jour la liste des applications. Recopie le Key ID et
l'Application key de l'étape 1, le bucket, et le nom du projet — c'est le dossier sous lequel
les sauvegardes seront rangées, en général le nom du client.
« Vérifier » avant tout le reste : il dit ce qui manque — pg_dump
introuvable, filestore absent, bucket hors de portée de la clé, place libre insuffisante — et
surtout il rattrape le piège du délai (voir les détails). Ce n'est qu'une fois qu'il est
satisfait qu'on coche « Sauvegarde automatique » , qui allume le passage
toutes les six heures.
« Sauvegarder maintenant » lance un premier envoi sans attendre : il tourne en
arrière-plan, la page n'a pas besoin de rester ouverte.
Les détails ennuyeux
Les deux buckets
Un pour les dumps, un pour les filestores — le second doit porter filestore dans
son nom, c'est ainsi que le sélecteur rapproche une archive de son dump. Un seul bucket pour les
deux fonctionne aussi : dumps et archives partagent alors le même dossier. Les noms se corrigent
dans la commande collée, sur la ligne o2-backup install.
La rétention est l'affaire d'une règle de cycle de vie du bucket (« garder les
n derniers jours ») : le script n'efface jamais rien à distance.
Ce que déposent les sauvegardes
Dump et archive partagent leur dossier et leur nom de base — c'est ce qui permet de proposer
d'office le bon filestore au moment de restaurer :
odoo-database/ batimax-19/batimax_19.dump
odoo-filestore/ batimax-19/batimax_19_filestore.zip
Le nom ne change pas d'une sauvegarde à l'autre : Backblaze en
empile les versions, le réglage du projet reste valable, et le sélecteur propose toujours la plus
récente — remonter à une version antérieure passe par la console Backblaze.
TIMESTAMPED=1 dans /etc/o2-backup/o2-backup.conf ajoute la date au nom,
et ARCHIVE=tar.gz remplace le zip par une archive diffusée, qui ne pose jamais le
filestore sur le disque.
Les commandes, une par une
o2-backup setup # tout reprendre : projets, filestores, cadence
o2-backup detect --ask # rechoisir projets et bases
o2-backup detect --write # tout prendre, sans questions
o2-backup list # ce qui sera sauvegardé
o2-backup check # prérequis, sans rien envoyer
o2-backup run [projet…] # sauvegarde maintenant
o2-backup schedule --every 4h # change la cadence (--daily --at 02:30 pour un seul passage)
Configuration dans /etc/o2-backup/, journal dans
/var/log/o2-backup.log. Prérequis sur sa machine : Docker, curl et
sha1sum et zip — rien de plus, le script parle à Backblaze par son
API native. Si zip manque, l'assistant propose de l'installer et nomme la commande ;
refusé, le filestore part en .tar.gz, qu'o2Chat restaure aussi bien — et la question
ne se pose pas du tout quand on a répondu « bases seules » (WITH_FILESTORE=0).
Côté o2Chat
Dans Réglages → Compte Backblaze , la clé de lecture de l'installation.
Puis, dans les réglages de ce projet, le bucket et le nom de fichier — celui-ci préremplit la
recherche du sélecteur de sauvegardes.
Le script
Télécharger o2-backup.sh
Copier le script seul
Les détails ennuyeux
Le piège du délai — à regarder en premier
Odoo tue une tâche planifiée qui dépasse son délai, et un dump de plusieurs gigaoctets le
dépasse. Le réglage ne se lit pas où l'on croit : limit_time_real_cron
n'est retenu que s'il est strictement positif . À -1, qui est le
défaut , comme à 0, c'est limit_time_real qui s'applique —
120 secondes . Dans son odoo.conf :
limit_time_real_cron = 86400
« Vérifier » le dit tout seul, et nomme la limite réellement en vigueur. C'est
la seule chose qui casse en silence : la sauvegarde part, se fait couper en chemin, et rien ne
s'en plaint.
Ce que le module dépose
Les mêmes noms que le script, puisque c'est le même sélecteur qui les relit :
odoo-database/ batimax-19/batimax_19.dump
odoo-filestore/ batimax-19/batimax_19_filestore.zip
Le dump est un pg_dump --format=c, et non la sauvegarde native
d'Odoo : celle-ci écrit du SQL en clair dans un zip, qu'o2Chat refuse — il reconnaît un dump à
son en-tête PGDMP, et s'en sert pour choisir le client PostgreSQL qui saura le
relire.
Lancer une sauvegarde à la main
« Sauvegarder maintenant » suffit : le travail part dans un fil détaché, la page n'a pas
besoin de rester ouverte et l'avancement s'écrit dans « Détail ». Pour la suivre ligne à ligne,
sans mobiliser le moindre worker :
python3 odoo-bin shell -d BASE -c odoo.conf --no-http --log-level=info
>>> env['mtx.backup.b2']._get_config()._run()
Où vivent les réglages
Dans Odoo, Paramètres → Technique → Sauvegarde Backblaze , réservé aux administrateurs.
La clé Backblaze y est enregistrée en base , donc présente dans le dump
lui-même : c'est la contrepartie de n'avoir rien à installer sur la machine, et elle reste
tenable parce que la clé de sauvegarde écrit sans pouvoir lire ni effacer .
Ce que cela ne fait pas
Cela rapatrie la base d'un client Windows ; cela ne déploie pas chez lui.
« Mettre à jour la production » suppose docker compose, un conteneur ou systemd — les trois
supposent Linux. La mise à jour du code là-bas reste un git pull à la main.
Tunnel vers une production injoignable
Ni VPN, ni port ouvert ? On inverse le sens :
c'est la machine du client qui appelle , vers l'extérieur, et réserve un port sur
ce serveur. « Mettre à jour la prod » s'adresse alors à 127.0.0.1 et à ce port —
rien à ouvrir sur son pare-feu.
Ce serveur n'est pas encore prêt à recevoir des tunnels. Un compte système
sans shell et deux lignes de réglage sshd, une fois pour toutes.
Préparer ce serveur
Attribue un port à ce client
Un port par client, jamais réattribué : c'est lui qui distingue une
production d'une autre, et une collision ferait déployer chez le mauvais.
Nom du client
Port réservé sur ce serveur
Adresse de ce serveur, vue depuis chez le client
Préparer la commande
Va sur le serveur du client, et colle
ssh root@serveur-du-client
En root, ou depuis un compte sudo — le collage s'en charge lui-même et le
mot de passe n'est demandé qu'une fois. Le script y voyage tout entier : le client n'a
rien à télécharger depuis cette machine. Il installe le tunnel, le pose en service,
autorise o2Chat à entrer — le tunnel n'achemine que du TCP, il faut
encore que son sshd nous ouvre — et te rend une clé publique .
Aucune clé publique lisible sur ce serveur : le collage
monte le tunnel mais ne laisse pas entrer o2Chat. Fabrique-en une
(ssh-keygen -t ed25519), ou renseigne le chemin de la clé privée dans la page
Déploiement — o2Chat cherche la publique à côté, en .pub.
Renseigne le nom et le port ci-dessus, puis
« Préparer la commande » : elle part dans le presse-papier.
Voir la commande, ou la copier de nouveau
Rapporte la clé qu'il t'a rendue
La clé privée reste chez lui — seule la publique voyage. Une fois déclarée, elle ne pourra
réserver que ce port-là et rien atteindre d'autre ici.
Déclarer ce client
régler le déploiement de ce projet sur ce tunnel
Les tunnels de ce serveur
Un tunnel peut être déclaré et mort : sa machine, elle, croit toujours que tout
va bien. C'est d'ici que ça se voit.
Les détails ennuyeux
Pourquoi pas autossh
Il ne fait que relancer ssh quand celui-ci sort, or le mode d'échec
courant n'est pas « ssh sort » mais « ssh reste vivant et le tunnel est mort ». Le service posé
chez le client s'appuie sur ServerAliveInterval et ExitOnForwardFailure,
que systemd relance : une coupure se rattrape en moins d'une minute.
En ligne de commande, sur ce serveur
o2-tunnel-relay status # qui est réellement monté
o2-tunnel-relay next # le prochain port libre
o2-tunnel-relay paste <nom> <port> # refabriquer le collage
o2-tunnel-relay remove <nom> # retirer un client
Et chez le client
o2-tunnel status # où en est le tunnel
o2-tunnel check # l'éprouver en le montant pour de vrai
o2-tunnel authorize '<clé publique d o2Chat>' # laisser entrer o2Chat
Le tunnel ne transporte que du TCP : o2Chat s'authentifie encore auprès du sshd
du client. C'est une seconde clé, sans rapport avec celle du tunnel.
Voir un port de la production
Que veux-tu voir là-bas ?
Un port seul désigne la production elle-même. Une adresse complète désigne
une machine de son réseau : c'est la production qui ouvre la connexion, pas ce serveur.
Pendant combien de temps ?
15 minutes
30 minutes
1 heure
2 heures
4 heures
Ce port s'ouvre sur Internet, en clair, sur une adresse IP — et derrière, c'est la
base réelle du client. Le lien ne vaut que pour le navigateur qui l'ouvre, chaque page
porte un cadre rouge, et tout se referme à l'heure dite.