The core documentation and frequently asked questions for caddyscript. This includes installation guides, maintenance commands, and common queries.
The script is designed for a minimal, fresh install of Debian 13.
Run this single command on a fresh Debian 13 minimal VPS:
$ curl -fsSL https://get.caddyscript.io | bash
Alternative: Manual install (if you prefer control)
# Download and install in one go
$ sudo curl -fsSL https://get.caddyscript.io -o /usr/local/bin/caddyscript \
&& sudo chmod +x /usr/local/bin/caddyscript
# Now use it
$ caddyscript --install
The script sets up security by default by enabling UFW Firewall (ports 22, 80, 443 only), installing Fail2Ban, and enabling Unattended Upgrades for automatic security patches.
All site creation is handled via the --create command with a specified --type. The root for all sites is /var/www/<domain>/htdocs.
| Site Type | Command Example |
|---|---|
| ClassicPress | $ caddypress --create --domain blog.com --type classicpress |
| Static HTML | $ caddypress --create --domain static.com --type static |
| General PHP | $ caddypress --create --domain phpapp.com --type php |
| Staging Site | $ caddypress --create --domain staging.blog.com --type staging --staging-source blog.com |
Note on Staging: The script clones site files but requires manual database cloning and configuration updates for the staging site (indicated by a TODO in the source code).
Use the --backup command to create a compressed archive (.tar.gz) of the site files, saved to /root/backups/.
$ caddypress --backup --domain example.com --type tar
Database Backup: The script only handles file backup. You must manually run mysqldump to secure your database.
The script does not have a dedicated update function. Security patches are handled automatically by **Unattended Upgrades**. For major version changes (e.g., PHP 8.3 to 8.4), use standard Debian package management commands (`apt-get upgrade`).
The --delete command removes the Caddy config, PHP-FPM pool, and the entire webroot directory. It first runs a forced file backup for safety.
$ caddypress --delete --domain example.com
This command stops and purges all installed components (Caddy, PHP, MariaDB, UFW) and deletes all associated configuration files and web content. This action is irreversible.
$ caddypress --uninstall
The script automatically generates this optimized configuration. It includes hardening for headers, Brotli/Zstd compression, and aggressive asset caching.
{
# Global Options
email admin@example.com
auto_https on
}
# ===========================================================
# DOMAIN 1: CLASSICPRESS / PHP SITE — example.com
# ===========================================================
example.com {
root * /var/www/example.com/htdocs
# ---- PHP HANDLER (Auto-detects index.php) ----
php_fastcgi unix//run/php/php8.3-fpm.sock
file_server
# ---- COMPRESSION ----
encode gzip zstd
# ---- SECURITY HEADERS ----
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy "geolocation=(), microphone=(), camera=()"
}
# ---- ASSET CACHING (Immutable) ----
# Cache images/css/js for 30 days
@assets {
path *.css *.js *.jpg *.jpeg *.png *.gif *.svg *.ico *.webp *.avif *.woff *.woff2 *.ttf *.eot *.mp4 *.webm
}
header @assets Cache-Control "public, max-age=2592000, immutable"
# ---- NO CACHE FOR ADMIN ----
# Ensure admin panels are never cached by browsers
@nocache {
path /wp-admin/* /wp-login.php
}
header @nocache Cache-Control "no-store, no-cache, must-revalidate"
# ---- LOGGING (Rolling) ----
log {
output file /var/www/example.com/logs/access.log {
roll_size 10MiB
roll_keep 7
roll_keep_for 30d
}
}
}
# ===========================================================
# DOMAIN 2: STATIC SITE — blog.example.com
# ===========================================================
blog.example.com {
root * /var/www/blog.example.com/htdocs
file_server
encode gzip zstd
# ---- SECURITY HEADERS ----
header {
Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
X-Frame-Options "SAMEORIGIN"
X-Content-Type-Options "nosniff"
}
# ---- CACHING ----
@html {
path *.html *.htm
}
header @html Cache-Control "public, max-age=600"
log {
output file /var/www/blog.example.com/logs/access.log
}
}