Documentation Index
Fetch the complete documentation index at: https://mintlify.com/caddyserver/caddy/llms.txt
Use this file to discover all available pages before exploring further.
The caddy storage command provides subcommands for working with Caddy’s storage, allowing you to export and import storage contents like TLS certificates and ACME data.
EXPERIMENTAL: This command may be changed or removed in future versions.
Usage
caddy storage <subcommand> [flags]
Description
Allows exporting and importing Caddy’s storage contents. The storage contains:
- TLS certificates (from ACME or loaded files)
- ACME account data (account keys, registration info)
- ACME challenge data (for DNS and other challenges)
- OCSP staples and other TLS-related data
This is useful for:
- Migrating between storage backends
- Backing up certificates and keys
- Transferring data between servers
- Switching storage configurations
When importing to or exporting from file_system storage (the default), the command should be run as the user that owns the associated root path.
Subcommands
export
Exports storage assets as a tarball.
caddy storage export --config <path> --output <path>
import
Imports storage assets from a tarball.
caddy storage import --config <path> --input <path>
Combining Export and Import
The two commands can be combined in a pipeline to transfer directly from one storage to another:
caddy storage export --config Caddyfile.old --output - | \
caddy storage import --config Caddyfile.new --input -
The - argument refers to stdout and stdin, respectively.
Export Flags
Input configuration file (required).The storage configuration will be extracted from this config.
Output path for the tarball (required).Use - for stdout (useful for piping).
Import Flags
Configuration file to load (required).The storage configuration will be extracted from this config.
Path to tarball to import (required).Use - for stdin (useful for piping).
Examples
Export to file
caddy storage export --config Caddyfile --output backup.tar
Creates backup.tar containing all storage assets.
Import from file
caddy storage import --config Caddyfile --input backup.tar
Restores storage assets from backup.tar.
Export to stdout
caddy storage export --config Caddyfile --output -
Writes tarball to stdout (useful for piping or compression).
Import from stdin
cat backup.tar | caddy storage import --config Caddyfile --input -
Compress backup
caddy storage export --config Caddyfile --output - | gzip > backup.tar.gz
Restore from compressed backup
gunzip -c backup.tar.gz | caddy storage import --config Caddyfile --input -
Transfer between servers
# On source server
caddy storage export --config Caddyfile --output - | \
ssh user@destination 'caddy storage import --config /etc/caddy/Caddyfile --input -'
Migrate storage backends
Old config using file storage:
# Caddyfile.old
{
storage file_system {
root /var/lib/caddy/old
}
}
New config using different storage:
# Caddyfile.new
{
storage file_system {
root /var/lib/caddy/new
}
}
Migrate:
caddy storage export --config Caddyfile.old --output - | \
caddy storage import --config Caddyfile.new --input -
Backup before upgrade
# Create backup
caddy storage export --config /etc/caddy/Caddyfile --output ~/caddy-backup-$(date +%Y%m%d).tar
# Upgrade Caddy
sudo apt update && sudo apt upgrade caddy
# If something goes wrong, restore
# caddy storage import --config /etc/caddy/Caddyfile --input ~/caddy-backup-YYYYMMDD.tar
Exit Codes
0 - Success
1 - Failed startup (invalid config or missing flags)
2 - Failed quit (error during export/import)
What Gets Exported
The export includes all “terminal” keys from the storage:
- Certificates -
certificates/acme/.../*.crt
- Private keys -
certificates/acme/.../*.key
- Account keys -
acme/.../*.json
- OCSP staples - Various cached data
- Locks (if present at export time)
The exact structure depends on your storage backend and ACME usage.
The export creates a standard tar archive:
# List contents
tar -tf backup.tar
# Extract to inspect
mkdir inspect
tar -xf backup.tar -C inspect
ls -R inspect
Example contents:
certificates/acme/acme-v02.api.letsencrypt.org-directory/example.com/example.com.crt
certificates/acme/acme-v02.api.letsencrypt.org-directory/example.com/example.com.key
acme/acme-v02.api.letsencrypt.org-directory/users/...
Storage Backends
Caddy supports different storage backends:
File System (default)
{
storage file_system {
root /var/lib/caddy
}
}
Consul
{
storage consul {
address "localhost:8500"
prefix "caddy"
}
}
Redis
{
storage redis {
address "localhost:6379"
prefix "caddy"
}
}
{
storage s3 {
bucket "my-caddy-storage"
region "us-east-1"
}
}
Migrating Between Storage Types
File System → Consul
# Export from file system
caddy storage export --config Caddyfile.fs --output certs.tar
# Import to Consul
caddy storage import --config Caddyfile.consul --input certs.tar
Consul → File System
caddy storage export --config Caddyfile.consul --output certs.tar
caddy storage import --config Caddyfile.fs --input certs.tar
Caveats
- Keys are removed during export if they’re deleted from storage while export is in progress (warning will be logged)
- Permissions matter for file_system storage - run as the correct user
- Storage must be configured in the config file for both export and import
- Concurrent access during export may lead to inconsistent state
Best Practices
1. Stop Caddy during migration
sudo systemctl stop caddy
caddy storage export --config /etc/caddy/Caddyfile --output backup.tar
# ... change storage config ...
caddy storage import --config /etc/caddy/Caddyfile --input backup.tar
sudo systemctl start caddy
2. Verify backup integrity
# Create backup
caddy storage export --config Caddyfile --output backup.tar
# Verify it's a valid tar
tar -tf backup.tar > /dev/null
if [ $? -eq 0 ]; then
echo "Backup is valid"
fi
3. Regular backups
#!/bin/bash
# backup-caddy-storage.sh
BACKUP_DIR="/backups/caddy"
mkdir -p "$BACKUP_DIR"
caddy storage export \
--config /etc/caddy/Caddyfile \
--output "$BACKUP_DIR/caddy-storage-$(date +%Y%m%d-%H%M%S).tar"
# Keep only last 7 days
find "$BACKUP_DIR" -name 'caddy-storage-*.tar' -mtime +7 -delete
4. Encrypt sensitive backups
# Export and encrypt
caddy storage export --config Caddyfile --output - | \
gpg --encrypt --recipient your@email.com > backup.tar.gpg
# Decrypt and import
gpg --decrypt backup.tar.gpg | \
caddy storage import --config Caddyfile --input -
Troubleshooting
Permission errors
Error: opening output file: permission denied
Run as the correct user or use sudo:
sudo -u caddy caddy storage export --config /etc/caddy/Caddyfile --output backup.tar
If the config doesn’t specify storage, Caddy uses file_system storage with default paths. Make sure your config is complete.
Empty export
If export produces an empty or very small tarball:
- Check that certificates exist in storage
- Verify storage path is correct
- Ensure ACME has issued certificates