Back to tutorials
Tutorial

cPanel Remote Storage Setup Tutorial (2026): Ship WHM Backups to S3-Compatible Object Storage Safely

cPanel remote storage setup tutorial for WHM: connect S3-compatible storage, encrypt backups, and verify restores in 2026.

By Anurag Singh
Updated on Jul 18, 2026
Category: Tutorial
Share article
cPanel Remote Storage Setup Tutorial (2026): Ship WHM Backups to S3-Compatible Object Storage Safely

Local-only backups fail the same way every time: the disk that dies also held your backups. This cPanel remote storage setup tutorial shows how to push WHM backups to S3-compatible object storage, lock down the keys, and confirm the files you upload can actually be restored.

The goal is simple: if the server gets corrupted, encrypted, or wiped, you still have clean recovery points somewhere else.

You’ll use WHM’s built-in backup system with an S3-compatible “Additional Destination.” You’ll also add a few guardrails. These help you avoid the classic “it saved, so it must be working” trap.

What you’ll build (and what you need before you start)

This walkthrough assumes you’re on a licensed cPanel/WHM server running AlmaLinux, Rocky Linux, or Ubuntu (via supported images/partners). You’ll also need root access in WHM.

The menu names match current WHM builds commonly deployed in 2026.

  • Outcome: Nightly automated account backups stored in object storage, not on the server.
  • Remote target: S3-compatible object storage (AWS S3, Wasabi, Backblaze B2 S3, MinIO, etc.).
  • Security baseline: least-privilege access key, bucket policy restrictions, encryption at rest, and predictable retention.

If you’re still picking the platform for WHM, size the VPS for backup work, not just web traffic.

Compression and packaging can spike CPU and disk I/O, especially on a busy reseller node.

HostMyCode’s managed VPS hosting fits well if you want help with cPanel operations (updates, monitoring, and recovery support). You still keep control of accounts and billing.

Step 1: Clean up and confirm backup prerequisites in WHM

Set up remote storage after you know local backup runs are stable.

A remote destination can’t fix a backup job that fails mid-run.

  1. Check available disk space on the server. WHM still stages backups locally.

    If the staging area fills up, the upload won’t finish.

    df -h
    cd /backup && du -sh . 2>/dev/null || true

    If space is tight, address it first. HostMyCode has a practical cleanup walkthrough here: server storage cleanup on a hosting VPS.

  2. Verify backup is enabled in WHM:

    • WHM → BackupBackup Configuration
    • Set Backup Status = Enabled
    • Pick a schedule (nightly is typical)
  3. Choose a staging directory. Many admins use /backup on a separate volume.

    If you don’t have a separate disk yet, use the largest filesystem. Plan to split it later.

Step 2: Create your S3 bucket (and do it with least privilege)

Create a dedicated bucket for this WHM server.

Don’t lump it in with app uploads, logs, or “misc” storage.

Backups need clear lifecycle rules and clean access boundaries.

  • Bucket name pattern: whm-backups-yourhostname-01
  • Region: pick the closest region to your server for faster uploads
  • Object ownership: keep the backup bucket owned by your storage account

Next, create an access key that can touch only this bucket.

Limit it to the actions WHM actually needs.

If your provider supports source-IP restrictions, pin the key to your server’s public IP.

That one control sharply reduces the blast radius of a leaked key.

Example IAM policy (AWS-style) for a single backup bucket

Adjust the bucket name and, if your provider supports it, add an IP condition.

Keep this narrow on purpose.

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowListBucket",
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": "arn:aws:s3:::whm-backups-yourhostname-01"
    },
    {
      "Sid": "AllowObjectOps",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:PutObject",
        "s3:DeleteObject",
        "s3:AbortMultipartUpload",
        "s3:ListBucketMultipartUploads",
        "s3:ListMultipartUploadParts"
      ],
      "Resource": "arn:aws:s3:::whm-backups-yourhostname-01/*"
    }
  ]
}

If your object storage supports bucket versioning, enable it. It won’t replace backups.

It can still save you from accidental deletions or a misconfigured lifecycle rule.

Step 3: Add the remote destination in WHM

With the bucket ready, connect it to WHM.

  1. WHM → BackupBackup Configuration

  2. Find Additional Destinations (the label varies slightly by build) and click Create New Destination.

  3. Select S3-compatible (or Amazon S3 if you’re using AWS S3).

  4. Fill in:

    • Bucket: whm-backups-yourhostname-01
    • Access Key ID / Secret: from your IAM user
    • Endpoint: required for S3-compatible providers (for AWS, this is usually implied)
    • Path/prefix: server-01/ (use a prefix if multiple servers share a bucket)
  5. Save, then run the connection test WHM provides.

    Treat the test as mandatory.

Pitfall: “Saved successfully” only means WHM accepted the settings.

It does not prove uploads work. You still need a backup run that creates objects in the bucket.

Step 4: Force a small backup and confirm objects exist

Run a controlled test now.

Don’t wait for the overnight schedule.

  1. Pick a small cPanel account (not your biggest WordPress/WooCommerce install).

  2. Run a manual backup from WHM:

    • WHM → BackupBackup Restoration (or Backup tools depending on build)
    • Or trigger a backup from the account’s cPanel if you allow it (not recommended for all resellers)
  3. After completion, open your S3 bucket and confirm:

    • New objects appear under your prefix
    • Object sizes look plausible (not 0 bytes, not tiny placeholders)
    • Timestamps match your backup run

If nothing shows up, start with outbound connectivity and name resolution.

Many “S3 is broken” tickets come down to blocked outbound 443 or a bad resolver.

This reference is useful in a pinch: diagnose blocked ports and DNS failures.

Step 5: Set retention in two places (and avoid surprise deletions)

Retention is where people get surprised.

Two different systems can delete backups:

  • WHM retention (how many daily/weekly/monthly backups it keeps)
  • Bucket lifecycle policies (how long objects remain in object storage)

Pick one system as your “source of truth.”

Then make the other conservative.

A safe default is:

  • WHM: keep 7 daily + 4 weekly
  • Bucket lifecycle: keep for 45–90 days (longer than WHM), with versioning enabled if possible

Why this works: WHM won’t let the bucket grow forever.

The bucket also won’t quietly delete your newest recovery points because a date calculation went sideways or a job ran late.

Step 6: Encrypt backups properly (not just “S3 has encryption”)

Enable server-side encryption on the bucket.

Most providers support it, and it’s an easy baseline.

Next, decide who can read the backups.

If several staff members have console access, the bucket becomes a shared point of exposure.

Two practical options:

  • Server-side encryption (SSE): simplest; enable at bucket level. Good baseline.
  • Client-side encryption: encrypt before upload. Better separation, but more moving parts.

On reseller servers where you want tighter separation, client-side encryption can be worth the extra operational work.

If you want that separation without rolling your own scripts, HostMyCode can help you design a clean backup and restore plan on a HostMyCode VPS.

This includes who holds keys, where they live, and how restores are performed.

Step 7: Make backups restorable: run a real restore test

If you haven’t restored a backup, you don’t know you have a backup.

Test restores on a staging box, not on production.

  1. Provision a small staging VPS with cPanel/WHM for restore testing (or use a spare dedicated server partition).

    If you want help building a safe test environment, HostMyCode offers assisted moves via HostMyCode migrations.

  2. Download one backup archive from object storage.

  3. In WHM on the staging box: WHM → BackupRestore a Full Backup/cpmove File.

  4. After restore, verify:

    • Account exists and can log in to cPanel
    • Document root files present
    • Databases appear and WordPress loads
    • Email accounts exist (even if you won’t route mail here)

If the restore fails due to SSL or DNS drift, fix that separately.

Then rerun the test.

Don’t treat this as a one-off task.

Make it a quarterly drill, and keep a runbook alongside it. This pairs well with HostMyCode’s disaster recovery runbook tutorial.

Step 8: Monitoring and alerting: catch silent failures

Backup failures don’t always show up as obvious alarms.

A full disk, a rotated key, or a changed endpoint can stop uploads while WHM still appears to “run.”

Build two simple checks:

  • On-server: alert when the backup job fails or the staging directory grows unusually fast.
  • On-bucket: alert when no new objects arrive in 24 hours.

At minimum, add a daily cron check that confirms a fresh backup exists locally before transfer.

If you want broader health coverage (CPU, memory, disk, and log checks), use a basic monitoring stack like the one outlined here: server monitoring with uptime and resource alerts.

Quick diagnostics: common remote-storage backup failures (and fast fixes)

  • 403 AccessDenied

    • Wrong access key/secret
    • IAM policy missing s3:ListBucket or s3:PutObject
    • Bucket policy denies your source IP
  • Connection timeout

    • Outbound 443 blocked by firewall/CSF
    • Wrong endpoint hostname for S3-compatible storage
    • Resolver issues on the VPS
  • Uploads succeed but restores are broken

    • Backups incomplete due to local disk pressure during staging
    • Corrupted archives from interrupted jobs
    • Retention deleted needed pieces (incrementals vs full)
  • Unexpected cost spikes

    • Retention too long + large accounts
    • Multipart uploads left incomplete (ensure abort permissions)
    • Versioning without lifecycle limits

Hardening checklist for cPanel backups in object storage

  • Use a dedicated bucket per server (or a strict prefix per server).
  • Create an IAM user/key restricted to that bucket only.
  • Restrict by source IP if your provider supports it.
  • Enable bucket encryption (SSE) at minimum.
  • Set retention with a clear owner (WHM vs bucket lifecycle) and test it.
  • Run a restore test on a staging server every quarter.
  • Rotate access keys on a schedule and document the process.
  • Alert when no new backups land within your expected window.

Summary: remote storage is the difference between “backup exists” and “recovery is possible”

Once WHM ships backups off the server, you remove the biggest single point of failure.

After that, execution matters.

Use least-privilege keys, predictable retention, and restore tests that prove the archives work.

If you’re building a new reseller node or migrating accounts to a cleaner WHM setup, HostMyCode can provision the platform and help keep backups and recovery realistic.

Start with managed VPS hosting for hands-on help, or choose a self-managed HostMyCode VPS if you prefer to run WHM your way.

If you’re running WHM on a single server, remote storage is one of the highest-impact safety upgrades you can make. HostMyCode can set you up with managed VPS hosting for cPanel-friendly performance and operational support, or a flexible HostMyCode VPS if you want full admin control.

FAQ

Should I keep local backups if I’m using object storage?

Yes. If disk space allows, keep a short local window (1–3 days). Local restores are faster, and remote storage protects you from total server loss.

Do I need server-side encryption if my backups are already “internal”?

Yes. Enable bucket encryption anyway. It’s a one-time setting and reduces risk if storage media is exposed or policies change.

How often should I rotate S3 access keys used by WHM?

Rotate on a schedule that matches your risk tolerance (commonly quarterly or twice a year), and rotate immediately after staff changes. After rotation, run a manual backup to confirm uploads still work.

What’s the fastest way to verify uploads are happening?

Check the bucket for new objects with timestamps from the last run. Pair that with an alert if no new objects arrive in 24 hours.

Can I store backups for multiple WHM servers in one bucket?

You can, but use a separate prefix per server and separate credentials per server. That way, one leaked key can’t delete everyone’s backups.