caddyscript

caddyscript Documentation

Now using v2 engine – CLI-first, safer, more powerful

The core documentation and frequently asked questions for caddyscript. This includes installation guides, maintenance commands, and common queries.

How To: Management & Operations

1. Installation & Minimum Specs

The script is designed for a minimal, fresh install of Debian 13.

Install caddyscript (One Line)

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

Security Measures

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.

2. Site Creation & Walkthroughs

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).

3. Backups, Updates, and Uninstallation

Create Backup

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.

Update Components

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`).

Delete Individual Site

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

Uninstall Full Stack (Nuclear Cleanup)

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

Reference: The Production Caddyfile

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
    }
}