Skip to content

Grav CLI Tools — bin/grav Commands, Automation and Maintenance

DodaTech Updated 2026-06-27 8 min read

In this tutorial, you'll learn Grav CLI tools — the complete bin/grav command reference, Grav Package Manager (GPM), automated maintenance tasks, creating custom console commands, and CLI automation for production operations.

What You'll Learn

  • All built-in bin/grav commands
  • Grav Package Manager (GPM) commands
  • Automated maintenance with CLI tools
  • Creating custom CLI commands in plugins
  • CLI automation scripts and Cron Jobs
  • Debugging and diagnostic commands

Why It Matters

In WordPress, WP-CLI provides a command-line interface for administration. In Grav, bin/grav and bin/gpm provide similar functionality out of the box. The CLI is essential for automation — tasks like cache clearing, backup, user management, and package management are faster from the command line than through the web interface.

Real-World Use

A site administrator manages 10 Grav sites. Every morning, a cron job runs bin/grav cache --clear on all sites. Before each deployment, a script runs bin/grav install and bin/grav cache:warmup. When a security vulnerability is announced, the admin runs bin/gpm update on all 10 sites from a single terminal. All of these operations are CLI-based, scriptable, and automatable.

Learning Path

flowchart LR
    A["Git Workflow"] --> B["CLI Tools
← You are here"]:::current B --> C["Production Deployment"] classDef current fill:#38bdf8,color:#0f172a,stroke-width:2px

bin/grav Commands

Basic Commands

Command Description
bin/grav list List all available commands
bin/grav help [command] Show help for a specific command
bin/grav version Show Grav version

Server

# Start development server
bin/grav server

# Start on specific port
bin/grav server --port=8080

# Start with custom host
bin/grav server --host=0.0.0.0

Cache

# Clear all caches
bin/grav cache --clear

# Clear specific cache types
bin/grav cache --clear-twig
bin/grav cache --clear-images
bin/grav cache --clear-assets
bin/grav cache --clear-plugins

# Clear without disabling site
bin/grav cache --clear --all

# Show cache status
bin/grav cache --status

Installation

# Install dependencies (Composer + plugins)
bin/grav install

# Install only Composer dependencies
bin/grav install --composer

# Install plugins only
bin/grav install --plugins

# Set up symlinks
bin/grav install --symlinks

User Management

# Create a new admin user (interactive)
bin/grav new-admin-user

# Create user with parameters
bin/grav new-admin-user --username=admin --email=admin@example.com

# List all users
bin/grav list-users

Grav Package Manager (GPM)

Package Management

# Search for packages
bin/gpm search gallery
bin/gpm search "admin panel"

# Install a plugin
bin/gpm install admin
bin/gpm install form email login

# Install a specific version
bin/gpm install admin@1.10.0

# Install a theme
bin/gpm install quark

Updates

# Check for updates
bin/gpm check-updates

# Show all available updates
bin/gpm update --check

# Update all packages
bin/gpm update

# Update specific packages
bin/gpm update admin form

# Simulate update (dry run)
bin/gpm update --simulate

Information

# Show installed packages
bin/gpm info admin

# List all installed plugins
bin/gpm list

# Show package details
bin/gpm show admin

# Check package dependencies
bin/gpm depends admin

Uninstall

# Remove a plugin
bin/gpm uninstall admin

# Remove without confirmation
bin/gpm uninstall admin --force

Maintenance Automation

Backup Script

scripts/backup.sh:

#!/bin/bash
set -e

BACKUP_DIR="/var/backups/grav"
SITE_DIR="/var/www/grav-site"
DATE=$(date +%Y-%m-%d-%H%M%S)

# Create backup directory
mkdir -p "$BACKUP_DIR/$DATE"

# Backup user data
echo "Backing up user data..."
tar -czf "$BACKUP_DIR/$DATE/user-data.tar.gz" \
    -C "$SITE_DIR" user/pages user/config user/accounts user/languages

# Check if user data backup succeeded
if [ $? -eq 0 ]; then
    echo "User data backup complete."
else
    echo "ERROR: User data backup failed!"
    exit 1
fi

# Export plugin list
echo "Exporting plugin list..."
bin/gpm list > "$BACKUP_DIR/$DATE/plugins.txt"

# Remove backups older than 30 days
find "$BACKUP_DIR" -type d -mtime +30 -exec rm -rf {} \;

echo "Backup complete: $BACKUP_DIR/$DATE"

Health Check Script

scripts/health-check.sh:

#!/bin/bash

SITE_DIR="/var/www/grav-site"
cd "$SITE_DIR"

echo "Grav Health Check"
echo "================="

# Check PHP version
echo "PHP version: $(php -v | head -n1)"

# Check Grav version
echo "Grav version: $(php bin/grav version 2>&1)"

# Check cache status
php bin/grav cache --status

# Check for updates
php bin/gpm check-updates

# Check directory permissions
echo ""
echo "Checking permissions..."
for dir in user/data user/accounts user/config; do
    if [ -w "$SITE_DIR/$dir" ]; then
        echo "  $dir: writable"
    else
        echo "  $dir: NOT writable!"
    fi
done

# Check disk space
echo ""
echo "Disk usage:"
df -h /var/www | tail -n1

# Check PHP extensions
echo ""
echo "Required PHP extensions:"
for ext in curl mbstring xml zip gd json; do
    if php -m | grep -q "^$ext$"; then
        echo "  $ext: installed"
    else
        echo "  $ext: MISSING!"
    fi
done

Custom CLI Commands (Review)

As covered in Lesson 28, custom CLI commands are registered in plugins:

// user/plugins/myadmin/myadmin.php
public function onCliInit()
{
    $this->grav['cli']->addCommand(
        new \Grav\Plugin\Console\HealthCheckCommand()
    );
    $this->grav['cli']->addCommand(
        new \Grav\Plugin\Console\SitemapGenerateCommand()
    );
}

Sitemap Generator CLI

user/plugins/myadmin/cli/SitemapGenerateCommand.php:

<?php
namespace Grav\Plugin\Console;

use Grav\Console\ConsoleCommand;

class SitemapGenerateCommand extends ConsoleCommand
{
    protected function configure()
    {
        $this
            ->setName('sitemap:generate')
            ->setDescription('Generate XML sitemap')
            ->addOption(
                'pretty',
                'p',
                \Symfony\Component\Console\Input\InputOption::VALUE_NONE,
                'Pretty-print the XML'
            );
    }

    protected function serve($input, $output)
    {
        $this->setupConsole($input, $output);
        $io = $this->getIO();

        $io->title('Sitemap Generator');

        $pages = $this->grav['pages']->all();
        $xml = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
        $xml .= '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n";

        $io->progressStart(count($pages));

        foreach ($pages as $page) {
            if ($page->published() && !$page->isModule()) {
                $xml .= '  <url>' . "\n";
                $xml .= '    <loc>' . $page->url(true) . '</loc>' . "\n";
                $xml .= '    <lastmod>' . date('c', $page->modified()) . '</lastmod>' . "\n";
                $xml .= '    <priority>' . ($page->route() == '/' ? '1.0' : '0.8') . '</priority>' . "\n";
                $xml .= '  </url>' . "\n";
            }
            $io->progressAdvance();
        }

        $xml .= '</urlset>' . "\n";

        file_put_contents(GRAV_ROOT . '/sitemap.xml', $xml);
        $io->progressFinish();
        $io->success('Sitemap generated: ' . GRAV_ROOT . '/sitemap.xml');
    }
}

Cron Job Integration

Set up automated tasks with cron:

# Edit crontab
crontab -e

# Add tasks
# Clear cache daily at 4 AM
0 4 * * * /usr/bin/php /var/www/grav/bin/grav cache --clear >> /var/log/grav-cache.log

# Run backup nightly at 2 AM
0 2 * * * /var/www/grav/scripts/backup.sh >> /var/log/grav-backup.log

# Health check every hour
0 * * * * /var/www/grav/scripts/health-check.sh >> /var/log/grav-health.log

# Check for updates weekly
0 6 * * 1 /usr/bin/php /var/www/grav/bin/gpm check-updates >> /var/log/grav-updates.log

Learning Path

flowchart LR
    A["Git Workflow"] --> B["CLI Tools
← You are here"]:::current B --> C["Production Deployment"] classDef current fill:#38bdf8,color:#0f172a,stroke-width:2px

Common Mistakes

  1. Running CLI commands with wrong PHP binary: Ensure the PHP version used by CLI matches the one used by the web server. Use which php to find the correct binary.

  2. Not running bin/grav install after adding plugins: After adding a plugin source (manually or via Git), run bin/grav install to set up dependencies and symlinks.

  3. Forgetting to clear cache after updates: After running bin/gpm update, always run bin/grav cache --clear to ensure the new versions take effect.

  4. Running cache warmup on an idle site: Cache warming works best on a live server. Running it on a development machine caches development URLs that are invalid in production.

  5. Not using --simulate before updates: The --simulate flag shows what would happen during an update without making changes. Always use it for major version updates.

Practice Questions

  1. What command clears only the Twig template cache? Answer: bin/grav cache --clear-twig. This is faster than clearing all caches and is useful when you only changed Twig templates.

  2. What is the purpose of bin/gpm check-updates? Answer: It checks for available updates to all installed plugins and themes. It does not perform the update — use bin/gpm update to apply updates.

  3. How do you create a new admin user from the command line? Answer: Run bin/grav new-admin-user and follow the interactive prompts for username, password, and email.

  4. What does bin/grav install do? Answer: It installs Composer dependencies, sets up plugin dependencies, creates symlinks, and sets up the folder structure. It must be run after cloning a Grav site or adding plugins.

  5. Challenge: Create a comprehensive CLI automation toolkit for a production Grav site. Build: a backup script that creates compressed archives of user data and config, a health check script that validates PHP extensions, permissions, and disk space, a deployment script that pulls from Git, installs dependencies, clears cache, and warms cache, a sitemap generator CLI command, a cron configuration that runs these tasks on schedule, and a status command that shows site health at a glance. All scripts should include error handling, logging, and notifications.

FAQ

What is the difference between `bin/grav` and `bin/gpm`?

bin/grav is the main CLI tool for site operations: server, cache, install, user management. bin/gpm (Grav Package Manager) handles plugin and theme installation, updates, and removal.

Can I run CLI commands through a web endpoint?

It is possible but not recommended. Use cron or a scheduled task runner instead. If you must trigger CLI tasks via web, use a secure endpoint with authentication.

How do I get help for a specific CLI command?

Run bin/grav help COMMANDNAME. For example, bin/grav help cache shows all options for the cache command.

What PHP extensions are required for Grav CLI to work?

curl, mbstring, xml, zip, gd (or imagick), json, and openssl. Missing extensions cause specific CLI commands to fail.

Can I create a CLI command that accepts interactive input?

Yes. Use the getIO() helper in your command class. It provides methods like ask(), confirm(), choice(), and askHidden() for interactive input.

Mini Project

Goal: Build a complete CLI automation toolkit for site maintenance.

  1. Create a backup CLI command that backs up pages, config, and plugins
  2. Create a health-check CLI command that validates the installation
  3. Create a sitemap generation CLI command
  4. Create a report CLI command that outputs site statistics
  5. Create a maintenance CLI command that runs multiple tasks
  6. Add progress bars and colored output to all commands
  7. Create shell scripts that chain multiple CLI commands
  8. Set up cron jobs for automated nightly tasks
  9. Add logging to all CLI commands
  10. Create a "one-command" deploy script combining all steps

What's Next

Now you can automate everything with CLI. Next, the final lesson — production deployment:

Continue to Lesson 40: Production Deployment — Nginx configuration, SSL, monitoring, and scaling.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro