diff --git a/README.md b/README.md index ae34c7fd1507e415f8892a527c7d23bef01b8ba4..55c7b8ac8fc1d791b180b3352ef6974357ad39da 100644 --- a/README.md +++ b/README.md @@ -36,13 +36,15 @@ For example (non-exhaustive list): Note about TLS certificates: a certificate will be added automatically during setup, using Certbot. +Systemd is required to handle the database backup scripts. + ## Installation ### Create an Ubuntu server instance The project should work with any Ubuntu server (Virtual Private Server (VPS), dedicated server...) version 20.04 -Debian server should work as well, though it has not been tested yet. +Debian stable 11 works as well, it has been tested, but only once yet (more to come). Suggestions include (non-exhaustive list): - [Hetzner](https://www.hetzner.com/cloud) diff --git a/config/systemd/mariadb-nc-backup.service b/config/systemd/mariadb-nc-backup.service new file mode 100644 index 0000000000000000000000000000000000000000..d6c8cf5af4f9fada3686c04dbab590852f9f5471 --- /dev/null +++ b/config/systemd/mariadb-nc-backup.service @@ -0,0 +1,9 @@ +[Unit] +Description=MariaDB NextCloud database backup + +[Service] +Type=simple +Nice=19 +IOSchedulingClass=2 +IOSchedulingPriority=7 +ExecStart=/mnt/repo-base/scripts/mariadb-nc-backup.sh diff --git a/config/systemd/mariadb-nc-backup.timer b/config/systemd/mariadb-nc-backup.timer new file mode 100644 index 0000000000000000000000000000000000000000..d9c66bb697eec2b4f525f99862cf8541ee70f42d --- /dev/null +++ b/config/systemd/mariadb-nc-backup.timer @@ -0,0 +1,8 @@ +[Unit] +Description=Backup NextCloud database + +[Timer] +OnCalendar=*-*-* 04:00:00 + +[Install] +WantedBy=timers.target diff --git a/config/systemd/mariadb-pf-backup.service b/config/systemd/mariadb-pf-backup.service new file mode 100644 index 0000000000000000000000000000000000000000..5bdadf14d565318c008929ea3b901ecb9aba58bc --- /dev/null +++ b/config/systemd/mariadb-pf-backup.service @@ -0,0 +1,9 @@ +[Unit] +Description=MariaDB postfix database backup + +[Service] +Type=simple +Nice=19 +IOSchedulingClass=2 +IOSchedulingPriority=7 +ExecStart=/mnt/repo-base/scripts/mariadb-pf-backup.sh diff --git a/config/systemd/mariadb-pf-backup.timer b/config/systemd/mariadb-pf-backup.timer new file mode 100644 index 0000000000000000000000000000000000000000..04f41abd306aea4e055d8da1abf26492cfc644b9 --- /dev/null +++ b/config/systemd/mariadb-pf-backup.timer @@ -0,0 +1,8 @@ +[Unit] +Description=Backup Postfix database + +[Timer] +OnCalendar=*-*-* 04:30:00 + +[Install] +WantedBy=timers.target diff --git a/deployment/questionnaire/questionnaire.dat b/deployment/questionnaire/questionnaire.dat index 344c47b19f16bc2dd9ed2e379d314b23eb648f14..122027c487fd020e2c31ba8d66627ba1a42aae9f 100644 --- a/deployment/questionnaire/questionnaire.dat +++ b/deployment/questionnaire/questionnaire.dat @@ -28,6 +28,9 @@ WELCOME_SECRET=@@@generate@@@:20@ NEXTCLOUD_EMAIL_RECOVERY_APP_SECRET=@@@generate@@@:15@ +MARIADB_BACKUP_USER=backupuser;default +MARIADB_BACKUP_PASSWORD=@@@generate@@@:20@ + # fixed defaults ENABLE_POP3=false;default DISABLE_RATELIMITING=false;default @@ -36,4 +39,4 @@ DISABLE_RATELIMITING=false;default #SMTP_FROM=welcome@domainA.com #VIRTUAL_HOST (for each domain two subdomains autoconfig/autodiscover) #VHOSTS_ACCOUNTS=welcome.domainA.com -#NC_HOST_IP \ No newline at end of file +#NC_HOST_IP diff --git a/docs/SQL_backups.md b/docs/SQL_backups.md new file mode 100644 index 0000000000000000000000000000000000000000..4fdcdee6f5b7dcb28661d7843c38d3d669c1695b --- /dev/null +++ b/docs/SQL_backups.md @@ -0,0 +1,45 @@ +# Review configuration +- Check and adjust to your needs `KEEP` and `BACKUPS_PATH` in `/mnt/repo-base/scripts/mariadb-nc-backup.sh` and `/mnt/repo-base/scripts/mariadb-nc-backup.sh` + - `KEEP`: number of files to be kept at end of backup + - `BACKUPS_PATH`: backups storage (can be a mount point, i.e. a Hetzner Volume) +- Check startup time (`OnCalendar`) in `/etc/systemd/system/mariadb-nc-backup.timer` and `/etc/systemd/system/mariadb-pf-backup.timer` + - Reference: + +# Activate scheduled backups +- If you changed startup time in timer units, issue a: +```bash + systemctl daemon-reload + ``` + - Then check with: +```bash + systemctl list-timers + ``` + - Hint: if your timer are not listed, issue these commands: +```bash + systemctl enable mariadb-nc-backup.timer + systemctl enable mariadb-pf-backup.timer +``` +- Finaly, start timers with: +```bash + systemctl start mariadb-nc-backup.timer + systemctl start mariadb-pf-backup.timer +``` +- Then check with with: +```bash + systemctl status mariadb-nc-backup.timer + systemctl status mariadb-pf-backup.timer +``` + +# Review execution log +After execution (probably the day after), you can check with: +```bash + systemctl status mariadb-nc-backup.timer + systemctl status mariadb-pf-backup.timer + systemctl status mariadb-nc-backup.service + systemctl status mariadb-pf-backup.service +``` +And: +```bash +journalctl -u mariadb-*-backup.service +``` + diff --git a/scripts/base.sh b/scripts/base.sh index d79cd93ca6623b1e66e0ce9b67fdbd175b8d74d0..937a6044503c62ee6e7aca2837042a5cffe4b58f 100755 --- a/scripts/base.sh +++ b/scripts/base.sh @@ -43,3 +43,6 @@ MYSQL_ROOT_PASSWORD=$(grep ^MYSQL_ROOT_PASSWORD= "$ENVFILE" | awk -F= '{ print $ ECLOUD_ACCOUNTS_SECRET=$(grep ^ECLOUD_ACCOUNTS_SECRET= "$ENVFILE" | awk -F= '{ print $NF }') +MARIADB_BACKUP_USER=$(grep ^MARIADB_BACKUP_USER= "$ENVFILE" | awk -F= '{ print $NF }') +MARIADB_BACKUP_PASSWORD=$(grep ^MARIADB_BACKUP_PASSWORD= "$ENVFILE" | awk -F= '{ print $NF }') + diff --git a/scripts/mariadb-nc-backup.sh b/scripts/mariadb-nc-backup.sh new file mode 100644 index 0000000000000000000000000000000000000000..418d04213f4f75a8d01eb450dacd88a9f2f4d0a4 --- /dev/null +++ b/scripts/mariadb-nc-backup.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +#============================================================================== +#title :mariadb-nc-backup.sh +#description :This script will backup /e/ NextCloud database from MariaDB Docker container +#author :sylvain@murena.io +#date :20221120 +#version :1.0 +#dependances :selfhosted /e/ Cloud, pigz (option) +#usage :- shell : bash /mnt/repo-base/scripts/mariadb-nc-backup.sh +#usage :- crontab : 0 4 * * * bash /mnt/repo-base/scripts/mariadb-nc-backup.sh >> /var/log/mariadb-nc-backup.log 2>&1 +#usage :- systemd : +#usage :-- Service unit (/etc/systemd/system/mariadb-nc-backup.service) : +#usage : [Unit] +#usage : Description=Perform NextCloud MariaDB backup +#usage : [Service] +#usage : Type=simple +#usage : Nice=19 +#usage : IOSchedulingClass=2 +#usage : IOSchedulingPriority=7 +#usage : ExecStart=/mnt/repo-base/scripts/mariadb-nc-backup.sh +#usage :-- Timer unit (/etc/systemd/system/mariadb-nc-backup.timer) : +#usage : [Unit] +#usage : Description=Backup NextCloud database +#usage : [Timer] +#usage : OnCalendar=*-*-* 04:00:00 +#usage : [Install] +#usage : WantedBy=timers.target +#usage :-- commands : +#usage : systemctl start mariadb-nc-backup.timer +#usage : systemctl enable mariadb-nc-backup.timer +#usage : systemctl list-timers +#notes :https://gitlab.e.foundation/e/backlog/-/issues/4027 +#============================================================================== +set -e + +# Get all /e/ Cloud variables +source "/mnt/repo-base/scripts/base.sh" + +# Get custom variables, if any +if [[ -x "/mnt/repo-base/scripts/custom.sh" ]]; then + source "/mnt/repo-base/scripts/custom.sh" +fi + +# !! EDIT THIS LINES FOR YOUR USAGE !! + +# Vars are from base.sh script +MARIA_DB=$MYSQL_DATABASE_NC +KEEP=2 +BACKUPS_PATH="/mnt/repo-base/backups/SQL" + +# Uncomment this if you run manually or from crontab +# Useless with systemd, as outputs will go to journal +#shopt -s expand_aliases +#alias echo='echo $(date --rfc-3339=ns)' + +# !! PLEASE DO NOT EDIT PAST THIS LINE !! + +# Get current timestamp for backup file naming +NOW=$(date +"%Y-%m-%d_%s") +# This is Docker container name +MARIA_SERVICE="mariadb" +# Full backup file name with path +BACKUP_FILE="${BACKUPS_PATH}/${NOW}_${MARIA_DB}.gz" + +# Check if pigz available, fallback to gzip +if [[ $(command -v pigz) ]]; then + COMPCMD="pigz" +else + COMPCMD="gzip" +fi + +# Easier to run Docker commands from here +cd "/mnt/repo-base" + +# Test if MariaDB container/service is online +if [[ -z $(docker-compose ps --services --filter "status=running" | grep -i $MARIA_SERVICE) ]]; then + echo "KO mariadb Docker service not running, abort" + exit 1 +else + echo "OK mariadb Docker service is running" +fi + +# If OK, continue with creating target dir if necessary +mkdir -p $BACKUPS_PATH 2>/dev/null + +# Set SECONDS timer to zero, to quantify runtime +SECONDS=0 +# Then start backup +# Note : MARIADB_BACKUP_* are from base.sh script ! +docker-compose exec -T $MARIA_SERVICE mysqldump --opt --single-transaction -u$MARIADB_BACKUP_USER -p$MARIADB_BACKUP_PASSWORD $MARIA_DB |$COMPCMD >$BACKUP_FILE +# As we can't easily get the errors from previous command, easier to check the message in backup file ;) +BACKUP_RESULT=$($COMPCMD -d -c $BACKUP_FILE |tail -1 |grep -i "dump completed") +if [[ -z $BACKUP_RESULT ]]; then + echo "KO bad backup, please see output file for messages" + exit 1 +else + echo "OK backup terminated successfully" +# Check execution time, advertize pigz if relevant + if [[ ($COMPCMD == "gzip") && ($SECONDS -gt 300) ]]; then + echo "WARNING backup took more than 5mn, you may give pigz a try" + fi +# If backup successful, purge the old files (NB : command outputted to log) + echo "Deleting old backups" + find $BACKUPS_PATH -type f -iname "*_${MARIA_DB}.gz" |sort -n |head -n -$KEEP |xargs -t rm -f +fi + +# End of script diff --git a/scripts/mariadb-pf-backup.sh b/scripts/mariadb-pf-backup.sh new file mode 100644 index 0000000000000000000000000000000000000000..d72e90ae8e2bb12672a546ae24b8d9540d72abf6 --- /dev/null +++ b/scripts/mariadb-pf-backup.sh @@ -0,0 +1,107 @@ +#!/usr/bin/env bash +#============================================================================== +#title :mariadb-pf-backup.sh +#description :This script will backup /e/ Postfix database from MariaDB Docker container +#author :sylvain@murena.io +#date :20221120 +#version :1.0 +#dependances :selfhosted /e/ Cloud, pigz (option) +#usage :- shell : bash /mnt/repo-base/scripts/mariadb-pf-backup.sh +#usage :- crontab : 30 4 * * * bash /mnt/repo-base/scripts/mariadb-pf-backup.sh >> /var/log/mariadb-pf-backup.log 2>&1 +#usage :- systemd : +#usage :-- Service unit (/etc/systemd/system/mariadb-pf-backup.service) : +#usage : [Unit] +#usage : Description=Perform Postfix MariaDB backup +#usage : [Service] +#usage : Type=simple +#usage : Nice=19 +#usage : IOSchedulingClass=2 +#usage : IOSchedulingPriority=7 +#usage : ExecStart=/mnt/repo-base/scripts/mariadb-pf-backup.sh +#usage :-- Timer unit (/etc/systemd/system/mariadb-pf-backup.timer) : +#usage : [Unit] +#usage : Description=Backup Postfix database +#usage : [Timer] +#usage : OnCalendar=*-*-* 04:30:00 +#usage : [Install] +#usage : WantedBy=timers.target +#usage :-- commands : +#usage : systemctl start mariadb-pf-backup.timer +#usage : systemctl enable mariadb-pf-backup.timer +#usage : systemctl list-timers +#notes :https://gitlab.e.foundation/e/backlog/-/issues/4027 +#============================================================================== +set -e + +# Get all /e/ Cloud variables +source "/mnt/repo-base/scripts/base.sh" + +# Get custom variables, if any +if [[ -x "/mnt/repo-base/scripts/custom.sh" ]]; then + source "/mnt/repo-base/scripts/custom.sh" +fi + +# !! EDIT THIS LINES FOR YOUR USAGE !! + +# Vars are from base.sh script +MARIA_DB=$PFDB_DB +KEEP=2 +BACKUPS_PATH="/mnt/repo-base/backups/SQL" + +# Uncomment this if you run manually or from crontab +# Useless with systemd, as outputs will go to journal +#shopt -s expand_aliases +#alias echo='echo $(date --rfc-3339=ns)' + +# !! PLEASE DO NOT EDIT PAST THIS LINE !! + +# Get current timestamp for backup file naming +NOW=$(date +"%Y-%m-%d_%s") +# This is Docker container name +MARIA_SERVICE="mariadb" +# Full backup file name with path +BACKUP_FILE="${BACKUPS_PATH}/${NOW}_${MARIA_DB}.gz" + +# Check if pigz available, fallback to gzip +if [[ $(command -v pigz) ]]; then + COMPCMD="pigz" +else + COMPCMD="gzip" +fi + +# Easier to run Docker commands from here +cd "/mnt/repo-base" + +# Test if MariaDB container/service is online +if [[ -z $(docker-compose ps --services --filter "status=running" | grep -i $MARIA_SERVICE) ]]; then + echo "KO mariadb Docker service not running, abort" + exit 1 +else + echo "OK mariadb Docker service is running" +fi + +# If OK, continue with creating target dir if necessary +mkdir -p $BACKUPS_PATH 2>/dev/null + +# Set SECONDS timer to zero, to quantify runtime +SECONDS=0 +# Then start backup +# Note : MARIADB_BACKUP_* are from base.sh script ! +docker-compose exec -T $MARIA_SERVICE mysqldump --opt --single-transaction -u$MARIADB_BACKUP_USER -p$MARIADB_BACKUP_PASSWORD $MARIA_DB |$COMPCMD >$BACKUP_FILE +# As we can't easily get the errors from previous command, easier to check the message in backup file ;) +BACKUP_RESULT=$($COMPCMD -d -c $BACKUP_FILE |tail -1 |grep -i "dump completed") +if [[ -z $BACKUP_RESULT ]]; then + echo "KO bad backup, please see output file for messages" + exit 1 +else + echo "OK backup terminated successfully" +# Check execution time, advertize pigz if relevant + if [[ ($COMPCMD == "gzip") && ($SECONDS -gt 300) ]]; then + echo "WARNING backup took more than 5mn, you may give pigz a try" + fi +# If backup successful, purge the old files (NB : command outputted to log) + echo "Deleting old backups" + find $BACKUPS_PATH -type f -iname "*_${MARIA_DB}.gz" |sort -n |head -n -$KEEP |xargs -t rm -f +fi + +# End of script diff --git a/scripts/postinstall.sh b/scripts/postinstall.sh index e66e0de7fc9676dea78f8f339cd274b8923c72f1..653522efcc9af3d776c1dc28c84c93e665e4da33 100755 --- a/scripts/postinstall.sh +++ b/scripts/postinstall.sh @@ -19,6 +19,7 @@ docker-compose exec -T --user www-data nextcloud php occ maintenance:install \ --admin-email="$ALT_EMAIL" --database="mysql" --database-pass="$MYSQL_PASSWORD_NC" \ --database-name="$MYSQL_DATABASE_NC" --database-host="mariadb" --database-user="$MYSQL_USER_NC" \ --database-port="3306" --data-dir="/var/www/data" +docker-compose exec -T --user www-data nextcloud php occ maintenance:mode --off docker-compose exec -T --user www-data nextcloud php occ db:convert-filecache-bigint --no-interaction # Nextcloud resets trusted_domains to localhost during installation, so we have to set it again @@ -48,7 +49,7 @@ docker-compose exec -T --user www-data nextcloud php /var/www/html/occ app:enabl docker-compose exec -T --user www-data nextcloud php /var/www/html/occ app:enable email-recovery docker-compose exec -T --user www-data nextcloud php /var/www/html/occ app:enable ecloud-accounts docker-compose exec -T --user www-data nextcloud php /var/www/html/occ app:enable ecloud-theme-helper -docker-compose exec -T --user www-data nextcloud php /var/www/html/occ app:enable ecloud-launcher +docker-compose exec -T --user www-data nextcloud php /var/www/html/occ app:enable murena_launcher docker-compose exec -T --user www-data nextcloud php /var/www/html/occ app:disable firstrunwizard docker-compose exec -T --user www-data nextcloud php /var/www/html/occ config:app:set rainloop rainloop-autologin --value 1 docker-compose exec -T --user www-data nextcloud php /var/www/html/occ app:install tasks @@ -110,6 +111,22 @@ docker-compose exec -T welcome find /var/www/html/invite_template/ -type f -exec docker-compose exec -T welcome find /var/www/html/ -type f -name '*.html' -exec sed -i "s/e\.email/$DOMAIN/g" {} \; docker-compose exec -T welcome find /var/www/html/account_created_templates/ -type f -exec sed -i "s/ecloud\.global/$DOMAIN/g" {} \; +echo "Installing SQL backup scripts" +# Create Mariadb backup user +docker-compose exec -T mariadb mysql --user=root --password="$MYSQL_ROOT_PASSWORD" \ + -e "CREATE USER '$MARIADB_BACKUP_USER'@'localhost' IDENTIFIED BY '$MARIADB_BACKUP_PASSWORD';" +docker-compose exec -T mariadb mysql --user=root --password="$MYSQL_ROOT_PASSWORD" \ + -e "GRANT SELECT, SHOW VIEW, LOCK TABLES, RELOAD, REPLICATION CLIENT ON *.* TO '$MARIADB_BACKUP_USER'@'localhost';" +# Install systemd services & timers +cp "config/systemd/mariadb-nc-backup.service" "/etc/systemd/system/mariadb-nc-backup.service" +cp "config/systemd/mariadb-pf-backup.service" "/etc/systemd/system/mariadb-pf-backup.service" +cp "config/systemd/mariadb-nc-backup.timer" "/etc/systemd/system/mariadb-nc-backup.timer" +cp "config/systemd/mariadb-pf-backup.timer" "/etc/systemd/system/mariadb-pf-backup.timer" +systemctl daemon-reload +systemctl enable mariadb-nc-backup.timer +systemctl enable mariadb-pf-backup.timer +echo "==> please read docs/SQL_backups.md to start SQL backups" + # display DKIM DNS setup info/instructions to the user echo -e "\n\n\n" echo -e "Please add the following records to your domain's DNS configuration:\n" @@ -126,6 +143,8 @@ bash scripts/show-info.sh echo "=================================================================================================================================" echo "Your signup link:" bash scripts/generate-signup-link.sh --user-email $ALT_EMAIL +echo "=================================================================================================================================" +echo "=================================================================================================================================" echo -e "\n\n\n" echo "Please reboot the server now" diff --git a/templates/docker-compose/docker-compose.yml b/templates/docker-compose/docker-compose.yml index 384a664a83376e5bc4de4b6c13c4a17da554d466..17829c590bc0d04a0c2b79bb331bb5cd741f3c41 100644 --- a/templates/docker-compose/docker-compose.yml +++ b/templates/docker-compose/docker-compose.yml @@ -126,7 +126,7 @@ services: - "${DOMAIN}:${NC_HOST_IP}" nextcloud: - image: registry.gitlab.e.foundation/e/infra/ecloud/nextcloud/selfhost:22-2-10-11 + image: registry.gitlab.e.foundation/e/infra/ecloud/nextcloud/selfhost:23-0-11-22 container_name: nextcloud restart: always networks: diff --git a/upgrade-guides/add-SQL-backups.md b/upgrade-guides/add-SQL-backups.md new file mode 100644 index 0000000000000000000000000000000000000000..bfe06178856a1861b4aeb6a74665fac7461295d0 --- /dev/null +++ b/upgrade-guides/add-SQL-backups.md @@ -0,0 +1,33 @@ +# Put files in place +Copy `config/systemd/mariadb*` to `/etc/systemd/system/` + +# Add SQL backup user +Generate a password using: +```bash +cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 20 | head -n 1 +``` +=> the string displayed is to replace $$PASSWORD$$ in following instructions + +Edit `/mnt/repo-base/.env`, add: +``` +MARIADB_BACKUP_USER=backupuser +MARIADB_BACKUP_PASSWORD=$$PASSWORD$$ +``` + +Edit `/mnt/repo-base/scripts/base.sh`, add: +``` +MARIADB_BACKUP_USER=$(grep ^MARIADB_BACKUP_USER= "$ENVFILE" | awk -F= '{ print $NF }') +MARIADB_BACKUP_PASSWORD=$(grep ^MARIADB_BACKUP_PASSWORD= "$ENVFILE" | awk -F= '{ print $NF }') +``` + +From `/mnt/repo-base/.env`, get value for `MYSQL_ROOT_PASSWORD` +=> the value is to replace $$ROOTPASSWORD$$ in following instructions +Issue: +```bash +cd /mnt/repo-base +docker-compose exec -T mariadb mysql --user=root --password="$$ROOTPASSWORD$$" -e "CREATE USER 'backupuser'@'localhost' IDENTIFIED BY '$$PASSWORD$$';" +docker-compose exec -T mariadb mysql --user=root --password="$$ROOTPASSWORD$$" -e "GRANT SELECT, SHOW VIEW, LOCK TABLES, RELOAD, REPLICATION CLIENT ON *.* TO 'backupuser'@'localhost';" +``` + +# Enable & start backups +Please read `/mnt/repo-base/docs/SQL_backups.md` diff --git a/upgrade-guides/upgrade-to-23.0.11.22.md b/upgrade-guides/upgrade-to-23.0.11.22.md new file mode 100644 index 0000000000000000000000000000000000000000..2f187de8551300166b9ba1919b88febdc4e23cf4 --- /dev/null +++ b/upgrade-guides/upgrade-to-23.0.11.22.md @@ -0,0 +1,27 @@ +# To upgrade from ecloud 22.x.x.x to 23.0.11.22 + +- As usual, upgrade your OS with latest patchs, optionally take backup/snapshot + - NB: you may want to filter out incomming email (TCP 25 & 587) during this upgrade, to avoid losing any messages in case of a rollback + +- Go to `/mnt/repo_base`, then run: + - `docker-compose stop` + - `git pull origin master` + +- In your `docker-compose.yml` file update the following: + - Set the nextcloud image to `registry.gitlab.e.foundation/e/infra/ecloud/nextcloud/selfhost:23.0.11.22` + - Set the mailserver image to `mailserver2/mailserver:1.1.11` +- Run `docker-compose pull` +- If pulls are OK, run `docker-compose up -d` + +- Examine `docker-compose logs --tail=500 nextcloud` for the following messages: + - `nextcloud | Upgrading nextcloud from x.x.x.x ...` (x.x.x.x is your previous Nextcloud version) + - `nextcloud | Update successful` + +- Get your country code (first column) from https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2#Officially_assigned_code_elements +- Run: + - `docker-compose exec -T --user www-data nextcloud php occ config:system:set defaultapp --value="ecloud-dashboard"` + - `docker-compose exec -T --user www-data nextcloud php occ db:add-missing-indices` + - `docker-compose exec -T --user www-data nextcloud php occ config:system:set default_phone_region --value="xx"` replacing xx with your country code (ie: FR) + +- To set the new and improved dashboard as your default app, run: + - `docker-compose exec -T --user www-data nextcloud php occ app:enable ecloud-dashboard`