{"id":3433,"date":"2025-12-26T18:49:40","date_gmt":"2025-12-26T15:49:40","guid":{"rendered":"https:\/\/www.dchost.com\/blog\/automating-off-site-backups-to-object-storage-with-rclone-restic-and-cron\/"},"modified":"2025-12-26T18:49:40","modified_gmt":"2025-12-26T15:49:40","slug":"automating-off-site-backups-to-object-storage-with-rclone-restic-and-cron","status":"publish","type":"post","link":"https:\/\/www.dchost.com\/blog\/en\/automating-off-site-backups-to-object-storage-with-rclone-restic-and-cron\/","title":{"rendered":"Automating Off\u2011Site Backups to Object Storage with rclone, restic and Cron"},"content":{"rendered":"<div class=\"dchost-blog-content-wrapper\"><p>Off\u2011site backups to S3\u2011compatible object storage are one of the most cost\u2011effective ways to protect cPanel and <a href=\"https:\/\/www.dchost.com\/vps\">VPS<\/a> workloads. Instead of relying only on local disks or a single data center, you can send encrypted, deduplicated backups to remote object storage automatically every night. In this article we will walk through a practical, battle\u2011tested setup using three tools that work beautifully together: <strong>rclone<\/strong> (sync to S3\u2011compatible storage), <strong>restic<\/strong> (encrypted, deduplicated backups) and <strong>Cron<\/strong> (scheduling). We will focus on real Linux servers and cPanel environments like the ones we manage every day at dchost.com, and we will keep everything provider\u2011neutral so you can use any S3\u2011compatible platform or your own MinIO cluster on a VPS or <a href=\"https:\/\/www.dchost.com\/dedicated-server\">dedicated server<\/a>.<\/p>\n<p>If you already understand why backups are important, your next question is usually: <em>\u201cHow do I automate this in a clean, testable way so I can forget about it until I really need it?\u201d<\/em> That is exactly what we will cover: what to back up on cPanel\/VPS, how to structure your object storage buckets, how to configure rclone and restic securely, how to schedule jobs with Cron, and how to test restores so you know the whole chain really works.<\/p>\n<div id=\"toc_container\" class=\"toc_transparent no_bullets\"><p class=\"toc_title\">\u0130&ccedil;indekiler<\/p><ul class=\"toc_list\"><li><a href=\"#Why_OffSite_Backups_to_Object_Storage_Matter\"><span class=\"toc_number toc_depth_1\">1<\/span> Why Off\u2011Site Backups to Object Storage Matter<\/a><\/li><li><a href=\"#Architecture_cPanelVPS_Object_Storage_rclone_restic_Cron\"><span class=\"toc_number toc_depth_1\">2<\/span> Architecture: cPanel\/VPS + Object Storage + rclone + restic + Cron<\/a><\/li><li><a href=\"#Preparing_Your_Object_Storage_Target\"><span class=\"toc_number toc_depth_1\">3<\/span> Preparing Your Object Storage Target<\/a><\/li><li><a href=\"#Installing_and_Configuring_rclone_for_S3Compatible_Storage\"><span class=\"toc_number toc_depth_1\">4<\/span> Installing and Configuring rclone for S3\u2011Compatible Storage<\/a><ul><li><a href=\"#Install_rclone_on_a_Linux_VPS_or_cPanel_server\"><span class=\"toc_number toc_depth_2\">4.1<\/span> Install rclone on a Linux VPS or cPanel server<\/a><\/li><li><a href=\"#Configure_an_S3_remote_in_rclone\"><span class=\"toc_number toc_depth_2\">4.2<\/span> Configure an S3 remote in rclone<\/a><\/li><\/ul><\/li><li><a href=\"#Setting_Up_Restic_Repositories_for_Encrypted_Deduplicated_Backups\"><span class=\"toc_number toc_depth_1\">5<\/span> Setting Up Restic Repositories for Encrypted, Deduplicated Backups<\/a><ul><li><a href=\"#Install_restic\"><span class=\"toc_number toc_depth_2\">5.1<\/span> Install restic<\/a><\/li><li><a href=\"#Environment_variables_for_restic_S3\"><span class=\"toc_number toc_depth_2\">5.2<\/span> Environment variables for restic + S3<\/a><\/li><li><a href=\"#Initialize_the_restic_repository\"><span class=\"toc_number toc_depth_2\">5.3<\/span> Initialize the restic repository<\/a><\/li><\/ul><\/li><li><a href=\"#Example_Backup_Flow_for_a_cPanel_Server\"><span class=\"toc_number toc_depth_1\">6<\/span> Example Backup Flow for a cPanel Server<\/a><ul><li><a href=\"#1_Enable_and_tune_native_cPanel_backups\"><span class=\"toc_number toc_depth_2\">6.1<\/span> 1. Enable and tune native cPanel backups<\/a><\/li><li><a href=\"#2_rclone_script_to_sync_cPanel_backups_to_object_storage\"><span class=\"toc_number toc_depth_2\">6.2<\/span> 2. rclone script to sync cPanel backups to object storage<\/a><\/li><li><a href=\"#3_Optional_restic_layer_for_deduplicated_history\"><span class=\"toc_number toc_depth_2\">6.3<\/span> 3. Optional: restic layer for deduplicated history<\/a><\/li><\/ul><\/li><li><a href=\"#Example_Backup_Flow_for_a_Generic_VPS_Without_cPanel\"><span class=\"toc_number toc_depth_1\">7<\/span> Example Backup Flow for a Generic VPS (Without cPanel)<\/a><ul><li><a href=\"#1_Define_what_to_back_up\"><span class=\"toc_number toc_depth_2\">7.1<\/span> 1. Define what to back up<\/a><\/li><li><a href=\"#2_Example_MySQL_dump_restic\"><span class=\"toc_number toc_depth_2\">7.2<\/span> 2. Example: MySQL dump + restic<\/a><\/li><\/ul><\/li><li><a href=\"#Scheduling_and_Monitoring_with_Cron\"><span class=\"toc_number toc_depth_1\">8<\/span> Scheduling and Monitoring with Cron<\/a><ul><li><a href=\"#Scheduling_on_a_generic_Linux_VPS\"><span class=\"toc_number toc_depth_2\">8.1<\/span> Scheduling on a generic Linux VPS<\/a><\/li><li><a href=\"#Scheduling_from_cPanelWHM\"><span class=\"toc_number toc_depth_2\">8.2<\/span> Scheduling from cPanel\/WHM<\/a><\/li><\/ul><\/li><li><a href=\"#Testing_Restores_Dont_Wait_for_an_Incident\"><span class=\"toc_number toc_depth_1\">9<\/span> Testing Restores: Don\u2019t Wait for an Incident<\/a><ul><li><a href=\"#Testing_restic_restores\"><span class=\"toc_number toc_depth_2\">9.1<\/span> Testing restic restores<\/a><\/li><li><a href=\"#Testing_cPanel_restores\"><span class=\"toc_number toc_depth_2\">9.2<\/span> Testing cPanel restores<\/a><\/li><\/ul><\/li><li><a href=\"#Hardening_Cost_Control_and_Practical_Tips\"><span class=\"toc_number toc_depth_1\">10<\/span> Hardening, Cost Control and Practical Tips<\/a><ul><li><a href=\"#1_Protect_credentials_and_limit_access\"><span class=\"toc_number toc_depth_2\">10.1<\/span> 1. Protect credentials and limit access<\/a><\/li><li><a href=\"#2_Use_encryption_correctly\"><span class=\"toc_number toc_depth_2\">10.2<\/span> 2. Use encryption correctly<\/a><\/li><li><a href=\"#3_Exclude_junk_and_temporary_data\"><span class=\"toc_number toc_depth_2\">10.3<\/span> 3. Exclude junk and temporary data<\/a><\/li><li><a href=\"#4_Watch_bandwidth_and_storage_costs\"><span class=\"toc_number toc_depth_2\">10.4<\/span> 4. Watch bandwidth and storage costs<\/a><\/li><li><a href=\"#5_Integrate_with_monitoring_and_runbooks\"><span class=\"toc_number toc_depth_2\">10.5<\/span> 5. Integrate with monitoring and runbooks<\/a><\/li><\/ul><\/li><li><a href=\"#Bringing_It_All_Together_on_dchostcom_Infrastructure\"><span class=\"toc_number toc_depth_1\">11<\/span> Bringing It All Together on dchost.com Infrastructure<\/a><\/li><\/ul><\/div>\n<h2><span id=\"Why_OffSite_Backups_to_Object_Storage_Matter\">Why Off\u2011Site Backups to Object Storage Matter<\/span><\/h2>\n<p>Modern backup strategy is no longer just \u201ccopy files to another folder\u201d. Between ransomware, accidental deletions, hardware failures and region\u2011wide incidents, you need a design that survives <strong>multiple failure modes<\/strong>. The classic pattern for this is the <strong>3\u20112\u20111 backup strategy<\/strong>: three copies of your data, on two different media, with one copy off\u2011site. If this sounds new to you, we recommend reading our detailed guide <a href=\"https:\/\/www.dchost.com\/blog\/en\/3-2-1-yedekleme-stratejisi-neden-ise-yariyor-cpanel-plesk-ve-vpste-otomatik-yedekleri-nasil-kurarsin\/\">explaining the 3\u20112\u20111 backup strategy and how to automate it on cPanel and VPS<\/a>.<\/p>\n<p>S3\u2011compatible <strong>object storage<\/strong> is a perfect fit for the off\u2011site part of 3\u20112\u20111:<\/p>\n<ul>\n<li><strong>Durable and replicated<\/strong>: objects are typically stored redundantly across multiple disks and sometimes across multiple availability zones.<\/li>\n<li><strong>Pay for what you use<\/strong>: you pay per GB stored and per GB transferred, which works well for growing backup sets.<\/li>\n<li><strong>API\u2011driven<\/strong>: tools like rclone and restic speak the S3 API natively, so automation is straightforward.<\/li>\n<li><strong>Geographically decoupled<\/strong>: you can store backups in a different data center or even a different country for stronger disaster recovery.<\/li>\n<\/ul>\n<p>If you want a broader comparison of storage types, we also have a detailed article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/object-storage-vs-block-storage-vs-file-storage-web-uygulamalari-ve-yedekler-icin-dogru-secim\/\">Object Storage vs Block Storage vs File Storage and which one to choose for web apps and backups<\/a>.<\/p>\n<h2><span id=\"Architecture_cPanelVPS_Object_Storage_rclone_restic_Cron\">Architecture: cPanel\/VPS + Object Storage + rclone + restic + Cron<\/span><\/h2>\n<p>Before writing any scripts, it helps to be clear on the overall architecture. For a typical cPanel or generic Linux VPS server, a clean design looks like this:<\/p>\n<ul>\n<li><strong>Source server<\/strong>: cPanel server or unmanaged VPS where your sites, databases and emails live.<\/li>\n<li><strong>Local backup staging<\/strong>: a directory on the same server (for example <code>\/backup<\/code> or <code>\/var\/backups<\/code>) where we generate daily backups or cPanel account archives.<\/li>\n<li><strong>restic repository<\/strong>: an encrypted backup repository stored directly in S3\u2011compatible object storage (or optionally on local disk, then synced with rclone).<\/li>\n<li><strong>rclone remote<\/strong>: a configured connection to your S3\u2011compatible storage endpoint.<\/li>\n<li><strong>Cron jobs<\/strong>: scheduled tasks that run backup scripts (files + databases) and send them to the restic repository via S3.<\/li>\n<\/ul>\n<p>There are two main patterns you can combine:<\/p>\n<ol>\n<li><strong>cPanel built\u2011in backups + rclone<\/strong><br \/>Use cPanel\/WHM&#039;s native backup system to produce compressed account backups under <code>\/backup<\/code>, then use rclone to sync those archives to object storage.<\/li>\n<li><strong>restic directly to S3\u2011compatible storage<\/strong><br \/>Use restic to back up specific directories (for example <code>\/home<\/code>, <code>\/var\/lib\/mysql<\/code> dumps, <code>\/etc<\/code>) directly to an S3 backend with encryption and deduplication.<\/li>\n<\/ol>\n<p>In practice, many teams do both: they preserve <strong>native cPanel restore points<\/strong> and also maintain a <strong>restic repository<\/strong> for quick granular restores. Our other article <a href=\"https:\/\/www.dchost.com\/blog\/en\/restic-ve-borg-ile-s3-uyumlu-uzak-yedekleme-surumleme-sifreleme-ve-saklama-ne-zaman-nasil\/\">on off\u2011site backups with restic\/Borg to S3\u2011compatible storage<\/a> goes deeper into the theory; here we will focus more on concrete scripts for cPanel\/VPS.<\/p>\n<h2><span id=\"Preparing_Your_Object_Storage_Target\">Preparing Your Object Storage Target<\/span><\/h2>\n<p>First, you need an S3\u2011compatible object storage endpoint and credentials. This could be:<\/p>\n<ul>\n<li>A third\u2011party S3\u2011compatible object storage service.<\/li>\n<li>Your own <strong>MinIO cluster<\/strong> or single\u2011node deployment on a VPS or dedicated server from dchost.com (see our guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-uzerinde-minio-ile-s3%e2%80%91uyumlu-depolama-nasil-uretim%e2%80%91hazir-kurulur-erasure-coding-tls-ve-policyleri-tatli-tatli-anlatiyorum\/\">running production\u2011ready MinIO on a VPS<\/a>).<\/li>\n<\/ul>\n<p>Create a dedicated <strong>bucket<\/strong> for backups, for example:<\/p>\n<ul>\n<li>Bucket name: <code>company-backups<\/code><\/li>\n<li>Optional folder structure inside the bucket:<br \/>\n    <code>company-backups\/cpanel\/hostname\/...<\/code><br \/>\n    <code>company-backups\/vps\/app1\/...<\/code><\/li>\n<\/ul>\n<p>Then create an <strong>access key<\/strong> and <strong>secret key<\/strong> for a user that has permissions restricted to that bucket only (least privilege). Keep these credentials safe; we will store them in a root\u2011only configuration file or in environment variables on the server.<\/p>\n<h2><span id=\"Installing_and_Configuring_rclone_for_S3Compatible_Storage\">Installing and Configuring rclone for S3\u2011Compatible Storage<\/span><\/h2>\n<p><strong>rclone<\/strong> is a versatile command\u2011line tool that can sync files and directories to many cloud backends, including any S3\u2011compatible service.<\/p>\n<h3><span id=\"Install_rclone_on_a_Linux_VPS_or_cPanel_server\">Install rclone on a Linux VPS or cPanel server<\/span><\/h3>\n<p>On most distributions, you can either use the package manager or the installer script. For example on Debian\/Ubuntu:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo apt update\nsudo apt install rclone\n<\/code><\/pre>\n<p>On AlmaLinux\/Rocky\/other RHEL derivatives:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo dnf install rclone\n<\/code><\/pre>\n<p>If your repository versions are too old, you can use the official install script:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">curl -fsSL https:\/\/rclone.org\/install.sh | sudo bash\n<\/code><\/pre>\n<h3><span id=\"Configure_an_S3_remote_in_rclone\">Configure an S3 remote in rclone<\/span><\/h3>\n<p>Run the configuration wizard as root:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo rclone config\n<\/code><\/pre>\n<p>Follow the interactive prompts:<\/p>\n<ol>\n<li>Choose <code>n<\/code> for a new remote.<\/li>\n<li>Name it, for example <code>backup-s3<\/code>.<\/li>\n<li>Storage type: select <code>s3<\/code>.<\/li>\n<li>Provider: choose <code>Other<\/code> (for generic S3\u2011compatible) unless your provider is listed specifically.<\/li>\n<li>Enter your S3 endpoint URL (for example <code>https:\/\/objects.example.com<\/code>).<\/li>\n<li>Region: set according to your provider, or leave blank if not required.<\/li>\n<li>Enter your access key ID and secret access key.<\/li>\n<li>For advanced S3 options like ACLs or storage classes, you can accept defaults initially.<\/li>\n<\/ol>\n<p>When done, test the configuration:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo rclone ls backup-s3:company-backups\n<\/code><\/pre>\n<p>If the bucket is empty, you may see nothing, but you should not see an error.<\/p>\n<h2><span id=\"Setting_Up_Restic_Repositories_for_Encrypted_Deduplicated_Backups\">Setting Up Restic Repositories for Encrypted, Deduplicated Backups<\/span><\/h2>\n<p><strong>restic<\/strong> is a modern backup program that offers encrypted, incremental, deduplicated backups and can store data directly in S3\u2011compatible object storage.<\/p>\n<h3><span id=\"Install_restic\">Install restic<\/span><\/h3>\n<p>On Debian\/Ubuntu:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo apt update\nsudo apt install restic\n<\/code><\/pre>\n<p>On RHEL\u2011based systems, you may install from EPEL or download a binary from the restic releases page:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">curl -L -o restic.bz2 https:\/\/github.com\/restic\/restic\/releases\/download\/v0.16.4\/restic_0.16.4_linux_amd64.bz2\nbunzip2 restic.bz2\nchmod +x restic\nsudo mv restic \/usr\/local\/bin\/\n<\/code><\/pre>\n<h3><span id=\"Environment_variables_for_restic_S3\">Environment variables for restic + S3<\/span><\/h3>\n<p>We normally keep restic settings in a root\u2011only file such as <code>\/root\/.restic-env<\/code> and load it in our backup scripts. Example:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">export RESTIC_REPOSITORY=&quot;s3:https:\/\/objects.example.com\/company-backups\/vps-app1&quot;\nexport RESTIC_PASSWORD=&quot;super-strong-long-random-password&quot;\nexport AWS_ACCESS_KEY_ID=&quot;YOUR_ACCESS_KEY_ID&quot;\nexport AWS_SECRET_ACCESS_KEY=&quot;YOUR_SECRET_KEY&quot;\n<\/code><\/pre>\n<p>Secure the file:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo chown root:root \/root\/.restic-env\nsudo chmod 600 \/root\/.restic-env\n<\/code><\/pre>\n<h3><span id=\"Initialize_the_restic_repository\">Initialize the restic repository<\/span><\/h3>\n<p>Once the environment variables are set, initialize the repository:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">source \/root\/.restic-env\nrestic init\n<\/code><\/pre>\n<p>You should see a confirmation that the repository has been initialized in the bucket path. This creates the encrypted structure that restic will use for snapshots, deduplication and metadata.<\/p>\n<h2><span id=\"Example_Backup_Flow_for_a_cPanel_Server\">Example Backup Flow for a cPanel Server<\/span><\/h2>\n<p>On cPanel\/WHM, you usually want two layers:<\/p>\n<ul>\n<li>cPanel&#039;s <strong>native backups<\/strong> (account\u2011level archives for easy full account restores).<\/li>\n<li>Optionally, a <strong>restic layer<\/strong> for deduplicated, long\u2011retention backups across many days or weeks.<\/li>\n<\/ul>\n<h3><span id=\"1_Enable_and_tune_native_cPanel_backups\">1. Enable and tune native cPanel backups<\/span><\/h3>\n<p>In WHM, go to <strong>Backup Configuration<\/strong> and:<\/p>\n<ul>\n<li>Enable backups.<\/li>\n<li>Choose compressed or incremental backups.<\/li>\n<li>Set the backup directory (often <code>\/backup<\/code> on a separate disk).<\/li>\n<li>Decide how many daily\/weekly\/monthly copies to retain locally.<\/li>\n<\/ul>\n<p>If you want a detailed walkthrough of cPanel backup options, see our <a href=\"https:\/\/www.dchost.com\/blog\/en\/cpanelde-tum-siteyi-yedekleme-ve-geri-yukleme-rehberi\/\">Full cPanel Backup and Restore guide<\/a>.<\/p>\n<h3><span id=\"2_rclone_script_to_sync_cPanel_backups_to_object_storage\">2. rclone script to sync cPanel backups to object storage<\/span><\/h3>\n<p>Create a script such as <code>\/root\/backup-cpanel-rclone.sh<\/code>:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">#!\/usr\/bin\/env bash\nset -euo pipefail\n\nBACKUP_SRC=&quot;\/backup&quot;              # cPanel backup directory\nREMOTE=&quot;backup-s3:company-backups\/cpanel\/$(hostname -f)&quot;\nLOG_FILE=&quot;\/var\/log\/backup-cpanel-rclone.log&quot;\n\n{\n  echo &quot;[$(date -Is)] Starting cPanel backup upload...&quot;\n\n  # Sync local backup directory to S3-compatible storage\n  rclone sync &quot;${BACKUP_SRC}&quot; &quot;${REMOTE}&quot; \n    --fast-list \n    --transfers=4 \n    --checkers=8 \n    --delete-excluded\n\n  echo &quot;[$(date -Is)] Upload completed successfully.&quot;\n} &gt;&gt; &quot;${LOG_FILE}&quot; 2&gt;&amp;1\n<\/code><\/pre>\n<p>Make it executable:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo chmod +x \/root\/backup-cpanel-rclone.sh\n<\/code><\/pre>\n<p>Now you have a simple, repeatable way to upload all generated cPanel backup archives to the remote object storage bucket.<\/p>\n<h3><span id=\"3_Optional_restic_layer_for_deduplicated_history\">3. Optional: restic layer for deduplicated history<\/span><\/h3>\n<p>If you want more efficient long\u2011term history (for example dozens of daily snapshots) without keeping all old cPanel tarballs, add restic on top. Create <code>\/root\/.restic-env<\/code> for this server:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">export RESTIC_REPOSITORY=&quot;s3:https:\/\/objects.example.com\/company-backups\/restic-cpanel-$(hostname -s)&quot;\nexport RESTIC_PASSWORD=&quot;another-very-strong-random-password&quot;\nexport AWS_ACCESS_KEY_ID=&quot;YOUR_ACCESS_KEY_ID&quot;\nexport AWS_SECRET_ACCESS_KEY=&quot;YOUR_SECRET_KEY&quot;\n<\/code><\/pre>\n<p>Initialize once:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">source \/root\/.restic-env\nrestic init\n<\/code><\/pre>\n<p>Create <code>\/root\/backup-cpanel-restic.sh<\/code>:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">#!\/usr\/bin\/env bash\nset -euo pipefail\n\nsource \/root\/.restic-env\n\nLOG_FILE=&quot;\/var\/log\/backup-cpanel-restic.log&quot;\n\n{\n  echo &quot;[$(date -Is)] Starting restic backup of critical paths...&quot;\n\n  restic backup \n    \/home \n    \/etc \n    \/var\/named \n    \/var\/lib\/mysql-backups \n    --exclude-caches \n    --one-file-system\n\n  echo &quot;[$(date -Is)] Backup finished. Running retention policy...&quot;\n\n  restic forget \n    --keep-daily 7 \n    --keep-weekly 4 \n    --keep-monthly 6 \n    --prune\n\n  echo &quot;[$(date -Is)] Retention completed.&quot;\n} &gt;&gt; &quot;${LOG_FILE}&quot; 2&gt;&amp;1\n<\/code><\/pre>\n<p>This assumes you have a separate process (for example a MySQL dump cron job) that keeps recent database dumps in <code>\/var\/lib\/mysql-backups<\/code>. Adjust paths to your environment.<\/p>\n<h2><span id=\"Example_Backup_Flow_for_a_Generic_VPS_Without_cPanel\">Example Backup Flow for a Generic VPS (Without cPanel)<\/span><\/h2>\n<p>On an unmanaged VPS (for example hosting a Laravel or Node.js app), you usually control everything via SSH. Here is a simple, flexible pattern that we also use internally.<\/p>\n<h3><span id=\"1_Define_what_to_back_up\">1. Define what to back up<\/span><\/h3>\n<p>For a typical Linux VPS running web applications, you want:<\/p>\n<ul>\n<li><strong>Application code and uploads<\/strong>: for example <code>\/var\/www<\/code> or <code>\/opt\/apps<\/code>.<\/li>\n<li><strong>Databases<\/strong>: MySQL\/MariaDB, PostgreSQL, etc. Usually via logical dumps or snapshot tools.<\/li>\n<li><strong>Configuration<\/strong>: <code>\/etc<\/code> (web server, PHP\u2011FPM, system config).<\/li>\n<li><strong>Optional logs<\/strong>: at least for short retention, if you need to investigate incidents.<\/li>\n<\/ul>\n<p>We have a separate article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/mysql-veritabani-yedekleme-stratejileri-mysqldump-percona-xtrabackup-ve-snapshot-nasil-secilir\/\">MySQL backup strategies (mysqldump vs XtraBackup vs snapshots)<\/a> if you want to design your database backup layer in more detail.<\/p>\n<h3><span id=\"2_Example_MySQL_dump_restic\">2. Example: MySQL dump + restic<\/span><\/h3>\n<p>Create a dump directory and a simple script, for example <code>\/root\/mysql-dump.sh<\/code>:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">#!\/usr\/bin\/env bash\nset -euo pipefail\n\nBACKUP_DIR=&quot;\/var\/backups\/mysql&quot;\nmkdir -p &quot;${BACKUP_DIR}&quot;\n\nDATE=&quot;$(date +%F_%H-%M-%S)&quot;\n\nmysqldump --all-databases --single-transaction --routines --events \n  | gzip &gt; &quot;${BACKUP_DIR}\/mysqldump-${DATE}.sql.gz&quot;\n\n# Optional: delete local dumps older than 7 days\nfind &quot;${BACKUP_DIR}&quot; -type f -mtime +7 -delete\n<\/code><\/pre>\n<p>Make it executable:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo chmod +x \/root\/mysql-dump.sh\n<\/code><\/pre>\n<p>Next, define restic environment <code>\/root\/.restic-env<\/code> (if you haven&#039;t already):<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">export RESTIC_REPOSITORY=&quot;s3:https:\/\/objects.example.com\/company-backups\/vps-app1-restic&quot;\nexport RESTIC_PASSWORD=&quot;super-long-random-password&quot;\nexport AWS_ACCESS_KEY_ID=&quot;YOUR_ACCESS_KEY_ID&quot;\nexport AWS_SECRET_ACCESS_KEY=&quot;YOUR_SECRET_KEY&quot;\n<\/code><\/pre>\n<p>Initialize once:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">source \/root\/.restic-env\nrestic init\n<\/code><\/pre>\n<p>Now create the main VPS backup script <code>\/root\/backup-vps-restic.sh<\/code>:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">#!\/usr\/bin\/env bash\nset -euo pipefail\n\nsource \/root\/.restic-env\n\nLOG_FILE=&quot;\/var\/log\/backup-vps-restic.log&quot;\n\n{\n  echo &quot;[$(date -Is)] Starting VPS backup...&quot;\n\n  # 1) Ensure fresh MySQL dump\n  \/root\/mysql-dump.sh\n\n  # 2) Run restic backup\n  restic backup \n    \/var\/www \n    \/etc \n    \/var\/backups\/mysql \n    --exclude-caches \n    --one-file-system\n\n  echo &quot;[$(date -Is)] Backup completed. Running retention policy...&quot;\n\n  restic forget \n    --keep-daily 7 \n    --keep-weekly 4 \n    --keep-monthly 6 \n    --prune\n\n  echo &quot;[$(date -Is)] Retention finished.&quot;\n} &gt;&gt; &quot;${LOG_FILE}&quot; 2&gt;&amp;1\n<\/code><\/pre>\n<p>Make it executable:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo chmod +x \/root\/backup-vps-restic.sh\n<\/code><\/pre>\n<h2><span id=\"Scheduling_and_Monitoring_with_Cron\">Scheduling and Monitoring with Cron<\/span><\/h2>\n<p>Once your scripts work when run manually, the next step is automation with <strong>Cron<\/strong>. We have a separate guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/cpanel-ve-directadminde-otomatik-gorevler-planlama-cron-job-ile-yedek-rapor-ve-bakim-isleri\/\">automating backups, reports and maintenance with Cron on cPanel and DirectAdmin<\/a>, but we will highlight the essentials here.<\/p>\n<h3><span id=\"Scheduling_on_a_generic_Linux_VPS\">Scheduling on a generic Linux VPS<\/span><\/h3>\n<p>Edit the root user&#039;s crontab:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">sudo crontab -e\n<\/code><\/pre>\n<p>Example schedule:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\"># m  h  dom mon dow   command\n# Daily VPS backup at 02:30\n30 2 * * * \/root\/backup-vps-restic.sh\n\n# Daily cPanel backup upload at 03:30 (if using cPanel pattern)\n30 3 * * * \/root\/backup-cpanel-rclone.sh\n\n# Daily cPanel restic backup at 04:00\n0 4 * * * \/root\/backup-cpanel-restic.sh\n<\/code><\/pre>\n<p>Cron will email the output to the root account if there are errors (assuming local email is configured). In addition, you can:<\/p>\n<ul>\n<li>Monitor log files under <code>\/var\/log\/backup-*.log<\/code>.<\/li>\n<li>Push log metrics into your existing monitoring stack (for example Prometheus + alerting), similar to what we describe in our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/vps-izleme-ve-uyari-nasil-kurulur-prometheus-grafana-ve-node-exporter-ile-sessiz-alarmlari-konusturmak\/\">VPS monitoring and alerts with Prometheus and Grafana<\/a>.<\/li>\n<\/ul>\n<h3><span id=\"Scheduling_from_cPanelWHM\">Scheduling from cPanel\/WHM<\/span><\/h3>\n<p>On cPanel servers, you can also schedule scripts using:<\/p>\n<ul>\n<li><strong>WHM &rarr; Cron Jobs<\/strong> for server\u2011wide tasks.<\/li>\n<li><strong>cPanel &rarr; Cron Jobs<\/strong> for per\u2011account tasks (less relevant for system\u2011wide backups).<\/li>\n<\/ul>\n<p>The commands will be the same (<code>\/root\/backup-cpanel-rclone.sh<\/code> etc.), but you manage them through WHM&#039;s UI instead of <code>crontab -e<\/code>.<\/p>\n<h2><span id=\"Testing_Restores_Dont_Wait_for_an_Incident\">Testing Restores: Don\u2019t Wait for an Incident<\/span><\/h2>\n<p>A backup that has never been restored is an assumption, not a guarantee. We strongly recommend including <strong>regular restore tests<\/strong> in your maintenance schedule. This is also a key part of any serious disaster recovery plan; if you are designing one, our guide on <a href=\"https:\/\/www.dchost.com\/blog\/en\/felaket-kurtarma-plani-nasil-yazilir-rto-rpoyu-kafada-netlestirip-yedek-testleri-ve-runbooklari-gercekten-calisir-hale-getirmek\/\">how to write a disaster recovery (DR) plan with realistic RPO\/RTO and backup tests<\/a> may help.<\/p>\n<h3><span id=\"Testing_restic_restores\">Testing restic restores<\/span><\/h3>\n<p>List snapshots:<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">source \/root\/.restic-env\nrestic snapshots\n<\/code><\/pre>\n<p>Restore a specific directory to a temporary path (never overwrite live data blindly):<\/p>\n<pre class=\"language-bash line-numbers\"><code class=\"language-bash\">mkdir -p \/tmp\/restic-restore-test\nrestic restore latest --target \/tmp\/restic-restore-test\n<\/code><\/pre>\n<p>Check that files, permissions and timestamps look reasonable. For database dumps, run a test import into a temporary database on a non\u2011production server.<\/p>\n<h3><span id=\"Testing_cPanel_restores\">Testing cPanel restores<\/span><\/h3>\n<p>For cPanel native backups:<\/p>\n<ul>\n<li>Download a backup archive from object storage using rclone if necessary.<\/li>\n<li>Use WHM&#039;s <strong>Restore a Full Backup\/cpmove File<\/strong> to restore into a test account or test server.<\/li>\n<\/ul>\n<p>This validates that your backup archives are complete and that all required settings (DNS zones, SSL, databases, email accounts) are properly preserved.<\/p>\n<h2><span id=\"Hardening_Cost_Control_and_Practical_Tips\">Hardening, Cost Control and Practical Tips<\/span><\/h2>\n<p>A few real\u2011world lessons from running this kind of setup across many servers:<\/p>\n<h3><span id=\"1_Protect_credentials_and_limit_access\">1. Protect credentials and limit access<\/span><\/h3>\n<ul>\n<li>Store S3 access keys in root\u2011owned files with <code>chmod 600<\/code>, never in world\u2011readable scripts.<\/li>\n<li>Create a dedicated S3 user with <strong>bucket\u2011scoped permissions<\/strong> (no access to other buckets or admin APIs).<\/li>\n<li>Rotate access keys periodically and test after rotation.<\/li>\n<\/ul>\n<h3><span id=\"2_Use_encryption_correctly\">2. Use encryption correctly<\/span><\/h3>\n<ul>\n<li>restic encrypts all data by default; keep the <code>RESTIC_PASSWORD<\/code> safe (ideally in a separate password manager).<\/li>\n<li>If you use rclone without restic, consider rclone&#039;s <code>crypt<\/code> backend to encrypt data client\u2011side before sending to object storage.<\/li>\n<li>Some object storage platforms also support <strong>object lock<\/strong> and WORM (Write\u2011Once Read\u2011Many) for ransomware protection; we cover this in depth in <a href=\"https:\/\/www.dchost.com\/blog\/en\/s3-object-lock-ile-fidye-yazilima-karsi-kale-gibi-yedek-versioning-mfa-delete-ve-geri-donus-testlerini-samimi-samimi-konusalim\/\">our guide to ransomware\u2011proof backups with S3 Object Lock<\/a>.<\/li>\n<\/ul>\n<h3><span id=\"3_Exclude_junk_and_temporary_data\">3. Exclude junk and temporary data<\/span><\/h3>\n<p>Backups are not a trash bag for everything on the disk. Excluding some paths improves speed and reduces costs:<\/p>\n<ul>\n<li>Cache directories (for example <code>storage\/framework\/cache<\/code> in Laravel, <code>wp-content\/cache<\/code> in WordPress).<\/li>\n<li>System caches under <code>\/var\/cache<\/code> that can be rebuilt.<\/li>\n<li>Big application logs if you already centralize logs elsewhere (for example Loki\/ELK stack).<\/li>\n<\/ul>\n<p>Add <code>--exclude<\/code> rules or a file like <code>--exclude-file=\/root\/backup-excludes.txt<\/code> in restic to manage this cleanly.<\/p>\n<h3><span id=\"4_Watch_bandwidth_and_storage_costs\">4. Watch bandwidth and storage costs<\/span><\/h3>\n<ul>\n<li>Try to run backups during off\u2011peak hours to reduce impact on production traffic.<\/li>\n<li>restic deduplication significantly reduces storage usage, especially when many files change little between days.<\/li>\n<li>Use a retention policy (for example keep 7 daily, 4 weekly, 6 monthly) that fits your legal and business needs. Our article on <a href=\"https:\/\/www.dchost.com\/blog\/en\/yedek-saklama-suresi-nasil-belirlenir-kvkk-gdpr-ve-maliyet-dengesi\/\">how to decide backup retention periods under KVKK\/GDPR vs real storage costs<\/a> is a good companion here.<\/li>\n<\/ul>\n<h3><span id=\"5_Integrate_with_monitoring_and_runbooks\">5. Integrate with monitoring and runbooks<\/span><\/h3>\n<ul>\n<li>Add simple sanity checks: for example, after each backup, record the snapshot ID or last backup date in a small status file.<\/li>\n<li>Use your monitoring system to alert if backups haven&#039;t run in N hours or if last backup failed.<\/li>\n<li>Document a clear <strong>restore runbook<\/strong> so that anyone on the team can restore a site, database or whole server under pressure.<\/li>\n<\/ul>\n<h2><span id=\"Bringing_It_All_Together_on_dchostcom_Infrastructure\">Bringing It All Together on dchost.com Infrastructure<\/span><\/h2>\n<p>When we design backup strategies for customers on dchost.com VPS, dedicated servers or colocation, the pattern above is the one we keep coming back to: <strong>local snapshots + off\u2011site encrypted copies on S3\u2011compatible storage, automated with rclone, restic and Cron<\/strong>. It is simple enough to understand, but flexible enough to handle everything from a single WordPress site to complex multi\u2011app stacks. Most importantly, it is easy to test and to restore.<\/p>\n<p>If you are starting from scratch, your practical next steps are:<\/p>\n<ol>\n<li>Choose or deploy an S3\u2011compatible object storage backend and create a dedicated backup bucket.<\/li>\n<li>Install and configure rclone and restic on your cPanel\/VPS servers.<\/li>\n<li>Write minimal backup scripts that you can run manually and verify.<\/li>\n<li>Add Cron schedules and basic monitoring for success\/failure.<\/li>\n<li>Plan and rehearse at least one restore scenario (single site, full server, or critical database).<\/li>\n<\/ol>\n<p>As your environment grows, you can refine retention, add cross\u2011region replication or object lock, and integrate backup metrics into your wider observability stack. The foundation, however, stays the same: clear scope, simple scripts, reliable automation and regular restore tests. If your servers run on dchost.com infrastructure and you want to validate your backup plan or move to an object\u2011storage\u2011based design, our team is happy to help you map these concepts to your actual workloads.<\/p>\n<\/div>","protected":false},"excerpt":{"rendered":"<p>Off\u2011site backups to S3\u2011compatible object storage are one of the most cost\u2011effective ways to protect cPanel and VPS workloads. Instead of relying only on local disks or a single data center, you can send encrypted, deduplicated backups to remote object storage automatically every night. In this article we will walk through a practical, battle\u2011tested setup [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3434,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-3433","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-teknoloji"],"_links":{"self":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/3433","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/comments?post=3433"}],"version-history":[{"count":0,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/posts\/3433\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media\/3434"}],"wp:attachment":[{"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/media?parent=3433"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/categories?post=3433"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.dchost.com\/blog\/en\/wp-json\/wp\/v2\/tags?post=3433"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}