Apache
Apache is the most widely deployed HTTP server and the default on the majority of shared hosts. Grav is designed to run on Apache out of the box: every release ships an .htaccess file in the site root that handles URL rewriting and blocks direct access to private folders, so in most cases there is nothing to configure beyond making sure Apache is allowed to read that file.
Requirements
To run Grav on Apache you need:
apache2with themod_rewritemodule enabled (sudo a2enmod rewrite)phpavailable to Apache, either throughmod_php, or (recommended)php-fpmviamod_proxy_fcgi
Enable .htaccess overrides
Apache only reads the bundled .htaccess when AllowOverride is set to All for your document root. This is the single most common reason Grav's rewrite and security rules do not take effect. In your virtual host (or the relevant <Directory> block), set:
<Directory /var/www/grav>
AllowOverride All
Require all granted
</Directory>
Then reload Apache:
sudo systemctl reload apache2 # or: sudo apachectl graceful
If you cannot enable AllowOverride (for example on a locked-down host), copy the contents of the shipped .htaccess into your virtual host configuration instead, inside the matching <Directory> block.
Subfolder installs and RewriteBase
If Grav lives at the root of your domain, the default rules work as-is. If you installed Grav into a subfolder and you get 500 or 404 errors on subpages, uncomment the RewriteBase line near the top of .htaccess and set it to your subfolder:
RewriteBase /your_sub_folder
Behind a load balancer or proxy
In hosted or load-balanced environments where SSL is terminated upstream, uncomment the X-Forwarded-Proto block in .htaccess so Grav recognises the connection as secure:
RewriteCond %{HTTP:X-Forwarded-Proto} https
RewriteRule .* - [E=HTTPS:on]
The shipped security rules
The bundled .htaccess is the canonical source of these rules, so you should not need to maintain your own copy. For reference, the Security block blocks direct access to Grav's private folders and to script files inside its system and user folders, while still allowing public media uploaded under user/data (for example images added through Flex Objects) to be served directly:
1## Begin - Security
2# Block all direct access for these folders
3RewriteRule ^(\.git|cache|bin|logs|backup|webserver-configs|tests)/(.*) error [F,NC]
4# Block all direct access to these sensitive user folders, whatever the file type
5RewriteRule ^(user)/(accounts|config|env)/(.*) error [F,NC]
6# Block user/data too, but allow public asset uploads (e.g. Flex Object images)
7# to be served directly. SVG stays blocked as a stored-XSS vector; .css/.js are
8# served per project policy despite the same risk on this user-writable folder.
9RewriteCond %{REQUEST_URI} !\.(jpe?g|png|gif|webp|avif|bmp|ico|mp4|webm|ogg|ogv|mov|mp3|wav|m4a|flac|pdf|woff2|woff|ttf|otf|eot|css|js)$ [NC]
10RewriteRule ^(user)/data/(.*) error [F,NC]
11# Block access to specific file types for these system folders
12RewriteRule ^(system|vendor)/(.*)\.(txt|xml|md|html|htm|shtml|shtm|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ error [F,NC]
13# Block access to specific file types for these user folders
14RewriteRule ^(user)/(.*)\.(txt|md|json|yaml|yml|php|php2|php3|php4|php5|phar|phtml|pl|py|cgi|twig|sh|bat)$ error [F,NC]
15# Block all direct access to .md files:
16RewriteRule \.md$ error [F,NC]
17# Block all direct access to files and folders beginning with a dot
18RewriteRule (^|/)\.(?!well-known) - [F]
19# Block access to specific files in the root folder
20RewriteRule ^(LICENSE\.txt|composer\.lock|composer\.json|\.htaccess)$ error [F,NC]
21## End - Security
Note
If you replaced or heavily edited the shipped .htaccess, compare it against the current one in the Grav repository and make sure the Security block is present and up to date. The User Folder Exposure page explains the admin warning that fires when these rules are not being applied.
Confirming it works
A request for a private file such as https://www.example.com/user/config/system.yaml should return 403 Forbidden, not the file's contents. A request for a media file you uploaded under user/data (for example a .jpg) should still load normally.
Tip
LiteSpeed reads .htaccess and is fully compatible with Grav's Apache rules, so the same configuration applies. Just make sure rewrite rules are enabled for the virtual host.