Introduction
Grav is a modern, open-source flat-file CMS that stores all content in files rather than a database. This architecture provides exceptional performance, easy backups, and simple version control integration.
Why Choose Grav?
- No database required – content stored in Markdown files
- Blazing fast performance with built-in caching
- Easy backups – just copy the files
- Powerful admin panel with live preview
- Extensible with plugins and themes
- Git-friendly for version control workflows
Prerequisites
Before beginning the installation, ensure you have the following:
| Requirement | Details |
|---|---|
| Operating System | Ubuntu 22.04 or 24.04 LTS |
| Access Level | Root or sudo access |
| Domain Name | Pointed to your server's IP address |
| Memory | Minimum 512MB RAM (1GB+ recommended) |
Update System Packages
sudo apt update && sudo apt upgrade -yInstall PHP 8.3
Grav requires PHP with several extensions. We'll install PHP 8.3 from the Ondřej PPA for the latest stable version:
sudo add-apt-repository ppa:ondrej/php -y
sudo apt updateInstall PHP 8.3 with all required extensions:
sudo apt install -y php8.3 php8.3-fpm php8.3-cli php8.3-gd php8.3-curl \
php8.3-mbstring php8.3-xml php8.3-zip php8.3-opcache php8.3-apcu \
php8.3-intl php8.3-yamlVerify the installation:
php -vConfigure PHP for Optimal Performance
Edit the PHP-FPM configuration to optimize for Grav:
sudo nano /etc/php/8.3/fpm/php.iniLocate and modify these settings:
memory_limit = 256M
upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
max_input_vars = 3000
date.timezone = America/ChicagoRestart PHP-FPM to apply changes:
sudo systemctl restart php8.3-fpmInstall and Configure Nginx
Install Nginx:
sudo apt install -y nginxCreate a new server block configuration for your Grav site:
sudo nano /etc/nginx/sites-available/gravAdd the following configuration (replace yourdomain.com with your actual domain):
server {
listen 80;
listen [::]:80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/grav;
index index.php index.html;
# Grav-specific location rules
location / {
try_files $uri $uri/ /index.php?$query_string;
}
# Deny access to specific directories and files
location ~* /(.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
location ~* /(system|vendor)/.*\.(txt|xml|md|html|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
location ~* /user/.*\.(txt|md|json|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
location ~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) { return 403; }
# PHP handling
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_read_timeout 300;
}
# Static file caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2|ttf|svg|eot)$ {
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# Deny access to hidden files
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
}Enable the site and test the configuration:
sudo ln -s /etc/nginx/sites-available/grav /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl restart nginxDownload and Install Grav
Create the web directory and download the latest Grav release with Admin panel:
cd /var/www
sudo wget https://getgrav.org/download/core/grav-admin/latest -O grav-admin.zip
sudo unzip grav-admin.zip
sudo mv grav-admin grav
sudo rm grav-admin.zipSet the correct ownership and permissions:
sudo chown -R www-data:www-data /var/www/grav
sudo find /var/www/grav -type f -exec chmod 644 {} \;
sudo find /var/www/grav -type d -exec chmod 755 {} \;
sudo chmod -R 775 /var/www/grav/cache
sudo chmod -R 775 /var/www/grav/logs
sudo chmod -R 775 /var/www/grav/images
sudo chmod -R 775 /var/www/grav/assets
sudo chmod -R 775 /var/www/grav/user
sudo chmod -R 775 /var/www/grav/backupSecure with SSL Certificate
Install Certbot for free Let's Encrypt SSL certificates:
sudo apt install -y certbot python3-certbot-nginxObtain and install the certificate:
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.comFollow the prompts to complete the certificate installation. Certbot will automatically configure Nginx to redirect HTTP to HTTPS.
Verify automatic renewal is configured:
sudo certbot renew --dry-runConfigure the Firewall
Enable and configure UFW to allow web traffic:
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
sudo ufw statusComplete Grav Setup
Navigate to your domain in a web browser. You'll be greeted by the Grav Admin setup wizard. Create your admin account with a strong password.
After logging in, configure your site:
- Go to Configuration → Site to set your site title, description, and metadata
- Navigate to Configuration → System to configure caching and performance options
- Visit Plugins to explore and install additional functionality
- Check Themes to customize your site's appearance
Performance Optimization
Enable Grav's built-in caching by editing the system configuration:
sudo nano /var/www/grav/user/config/system.yamlAdd or modify these settings:
cache:
enabled: true
check:
method: file
driver: auto
prefix: 'g'
purge_at: '0 4 * * *'
clear_at: '0 3 * * *'
clear_job_type: 'standard'
clear_images_by_default: false
cli_compatibility: false
lifetime: 604800
gzip: true
allow_webserver_gzip: true
twig:
cache: true
debug: false
auto_reload: true
autoescape: true
assets:
css_pipeline: true
css_minify: true
js_pipeline: true
js_minify: trueSet Up Automated Backups
Create a backup script:
sudo nano /usr/local/bin/grav-backup.shAdd the following content:
#!/bin/bash
BACKUP_DIR="/var/backups/grav"
GRAV_DIR="/var/www/grav"
DATE=$(date +%Y%m%d_%H%M%S)
RETENTION_DAYS=14
# Create backup directory if it doesn't exist
mkdir -p $BACKUP_DIR
# Create compressed backup
tar -czf $BACKUP_DIR/grav_backup_$DATE.tar.gz -C $GRAV_DIR .
# Remove backups older than retention period
find $BACKUP_DIR -type f -name "*.tar.gz" -mtime +$RETENTION_DAYS -delete
echo "Backup completed: grav_backup_$DATE.tar.gz"Make the script executable and schedule it with cron:
sudo chmod +x /usr/local/bin/grav-backup.sh
sudo crontab -eAdd this line to run daily backups at 2 AM:
0 2 * * * /usr/local/bin/grav-backup.sh >> /var/log/grav-backup.log 2>&1Configure Log Rotation
sudo nano /etc/logrotate.d/grav/var/www/grav/logs/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 644 www-data www-data
}Maintenance Commands
Grav includes a powerful CLI tool for maintenance tasks. Here are essential commands:
# Update Grav core
cd /var/www/grav
sudo -u www-data bin/gpm self-upgrade
# Update all plugins and themes
sudo -u www-data bin/gpm update
# Clear cache
sudo -u www-data bin/grav cache
# Check system requirements
sudo -u www-data bin/grav sandbox
# Create a new user
sudo -u www-data bin/plugin login new-user
# Backup from CLI
sudo -u www-data bin/grav backupTroubleshooting
🎉 Congratulations!
Your Grav CMS installation is now running on your RamNode VPS with optimized performance settings, SSL security, and automated backups. The flat-file architecture means you'll enjoy fast page loads and simple maintenance without database overhead.
For further customization, explore the official Grav documentation and browse the plugin directory for additional functionality like SEO optimization, sitemaps, and contact forms.
