Backup Management¶
enconf creates incremental, deduplicated and encrypted backups — stored locally, on S3-compatible storage, or via FTP. Backups can be scheduled or triggered manually and restored at any time. Running jobs remain visible across page navigation.
Overview¶
Backup management is split into three tabs:
| Tab | Contents |
|---|---|
| Schedules | Create, edit and activate backup schedules |
| History | All executed and running backup and restore jobs |
| Restore | Select, browse and restore a snapshot — or delete a snapshot manually (danger confirm; removes one specific snapshot regardless of retention) |
Active Tasks Banner¶
Whenever at least one backup or restore job is running, a blue banner appears above the tabs. It is visible on all tabs and refreshes every 5 seconds.
The banner shows for each running job: - Type (Backup / Restore) - Schedule name and scope - Status (Running / Pending) - Start time
Completed jobs are automatically reflected in the History tab.
Server-Wide vs. Per-Customer Backups¶
As an admin you can choose between two modes:
| Mode | When to use | Repository path |
|---|---|---|
| Entire server | Recommended default. A single schedule backs up all customers (web roots, databases, mail vhosts, SSL certificates) into one shared backup repository. No customer picker. | <bucket>/<path>/server |
| Single customer | Only when a specific customer needs separate retention, target, or credentials. | <bucket>/<path>/<customer_id> |
Customers only ever see their own per-customer schedules. Server-wide schedules are admin-only.
Migrating existing schedules
Existing per-customer schedules continue to work unchanged. There is no automatic migration. To switch to server-wide mode, create a new server-wide schedule and disable the old per-customer ones.
Known limitation
In Entire server mode the config scope is not applied because the agent currently requires a single linux user for that scope. For server-wide backups use scopes full, web, db, mail, or ssl.
Schedules¶
Create Schedule¶
- Click New Schedule
- Fill in the form:
| Field | Required | Description |
|---|---|---|
| Name | Yes | Schedule name |
| Backup type | Yes (Admin) | Customer data (default), Panel/System, or Node — see the note below |
| Backup scope | Yes (Admin) | Entire server (default) or Single customer |
| Customer | When Single customer | Customer assignment — only shown when backup scope is Single customer |
| Scope | Yes | full, web, db, mail, ssl, or config |
| Frequency | Yes | hourly, daily, weekly, or monthly |
| Hour | No | Hour of execution in the time zone of the panel server (0–23) |
| Day of Week | For weekly | Day of the week |
| Day of Month | For monthly | Day of the month (1–28) |
| Retention | Yes | Number of snapshots to keep |
| Target | Yes | Local, S3 (recommended), SFTP, or FTP |
| S3 Endpoint | No | Custom S3 endpoint (empty = use global setting) |
| S3 Access Key | No | Custom access key (empty = use global setting) |
| S3 Secret Key | No | Custom secret key (empty = use global setting) |
- Click Create
Save Encryption Key
After creating a schedule, an individual encryption key is generated. Click the key icon in the schedule table to view it. Save this key externally (password manager, USB drive, safe) — without it, backups cannot be restored.
Only one local target per customer
A customer can have one customer-specific schedule with the Local target — the local backup repository lives at a fixed per-customer path and is shared (each schedule has its own encryption key). For a second schedule for the same customer, choose a different target (S3, SFTP, or FTP). Trying to create a second local target is rejected with a clear message.
Backup types: Customer data, Panel/System, Node
- Customer data backs up customers' web roots, databases, mail, and SSL.
- Panel/System backs up the panel host including the panel database (customers, subscriptions, site metadata) and system configuration.
This schedule is created automatically (daily 04:00 server time, 14 snapshots, target = the default backup target) the first time the panel runs — also on existing installs after the update; the first run is the next 04:00, never immediately. It is created once: if you delete or deactivate it, it does not come back — the Security Advisor then reports under "Panel state backup" that it is missing, with the consequence (after a total loss the data would be there but no accounts) and a button to create it again. The check also shows the date of the last successful run and warns when the run is overdue, when the target is this server itself (does not survive a total loss), or when the repository key has never been shown — without it the backup cannot be opened after a total loss. The automatic creation can be switched off with the panel setting panel_state_backup_auto = off.
- Node backs up the role-specific system configuration of a remote server (web/db/mail/dns) — without the panel database — for multi-server disaster recovery. The Node type is only offered when remote nodes are actually attached; on a single-server install it is hidden.
Managing the Encryption Key¶
Showing it needs your password — and is logged
This key decrypts every snapshot of the schedule. Showing it and replacing it therefore require re-entering your password — every time, not once per session: an open session alone is not enough. Every read is written to the audit log (who, when, which schedule). While impersonating a customer the key is not reachable; end the impersonation and use the admin route, so the entry names the person who acted.
The key dialog offers four actions:
| Action | Description |
|---|---|
| Copy | Copy the key to the clipboard |
| Download as file | Save the key as netcell-backup-key-<id>.txt |
| Replace key | Import an externally saved key — e.g. to keep using an existing backup repository from another panel installation |
| Close | Close the dialog |
Warning when replacing
Replacing the key makes all previous backups of this schedule unreadable with the new key — the data stays at the destination but cannot be restored, and that cannot be undone. Only use this function to restore access to an existing external repository (S3 or FTP) after reinstalling the panel.
If snapshots already exist, the panel names how many beforehand and only saves once you type that number — so the consequence cannot be clicked away unread. With no snapshots there is nothing to lose; the password alone is enough then.
Deleting a plan no longer loses the key
When a backup plan is deleted its repository stays at the storage target — the snapshots leave the view but keep taking up space. The key moves into the key store (Backup page, admin only): a new plan for the same target adopts it automatically and can read the existing snapshots again. That was not the case before — the key existed only in the plan's row, so a new plan met its own data with a key nobody had.
The store never shows a key, only what it opens. An entry leaves it only through Forget (password again, logged) — there is deliberately no deadline. After that the repository is closed for good, for us too. Repositories whose plan was deleted before this store existed stay unreadable.
Migrating to a new panel:
- On the old panel: key icon → Download as file
- On the new panel: create a backup schedule with the identical target (S3/FTP, bucket, path)
- Key icon → Replace key → paste the contents of the downloaded file
- Snapshots will then be listed again and can be restored
Emptying the Key Store¶
For entries in the key store that are not assigned to any schedule anymore, two actions are available with different reach:
| Action | What happens |
|---|---|
| Forget | Deletes only the entry from the panel database. The data at the storage target (snapshots, restic config) is left untouched — it keeps taking up space, but is no longer readable without the key. |
| Empty Completely | Also deletes the repository data directly at the storage target (local, S3, SFTP or FTP), and only then the entry in the store. This actually frees the occupied storage space. |
Empty Completely is irreversible
As with replacing a key, the panel first requires you to type the exact number of remaining snapshots, plus your password again. Deletion follows a fixed order — for all four targets (local, S3, SFTP, FTP) the restic config is removed last: an abort midway must never leave a later attempt believing the repository is gone while pack data still sits at the target (an orphaned remnant). Every call is recorded in the audit log.
Customer-supplied credentials (HasOwnTarget)
If the original schedule did not store its own S3/SFTP/FTP credentials, the panel resolves the connection automatically from the global backup settings (Settings → Backup). If the schedule had its own credentials (customer-supplied storage), the dialog asks for them again — they are not stored permanently or logged for this, only used for the single delete operation. This is irrelevant for local repositories.
If an Object Lock is active on the S3 target, Empty Completely fails with a corresponding error — the data remains until the retention period expires.
Custom S3 Storage¶
Customers can configure their own S3-compatible storage (e.g., AWS S3, Wasabi, MinIO, Hetzner Object Storage). S3 endpoint, access key, and secret key are configured directly on the schedule.
| Setting | Description |
|---|---|
| S3 Endpoint | URL of the S3-compatible service (e.g., https://s3.eu-central-1.amazonaws.com) |
| S3 Access Key | Access key for the S3 service |
| S3 Secret Key | Secret key (stored encrypted) |
| S3 Bucket | Name of the S3 bucket |
| S3 Path | Path within the bucket |
If fields are left empty, the global S3 settings from the admin are used (configured under Settings → Backup).
Permission: Custom Backup Storage
The ability to provide custom S3/FTP credentials can be restricted per package via the Custom Backup Storage (S3/FTP) permission. This permission is disabled by default.
Scope¶
| Value | What is backed up |
|---|---|
| full | Web files + databases + mail + SSL + configuration |
| web | Web files only (webspace) |
| db | Databases only (MariaDB) |
| Email mailboxes only (Maildir + Sieve) | |
| ssl | SSL certificates only |
| config | Nginx and PHP-FPM configuration |
Storage Targets¶
Local (Server)¶
Backups are stored in the local backup repository on the server.
Local Backups
Local backups do not protect against disk failure. Combine local backups with an external target.
S3 / S3-compatible — recommended¶
S3 is the recommended target
S3 (and S3-compatible services) write backups directly from the server, with no local staging — the most robust off-site target. In the schedule dialog S3 is marked (recommended).
| Field | Description |
|---|---|
| S3 Bucket | Bucket name |
| S3 Path | Subdirectory within the bucket (optional) |
S3 credentials (endpoint, region, access key, secret key) are configured under Settings → Backup.
SFTP (SSH)¶
SFTP uses restic's native SFTP backend over SSH — it writes directly to the target, with no local staging, and authenticates with a key (no password).
| Field | Description |
|---|---|
| SFTP Host | Server address |
| SFTP Port | Default: 22 |
| SFTP User | Username |
| Target path | Target directory on the SFTP server |
When you pick SFTP, the panel shows the agent's public key (copyable). Add it once to the SFTP target user's ~/.ssh/authorized_keys — the agent then authenticates without a password. A keepalive configuration detects dead connections and aborts quickly instead of hanging.
FTP¶
FTP is staged locally
FTP backups are created locally first on the server and then mirrored to the FTP target with lftp. This requires enough free disk space on the server — it's checked before every run, and if there isn't enough the backup aborts and reports it (the admin is notified). S3 and SFTP write directly and are preferred.
| Field | Description |
|---|---|
| FTP Host | Server address |
| FTP Port | Default: 21 |
| FTP User | Username |
| FTP Password | Password |
| FTP Path | Target directory on the FTP server |
| Encryption | FTPS explicit (recommended) / implicit / plaintext |
The local repository is the source of truth; the FTP target is a mirror of it. On the first run an existing FTP repository is downloaded once and then continued incrementally — switching to this scheme is lossless. If an existing FTP repository cannot be staged locally, the run aborts rather than overwriting the existing backups.
Network storage (NFS/CIFS)¶
Alternatively, the local backup path can be placed on an NFS or CIFS/SMB share (under Settings → Backup → Network storage). Both local and FTP-staged backups then land on the network storage. The mount is persisted as a systemd unit and survives reboots; the required client packages (nfs-common or cifs-utils) are installed by the agent on demand, and write access is verified during setup.
Connection Test¶
Click Test Connection to verify the storage target is reachable before saving the schedule:
| Storage target | Test method |
|---|---|
| S3 | restic init against the target — checks credentials, bucket access and write permission |
| SFTP | restic init over SSH — checks key authentication, reachability and write permission |
| FTP | lftp login + directory creation — checks auth, TLS, path and write permission |
| Local | Creates a test directory — checks write permission at the given path |
Test before saving
Always test the connection before creating a schedule, to avoid failed backups caused by wrong credentials.
Retention & Pruning¶
Retention sets how many snapshots to keep. This count is enforced after every backup — snapshots beyond the limit are dropped from the list right away.
Reclaiming the disk space those dropped snapshots occupied (a prune) is a separate, much heavier operation. To keep backups fast, enconf runs it in the background and at most once per week per repository, so a backup finishes the moment its snapshot is written and is never delayed by pruning — even on slow storage such as FTP. A backup run that is interrupted can no longer wedge a schedule: stale repository locks are cleared automatically on the next run.
Deleting a single snapshot is instant
Deleting a snapshot from the Restore tab removes it from the list immediately; the freed space is reclaimed by the next scheduled prune. There is no longer a multi-minute wait for the delete to complete.
Slow FTP targets — bounding the prune
On FTP the prune's pack-repacking is network-bound and can be slow, so it is capped per run and catches up across weekly runs (fully-unreferenced data is always freed in full immediately). The cap defaults to 64M for FTP targets and is unbounded for S3/local. Override it per install with BACKUP_PRUNE_MAX_REPACK in /etc/enconf/agent.env (e.g. BACKUP_PRUNE_MAX_REPACK=256M, or unlimited to disable the cap), then restart the agent.
Stuck runs¶
A run whose target stopped answering is ended by the agent so the repository does not stay locked. Progress is only what restic itself reports (files and bytes processed) — not how many bytes cross the wire, because a pack that is sent again looks like work from the outside.
- Files are still being read: if the counters stand still for 10 minutes, the run is ended.
- All files read, the last packs still going out: the counters stand still by design here. The run may take up to 45 minutes for this. If restic reports repeated retries meanwhile, it is ended earlier.
- SFTP targets: this protocol has no per-request time limit, restic never reports retries for it. Usually ssh ends the run earlier through its keep-alives (88 seconds on a test system). Whether and when that happens depends on the ssh configuration (
ServerAliveInterval/ServerAliveCountMax) and the far end; the time budgets are the fallback for when ssh notices nothing — a target that goes silent is then recognized after 10 or 45 minutes. - FTP targets: The transfer steps run through lftp, not restic, and provide neither counters nor retry messages. lftp recognizes a dead target itself (30 seconds of silence, three attempts): on a test system a silent target ended after about three minutes, a target that accepts an upload and never acknowledges it after about two minutes (one measurement per run; the second values vary by about ten seconds). A target that transfers extremely slowly but steadily runs until the absolute ceiling of 12 hours per run instead, because FTP offers no progress signal that could tell "too slow" from "slow". If you do not want that, set
ENCONF_BACKUP_MAX_HOURS(1–48) in/etc/enconf/agent.envto a smaller value and restart the agent.
An ended run shows as failed in the history and is tried again in the next period.
Enable / Disable Schedule¶
Disabled schedules are not executed automatically but can still be triggered manually.
Edit Schedule¶
- Click the Edit icon
- Adjust the settings
- Click Save
Delete Schedule¶
- Click the Delete icon
- Confirm the deletion
Snapshots Are Preserved
Deleting a schedule does not remove the snapshots already stored at the target.
Manual Backup¶
Any schedule can be triggered immediately:
- Click the green Run now button in the actions column of the desired schedule
- The backup job starts immediately and appears in the active tasks banner
Run All: Click Run All (top right) to trigger all active schedules simultaneously.
History (Job Table)¶
The History tab shows all executed and running backup and restore jobs.
Columns¶
| Column | Description |
|---|---|
| Started | Start time (e.g. "Today, 3:00 AM"), with duration and data size below |
| Schedule | Schedule name with colored scope tag; restore type shown additionally for restores |
| Status | Color-coded status label |
| Snapshot | Short snapshot ID (backups only, large screens only) |
| (Detail button) | Opens the detail view |
Tip: Clicking a row also opens the detail view.
Status Indicators¶
| Status | Color | Meaning |
|---|---|---|
| Pending | Gray | Waiting to run |
| Running | Blue (animated) | Currently executing |
| Success | Green | Completed successfully |
| Failed | Red | Failed |
Job Type¶
| Icon | Color | Meaning |
|---|---|---|
| ↑ Cloud | Blue | Backup |
| ↩ Arrow | Orange | Restore |
Detail View¶
Click a row or the info button to open the detail view. It shows:
- Type and Status as colored tags
- Schedule, start time, end time, duration, data size, snapshot ID
- Execution log — dark terminal window with detailed statistics:
- For backups: new files, changed files, unmodified files, data transferred, total duration
- For restores: files restored, files skipped, bytes, elapsed time
- Error message (for failed jobs)
No Log for Failed Jobs
The execution log is only available for successfully completed jobs. For failures, a red error message is shown instead.
Delete Old Entries¶
Click Delete old entries above the table to remove completed and failed jobs older than 30 days.
Snapshots and Restore¶
View Snapshots¶
- Switch to the Restore tab
- Select a schedule from the dropdown
- Click Load Snapshots
- Available restore points are displayed
| Column | Description |
|---|---|
| Created | Creation time (e.g. "Today, 2:23 PM") |
| Contains | Content tags based on backup scope |
| Actions | Restore, Browse files |
Browse Files¶
- Click Browse Files next to the snapshot
- Navigate through the snapshot's directory structure
- Click Restore next to any file to selectively restore that file
Start Restore¶
- Click Restore next to the desired snapshot
- Select what to restore using the card interface:
| Option | Description |
|---|---|
| Restore everything | All data from the backup (full scope only) |
| Web files | Website files & directories |
| Databases | All databases & tables |
| Email data | Emails & mailbox data |
| SSL certificates | SSL certificates & keys |
| Configuration | Nginx, PHP-FPM configuration |
| Single file | Targeted file path |
Available options depend on the schedule's scope.
- Confirm the restore
Overwrite
A restore overwrites the current data with the snapshot state. Create a manual backup of the current state beforehand.
The restore runs asynchronously in the background. Progress is visible in the active tasks banner and, once completed, in the History tab.
Backup Settings¶
Global backup settings are configured under Settings → Backup:
| Setting | Description |
|---|---|
| S3 Endpoint | URL of the S3 service (e.g. https://s3.amazonaws.com) |
| S3 Region | AWS region |
| S3 Access Key | Access key |
| S3 Secret Key | Secret key |
| Backup Enabled | Global on/off switch |
| Default Retention | Default number of snapshots to keep |
Global SFTP and FTP credentials can also be stored here; schedules use them as a fallback when they don't specify their own target.
Network storage (NFS/CIFS)¶
Under Settings → Backup → Network storage, the local backup path can be placed on a network share:
| Field | Description |
|---|---|
| Type | None (local disk), NFS, or CIFS/SMB |
| Server | Address of the NFS/CIFS server |
| Export path / Share name | NFS export (e.g. /exports/backups) or CIFS share |
| User / Password | CIFS only — credentials (stored encrypted, written to a root-only credentials file) |
| Additional mount options | Optional, comma-separated |
Save & Mount sets up the mount, verifies write access, and persists it as a systemd unit (survives reboots). Unmount detaches the share. The current status is shown while a network storage is active.
Prefer S3
Network storage and FTP stage backups locally first. For a direct, resilient off-site target, prefer S3 (or SFTP).
Note on restores performed before version 2.10.10¶
In versions before 2.10.10, a full restore could bring back an older database state than the one selected. The reason: every restore wrote its dump files into a temporary directory and never cleaned it up. A later restore read every directory still present, and whatever came last is what ended up in the database. The job reported success either way.
That same lookup was not limited to the customer being restored. If dump files from another customer's restore were still on the server, they could be imported as well.
Both are fixed in 2.10.10: a restore uses only the files of the chosen snapshot, in its own directory, cleans up afterwards, and removes leftover directories from earlier runs at start-up.
What to check if you restored before 2.10.10:
- Does the data in the affected databases match the point in time you meant to restore? An older state is the more likely outcome.
- Do the databases contain tables or rows that do not belong to this website?
- When in doubt, run the restore again on 2.10.10 — it now delivers exactly the state you pick.
Only restores were affected, not the backups themselves. The snapshots in your repositories are unchanged and complete.