Preface
Because I previously deployed a primary WordPress site and a backup site in my home data center, set up a mirror site on a cloud server, and successfully achieved real-time backup and rapid recovery of multiple WordPress configurations through the scheduled backup of the WordPress WPvivid backup plugin and the scheduled synchronization function of Syncthing (see article:Docker Series: Detailed Tutorial on Implementing Multi-Point Folder Synchronization Based on Syncthing Using Docker和Docker Series: Using Docker to Set Up a Blog Slave Site Based on WordPress and Implement Regular Backups of Master-Slave Site Configurations). However, due to an issue with my home broadband a few days ago (a non-natural failure, the dispute is still ongoing, I'll talk about it when there is a result), after I switched WordPress to the mirror site, I realized that the image host was still at home (unreachable during a network outage)~~. Therefore, just implementing redundancy for WordPress was not enough; the image host also needed redundancy. So, I spent some more time creating redundancy for the Chevereto image host on the mirror site as well, and only then was the blog fully restored.
As a result, I thought I might as well include Chevereto in the multi-point synchronization plan to achieve the same topology as the WordPress site: primary image host, backup image host, and mirror site image host. When data is added to the primary image host, the backup and mirror site image hosts can also sync and add data (ultimately, it's just because I'm lazy and wanted to get it done in one go~), which is why this article exists.
Chevereto consists of the program itself and its corresponding ”database” in the database. Images are stored in the program'sdata/imagesdirectory. There is a database in the database system used by Chevereto. Therefore, to achieve data synchronization, both the synchronization of Chevereto program data and the database must be implemented. Thus, it is divided into two steps: synchronization of Chevereto's own data (mainly images) and synchronization of its corresponding database.
Synchronization of Chevereto's own data
Note: This step relies on Syncthing to synchronize multiple Chevereto-related folders (for specific configuration details of Syncthing multi-point synchronization, please refer to my other article:Docker Series: Detailed Tutorial on Implementing Multi-Point Folder Synchronization Based on Syncthing Using Docker, this article will not cover the detailed configuration process too much, mainly because there is just too much to cover~~).
Depending on the deployment method of Chevereto (source code deployment or Docker deployment), this step may vary. However, the core concept is to add the Chevereto directory as a synchronized folder in Syncthing, and then synchronize it across multiple Chevereto nodes via Syncthing. Since I deployed Chevereto using Docker, this article will use files from this method as an example.
Since the planning of my primary, backup, and mirror image hosting nodes overlaps with the WordPress planning, Syncthing uses the Mac Mini node as the primary image hosting node (sync source), and then synchronizes to the Intermini node (backup site) and Tencent Cloud server (mirror site) nodes. Follow these steps:
- Redeploy the syncthing-macmini Docker container, using the -v parameter to map the corresponding Chevereto folder on the Mac Mini to the corresponding path in Syncthing. Here, I mapped it to the /data2 directory:

Perform the same operations on the syncthing-intermini and syncthing-tc nodes.
Note: At this point, the Docker version of Chevereto has not yet been deployed on these two nodes. You can first create the corresponding folders for Docker (make sure the folder permissions are writable) to solve the Chevereto data synchronization issue first; Docker can be deployed later.
- On syncthing-macmini, add data2 to the shared folders, and then share it with syncthing-intermini and syncthing-tc. After that, accept the sharing requests from syncthing-macmini on syncthing-intermini and syncthing-tc respectively, and complete the addition. The final sharing effect is as follows:



At this point, the data that the Docker version of Chevereto needs to mount inside the container has been successfully synchronized from the syncthing-macmini node to the other two nodes.
Note: Regarding the folder type, select on syncthing-macmini:

On the other two nodes, select:

Scheduled export of the Chevereto database
In my MariaDB, the database corresponding to Chevereto is named ”chevereto”:

There are three critical questions here: where to export, how to export, and how often to export.
Where to export
This problem is actually easy to solve, which is to use the directory mounted by the Chevereto container on the host machine. Because in the previous Syncthing configuration, the files in this directory are synchronized in real-time, the best way is to create a "db" subdirectory inside it, and then export the Chevereto database directly as a SQL file into this folder:

The final path is:
/Volumes/data/docker/chevereto/db #/Volumes/data是macos从Catalina版本以后的写法,这里不深究,大家根据自己的实际环境修改即可。
How to export
Exporting the Chevereto database from MariaDB is very simple, just use the mysqldump command. Combined with the path from the previous section, the command is as follows:
docker exec -u root 你的数据库容器名 mysqldump -uroot -p你的数据库密码 --databases 数据库中chevereto对应的库名字 > /Volumes/data/docker/chevereto/db/chevereto.sql #导出路径根据你的实际情况进行修改,只要是在前面配置的chevereto的同步目录下就行。注意mysqldump后面的-u和-p直接填用户名和密码,不要留空格
How often to export
This depends on everyone's different needs. For me, keeping it consistent with the synchronization cycle of WordPress automatic backup is fine, so let's set it to one week. But how to achieve automatic export once a week? This varies depending on the environment everyone uses. For example, macOS already has methods for setting up scheduled tasks (launchctl and crontab; theoretically, launchctl is better), but I don't want to hassle with it. So to be lazy, I directly put the command from the previous section into an executable script ”export_cheve_database.sh” under a specific directory in macOS, placed it in the macOS user directory, and then used the scheduled tasks of the aaPanel to log in via SSH periodically to execute it:


Note: To use this method of SSHing to a remote device to run a script, you need to configure the SSH client of the device where aaPanel is located for public key login to the macmini in advance (you can refer to my other article:Debian Series: Configuring SSH Public Key Login), but some details differ across different systems. For example, macOS has an extra step:
ssh-add ~/.ssh/id_rsa
The content of the ”export_cheve_database.sh” script on the macmini is as follows:
#!/bin/sh
# 手动加载环境变量,这个非常重要,默认不会加载。另外不同系统环境变量文件名不一样,需注意。
source ~/.bash_profile
# 执行导出chevereto库命令,导出的路径就在设置的chevereto同步目录下,这样一来导出了库之后就会被实时同步到chevereto的备用节点和镜像节点的对应目录中
docker exec -u root 你的数据库容器名或者容器id mysqldump -uroot -pyourpassword --databases chevereto > /Volumes/data/docker/chevereto/db/chevereto.sql
# 运行完成
echo 'end'
Scheduled import of the database on synchronized Chevereto nodes
Database import for Chevereto nodes
**Item 8:**
Original:
2、在mariadb容器的挂载目录(/docker/mariadb/db)内新建脚本文件”chevereto_import.sh”,内容如下:
Translation:
#!/bin/sh
mysql -uroot -pyourpassword chevereto < /var/lib/mysql/chevereto.sql
**Item 9:**Original:1TP/docker/mariadb/dbdirectory.
Give execution permissions to "chevereto_import.sh":
chmod +x /var/lib/mysql/chevereto_import.sh
Run the command on the host machine to execute
docker exec -u root 你的数据库容器名称 /var/lib/mysql/chevereto_import.sh
Implementing scheduled automatic import
If you want to run the above process automatically on a schedule, you only need to create a script on the host machine (don't forget to grant permissions) with the following content:
#!/bin/sh
docker exec -u root mariadb01 mysql -u root -pp@ssw0rd -e "DROP TABLE IF EXISTS chv_albums, chv_confirmations, chv_deletions, chv_follows, chv_images, chv_importing, chv_imports, chv_ip_bans, chv_likes, chv_locks, chv_logins, chv_notifications, chv_pages, chv_queues, chv_redirects, chv_requests, chv_settings, chv_stats, chv_storage_apis, chv_storages, chv_users, chv_categories;" chevereto #清除chevereto库中所有的表。
cp /docker/chevereto/db/chevereto.sql /docker/mariadb/db/01/chevereto.sql
docker exec -u root mariadb01 /var/lib/mysql/chevereto_import.sh
docker exec -u root mariadb01 mysql -u root -pp@ssw0rd -e "DROP TABLE IF EXISTS chv_albums, chv_confirmations, chv_deletions, chv_follows, chv_images, chv_importing, chv_imports, chv_ip_bans, chv_likes, chv_locks, chv_logins, chv_notifications, chv_pages, chv_queues, chv_redirects, chv_requests, chv_settings, chv_stats, chv_storage_apis, chv_storages, chv_users, chv_categories;" chevereto # Clear all tables in the chevereto database.
cp /docker/chevereto/db/chevereto.sql /docker/mariadb/db/01/chevereto.sql
docker exec -u root mariadb01 /var/lib/mysql/chevereto_import.sh


Then just run the script on a schedule.Docker Series: Using Docker to Build Your Own Image Hosting Service Based on Chevereto)。
Note: The first command is to clear the existing tables in the chevereto database. This is very important, otherwise the subsequent import will not succeed. Of course, you can also directly delete the chevereto database.
Afterword
I won't go into detail about how to run scripts on a schedule, as different systems have different methods. However, I can still be a bit lazy because I have installed the Baota Panel on both the backup site and the mirror site, so I still use the scheduled tasks feature:
And we're done! Then, you only need to use the same commands as the main site (mainly referring to the -v parameter to mount the correct synchronized folder) on the backup site and mirror site to create the chevereto container (and the database parameters at these nodes are the same, meaning they can use the same address or name, port, root password, etc.), and chevereto will work normally right away (for the detailed setup process of the chevereto image hosting, please refer to another article:
After all the tweaking above, the image hosting has now achieved a multi-level redundancy structure of “main site + backup site + mirror site”. Combined with the identical WordPress multi-level redundancy structure I have already implemented, I am no longer afraid of the two most painful problems of home data centers: the main site going down (macmini bricked/dying) and power/internet outages at home. This is because there are cloud server WordPress and image hosting mirror sites, and the image hosting can also guarantee the latest data within 7 days (the images themselves are automatically synchronized; this mainly refers to the frequency of database imports, which can be adjusted according to your needs). From a professional perspective, I have currently implemented application hot standby within the home data center as well as an active-active/disaster recovery site in the same city. According to the "three centers in two locations" specification, I am still short of an "off-site disaster recovery" site. I plan to implement this using hexo + github + cloudflare pages, but it can only be for the blog text part. After all, it is hosted on cloudflare pages and will be online forever. Off-site disaster recovery for the image hosting is a bit tricky, let me think about it.
But thinking about it this way, my previous WordPress multi-point data synchronization and rapid recovery solution relied on the WPvivid backup plugin and still required manual intervention, which is quite low-tech. After the trial of Chevereto multi-point automatic synchronization, WordPress should be able to achieve the same effect. Once I finish writing the article about Google Ads, I will look into fully automatic multi-point synchronization for WordPress.