diff --git a/pica-db-backup/Dockerfile b/pica-db-backup/Dockerfile index 5db85d19d731212a2499f925e85bc1682ef29ded..a1042c74ea265c446d53b06621a46859782929cd 100644 --- a/pica-db-backup/Dockerfile +++ b/pica-db-backup/Dockerfile @@ -2,6 +2,7 @@ FROM python:3-slim-buster RUN apt-get update && \ apt-get install -y --no-install-recommends \ + iputils-ping \ postgresql-client \ mysql-client \ mongodb-clients \ diff --git a/pica-db-backup/README.md b/pica-db-backup/README.md index c521d7e13d4989a12644e19f34c924e05f145911..6eba910716c03265b52c38fd45de85654b6ed580 100644 --- a/pica-db-backup/README.md +++ b/pica-db-backup/README.md @@ -4,7 +4,7 @@ Cet outil orchestre le backup des différents services de Picasoft. Il est capable de gérer les bases de données `postgres`, `mysql` ou `mongo` pour le moment. -Il est flexible et se configure via des fichiers JSON. +Il est flexible et se configure via un fichier JSON. <!-- TOC depthFrom:1 depthTo:6 withLinks:1 updateOnSave:1 orderedList:0 --> @@ -19,12 +19,12 @@ Il est flexible et se configure via des fichiers JSON. ## Configuration -Les fichiers dans [`.config`](./config) recensent les informations sur les différents services mis en place sur les machines et les informations nécessaires pour lancer les rotations sur ces services. +Le fichier dans [`config/backup_config.json`](./config/backup_config.json) recensent les informations sur les différentes bases de données qui doivent être backupées. -Ces fichiers **sont** les fichiers utilisés **en production**. -Ils ne doivent pas être modifiés sur les machines sans être synchronisés avec le dépôt Git. +Ce fichier **est** utilisé **en production**. +Il ne doit pas être modifié sur les machines sans être synchronisé avec le dépôt Git. -On veillera à ce que les noms d'hôte correspondent bien aux noms des conteneurs (gérés par d'autres Docker Compose), et que le dossier `/DATA/BACKUP` existe. +Ce service est destiné à être lancé sur l'ensemble des machines : de cette manière peu importe que Mattermost tourne sous pica01 ou pica02, elle aura des backups. Si une base de donnée n'est pas accessible, elle est simplement ignorée, ce qui permet d'utiliser le même fichier de configuration pour l'ensemble des machines. ### Structure @@ -40,7 +40,7 @@ On veillera à ce que les noms d'hôte correspondent bien aux noms des conteneur ### Gestion des secrets -Afin de pouvoir versionner les fichiers de configuration sans exposer les identifiants aux bases de données, on utilise le système suivant : +Afin de pouvoir versionner le fichier de configuration sans exposer les identifiants aux bases de données, on utilise le système suivant : * Dans le JSON, on utilise un nom de variable d'environnement à la place de l'identifant, **sans le $**, *e.g.* `ETHERPAD_DB_USER`. * Dans le fichier `db.secrets`, on renseigne la valeur de cette variable d'environnement. @@ -49,17 +49,21 @@ La substitution est effectué automatiquement par l'outil. ### Exemple +Cet exemple montre trois possibilités : le backup d'une base MySQL, Postgresql et MongoDB. + ```json { - "wekan": + "mattermost": { - "Host": "wekan-db", - "Port": "27017", - "Database": "wekan", - "Type": "mongo", - "Folder": "wekan", + "Host": "mattermost-db", + "Port": "5432", + "User": "MATTERMOST_DB_USER", + "Password": "MATTERMOST_DB_PASSWORD", + "Database": "mattermost", + "Type": "postgres", + "Folder": "mattermost", "Cron" : "0 * * * *", - "Init-Backup" : "0", + "Init-Backup" : "1", }, "etherpad": { @@ -70,22 +74,29 @@ La substitution est effectué automatiquement par l'outil. "Database": "--all-databases", "Type": "mysql", "Folder": "etherpad", - "Cron" : "0 * * * *", + "Cron" : "0 */6 * * *", "Options" : "--single-transaction", - "Init-Backup" : "0", + "Init-Backup" : "1", + }, + "wekan": + { + "Host": "wekan-db", + "Port": "27017", + "Database": "wekan", + "Type": "mongo", + "Folder": "wekan", + "Cron" : "0 */12 * * *", + "Init-Backup" : "1", } } + ``` ## Lancement -On se synchronise simplement avec le dépôt et on lance le Docker Compose. - -On copie `secrets/db.secrets.example` dans `secrets/db.secrets` : -* On assigne le nom de la VM à `HOSTNAME` (*e.g.* `pica02`), -* On renseigne les secrets (voir [plus bas]((#gestion-des-secrets))) +On se synchronise simplement avec le dépôt et on copie `secrets/db.secrets.example` dans `secrets/db.secrets` et on renseigne les secrets (voir [Gestion des secrets]((#gestion-des-secrets))). -L'outil sélectionne automatiquement le bon fichier de configuration en fonction du nom d'hôte de la machine virtuelle, il n'y a donc rien à modifier : +On lance ensuite le Docker Compose : ``` $ docker-compose up -d diff --git a/pica-db-backup/config/pica01.json b/pica-db-backup/config/backup_config.json similarity index 68% rename from pica-db-backup/config/pica01.json rename to pica-db-backup/config/backup_config.json index 4b9b6a3dd8a6918ef1d493b4ef6d7778a2497a43..dd627cd536aa0e7c4176adbde3327ca2b608b1eb 100644 --- a/pica-db-backup/config/pica01.json +++ b/pica-db-backup/config/backup_config.json @@ -10,13 +10,6 @@ "Folder": "mattermost", "Cron" : "0 * * * *", "Init-Backup" : "1", - "Backup-Rota": - { - "Hour" : 24, - "Day" : 7, - "Week" : 4, - "Month" : 12 - } }, "etherpad": { @@ -30,12 +23,15 @@ "Cron" : "0 */6 * * *", "Options" : "--single-transaction", "Init-Backup" : "1", - "Backup-Rota": - { - "Hour" : 24, - "Day" : 7, - "Week" : 4, - "Month" : 12 - } + }, + "wekan": + { + "Host": "wekan-db", + "Port": "27017", + "Database": "wekan", + "Type": "mongo", + "Folder": "wekan", + "Cron" : "0 */12 * * *", + "Init-Backup" : "1", } } diff --git a/pica-db-backup/config/pica02.json b/pica-db-backup/config/pica02.json deleted file mode 100644 index 0b5eecd984c74eb179b65d64f400997003999c86..0000000000000000000000000000000000000000 --- a/pica-db-backup/config/pica02.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "wekan": - { - "Host": "wekan-db", - "Port": "27017", - "Database": "wekan", - "Type": "mongo", - "Folder": "wekan", - "Cron" : "0 */12 * * *", - "Init-Backup" : "1", - "Backup-Rota": - { - "Hour" : 24, - "Day" : 7, - "Week" : 4, - "Month" : 12 - } - } -} diff --git a/pica-db-backup/mongo-run.sh b/pica-db-backup/mongo-run.sh index 570193cc404352bc34d6be2eab9f90fd6f9d88fb..dc1fe6039d563aabfb1cf469b66b62db5a813126 100755 --- a/pica-db-backup/mongo-run.sh +++ b/pica-db-backup/mongo-run.sh @@ -8,6 +8,8 @@ BACKUP_FOLDER=${BACKUP_FOLDER:-"/backup/"} [ -z "${MONGO_PORT}" ] && { echo "=> MONGO_PORT cannot be empty" && exit 1; } [ -z "${MONGO_DB}" ] && { echo "=> MONGO_DB cannot be empty" && exit 1; } +ping -c 1 -W 1 "${MONGO_HOST}" || echo "${MONGO_HOST} not available, skipping backup..."; exit 1 + if [[ -z "${MONGO_USER}" && -z "${MONGO_PASS}" ]]; then BACKUP_CMD="mongodump --forceTableScan -d ${MONGO_DB} -h ${MONGO_HOST}:${MONGO_PORT} -o $BACKUP_FOLDER"'${BACKUP_NAME}' RESTORE_CMD="mongorestore -d ${MONGO_DB} -h ${MONGO_HOST}:${MONGO_PORT} " diff --git a/pica-db-backup/mysql-run.sh b/pica-db-backup/mysql-run.sh index 21b85bf1870ae291e9871630b9edf89c0cfd4d34..0f345c7761e904f983f92084cf8a17126bc47a46 100755 --- a/pica-db-backup/mysql-run.sh +++ b/pica-db-backup/mysql-run.sh @@ -18,6 +18,8 @@ MYSQL_PASS=${MYSQL_PASS:-${MYSQL_ENV_MYSQL_PASS}} [ -z "${MYSQL_USER}" ] && { echo "=> MYSQL_USER cannot be empty" && exit 1; } [ -z "${MYSQL_PASS}" ] && { echo "=> MYSQL_PASS cannot be empty" && exit 1; } +ping -c 1 -W 1 "${MYSQL_HOST}" || echo "${MYSQL_HOST} not available, skipping backup..."; exit 1 + BACKUP_CMD="mysqldump -h${MYSQL_HOST} -P${MYSQL_PORT} -u${MYSQL_USER} -p${MYSQL_PASS} ${EXTRA_OPTS} ${MYSQL_DB} > $BACKUP_FOLDER"'${BACKUP_NAME}' ########################## diff --git a/pica-db-backup/postgres-run.sh b/pica-db-backup/postgres-run.sh index 4d57837370e0a4eb2e38df56060a77373cfd16ff..bae70c926386c7789fafec011f64f5e9a6968e6f 100755 --- a/pica-db-backup/postgres-run.sh +++ b/pica-db-backup/postgres-run.sh @@ -8,6 +8,8 @@ BACKUP_FOLDER=${BACKUP_FOLDER:-"/backup/"} [ -z "${POSTGRES_PASS}" ] && { echo "=> POSTGRES_PASS cannot be empty" && exit 1; } [ -z "${POSTGRES_DB}" ] && { echo "=> POSTGRES_DB cannot be empty" && exit 1; } +ping -c 1 -W 1 "${POSTGRES_HOST}" || echo "${POSTGRES_HOST} not available, skipping backup..."; exit 1 + BACKUP_CMD="pg_dump -w -c > $BACKUP_FOLDER"'${BACKUP_NAME}' ########################## @@ -60,7 +62,7 @@ export PGUSER=$POSTGRES_USER export PGPASSWORD=$POSTGRES_PASS echo "=> ${POSTGRES_SERVICE_NAME}: Restore database from \$1" -tar -xzvf \$1 +tar -xzvf \$1 output="\$(echo \$1 | awk -F'.tar.gz' '{print \$1".sql"}')" if psql < \$output ;then echo "${POSTGRES_SERVICE_NAME}: Restore succeeded"