Skip to content

Grav Deployment & Maintenance — Going Live and Staying Safe

DodaTech Updated 2026-06-27 6 min read

In this tutorial, you'll deploy your Grav site to production and set up a maintenance routine.

What You'll Learn

  • How to deploy Grav to production servers
  • Git-based deployment workflow
  • Backup strategies for flat-file sites
  • Updating Grav core, plugins, and themes
  • Monitoring and troubleshooting production issues

Why It Matters

A local Grav site is just practice. A live site delivers value. But deploying a CMS means considering server requirements, security, backups, and updates. Grav's flat-file architecture makes deployment simpler than database-driven CMS platforms — but you still need a plan.

Real-World Use

DodaTech deploys Grav documentation sites using a Git workflow: git push to a private repository, a webhook triggers git pull on the production server, followed by bin/grav cache. No database migrations, no sync jobs, no downtime.

Hosting Options

Shared Hosting

Most shared hosting supports Grav with PHP 8.0+.

Requirements:

  • PHP 8.0 or higher
  • PHP extensions: curl, mbstring, xml, zip, json
  • Apache with mod_rewrite (or Nginx)

Upload steps:

  1. Zip your Grav folder (excluding user/data/cache/)
  2. Upload via cPanel File Manager or FTP
  3. Unzip in the web root
  4. Set permissions: chmod -R 755 user/
  5. Clear cache: php bin/grav cache

VPS / Dedicated Server

Full control, best performance.

Nginx config:

server {
    listen 80;
    server_name example.com;
    root /var/www/grav;

    index index.php;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\. {
        deny all;
    }

    location ~ \.(yaml|twig|md)$ {
        deny all;
    }
}

Cloud Platform

Platforms like DigitalOcean App Platform, Railway, or Render can run Grav:

  1. Push your Grav site to a Git repository
  2. Set the build command: composer install --no-dev
  3. Set the start command: cp -r user /app/ && php -S 0.0.0.0:8080 index.php
  4. Set environment variable: GRAV_ENV=production

Git-Based Deployment

The most common workflow for Grav teams.

Step 1: Initialize Git

cd grav-site
git init
git add .
git commit -m "Initial Grav site"

Step 2: Add .gitignore

user/data/cache/*
user/data/logs/*
user/data/sessions/*
vendor/
.env

This excludes cache and vendor files — they're regenerated on the server.

Step 3: Set Up a Remote

git remote add origin https://github.com/yourorg/grav-site.git
git push -u origin main

Step 4: Deploy on the Server

# On the production server
git clone https://github.com/yourorg/grav-site.git
cd grav-site
composer install --no-dev
bin/grav cache --all

Step 5: Automate with a Webhook

For automatic deployment on push, create a deploy script:

#!/bin/bash
# /var/www/deploy.sh
cd /var/www/grav
git pull origin main
composer install --no-dev
bin/grav cache --all

Then set up a webhook that triggers this script when you push to the repository.

Backup Strategies

Grav's flat-file structure makes backups simple.

Full Backup (Files Only)

# Backup everything except cache and vendor
tar -czf grav-backup-$(date +%Y-%m-%d).tar.gz \
  --exclude="user/data/cache" \
  --exclude="vendor" \
  grav-site/

Incremental Backup with Git

git add .
git commit -m "Backup $(date +%Y-%m-%d)"
git push

Your entire site (content, config, themes) is backed up with full version history.

Selective Backups

What Where Backup Command
Content user/pages/ tar -czf pages-backup.tar.gz user/pages/
Configuration user/config/ tar -czf config-backup.tar.gz user/config/
Themes user/themes/ tar -czf themes-backup.tar.gz user/themes/
Plugins user/plugins/ tar -czf plugins-backup.tar.gz user/plugins/

Restore from Backup

# Restore full site
tar -xzf grav-backup-2026-06-27.tar.gz
cd grav-site
composer install --no-dev
bin/grav cache --all

Updating Grav

Check for Updates

bin/gpm version

Update Core

bin/grav selfupgrade

Update All Plugins and Themes

bin/gpm update

Safe Update Process

# 1. Backup
tar -czf pre-update-backup.tar.gz user/

# 2. Update
bin/grav selfupgrade
bin/gpm update

# 3. Clear cache
bin/grav cache --all

# 4. Verify
curl -I http://yoursite.com
⚠️ Warning

Always test updates on a local copy first. Grav is stable, but plugin compatibility issues can occur. The Admin plugin and Login plugin versions must match the Grav core version.

Maintenance Routine

Daily

# Check error logs
tail -f user/data/logs/grav.log

# Monitor disk usage
du -sh user/data/cache/

Weekly

# Git commit and push
git add user/pages/ user/config/
git commit -m "Weekly backup $(date +%Y-%m-%d)"
git push

# Check for updates
bin/gpm version

Monthly

# Full backup
tar -czf monthly-backup-$(date +%Y-%m).tar.gz grav-site/

# Clear old cache
bin/grav cache --all

# Review security
bin/grav security

# Update dependencies
composer update --no-dev

Troubleshooting Production Issues

Problem Likely Cause Fix
White screen PHP error or permission issue Check user/data/logs/grav.log, set permissions
404 on pages .htaccess or Nginx config missing Ensure rewrite rules are configured
Admin login loops Session directory not writable chmod 755 user/data/sessions/
Styles missing Asset pipeline broken Clear cache, disable pipeline temporarily
Slow page loads Cache disabled in production Enable Caching in system.yaml
Forms not emailing SMTP credentials wrong Check user/config/plugins/email.yaml

Learning Path

flowchart LR
  A["What is Grav?"] --> B["Installation"]
  B --> C["Pages & Content"]
  C --> D["Navigation"]
  D --> E["Twig Templating"]
  E --> F["Themes"]
  F --> G["Taxonomy & Blog"]
  G --> H["Plugins & Admin"]
  H --> I["Configuration & Caching"]
  I --> J["Deployment & Maintenance
← You are here"]:::current classDef current fill:#38bdf8,color:#0f172a,stroke-width:2px

What You Built

Over 10 lessons, you built a complete Grav documentation site:

Lesson What You Did
1 Learned the flat-file CMS concept
2 Installed Grav and explored the folder structure
3 Created pages with Markdown and frontmatter
4 Organized navigation and menus
5 Built Twig templates with inheritance
6 Customized themes with branding
7 Set up blog with taxonomy and tags
8 Extended with plugins and Admin panel
9 Optimized caching for production
10 Deployed to production and set up maintenance

Practice Questions

  1. What's the simplest way to back up a Grav site? Answer: Git. git add . && git commit -m "backup" && git push backs up content, config, and themes with full version history.

  2. How do you deploy Grav to a production server? Answer: Clone the Git repo on the server, run composer install --no-dev, clear cache. Alternatively, upload files via FTP.

  3. How do you update Grav core and plugins safely? Answer: Backup first, then run bin/grav selfupgrade and bin/gpm update, then clear cache and verify.

  4. Why is Git-based deployment easier with Grav than WordPress? Answer: No database. Content is files that can be version-controlled, merged, and deployed like any codebase. WordPress requires database syncing between environments.

  5. Challenge: Deploy your Grav site to a production server. Set up automated daily Git backups. Configure a weekly cron job for updates. Test a restore from your backup.

Final Words

You started with "what is a flat-file CMS" and ended with a fully deployed Grav site. Here's what makes Grav special in the CMS landscape:

  • No database — Setup takes 2 minutes, backups are file copies
  • Git-native — The entire site is version controllable
  • Fast by default — File reads beat database queries
  • Twig templates — Clean, secure, maintainable
  • Developer-friendly — Edit in any text editor, deploy with git pull

Your Grav site is ready. Add more content, refine your theme, and keep learning. Every expert was once a beginner — and you're no longer a beginner.

Continue exploring other tutorials:

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro