I am trying to move the rules/content in the .htaccess file to the virtualhost (file of my WordPress website).
Server details - Apache 2.4 on Ubuntu 20.04.3 LTS
This is how the virtualhost file looks like after I have moved the contents of the .htaccess file -
<IfModule mod_ssl.c>
<VirtualHost *:443>
Protocols h2 http/1.1
ServerName example.com
ServerAlias www.example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/example.com
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.example.com [NC]
RewriteRule ^(.*)$ https://example.com$1 [L,R=permanent,NC]
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem
<Location />
# BEGIN WordPress
# The directives (lines) between "BEGIN WordPress" and "END WordPress" are
# dynamically generated, and should only be modified via WordPress filters.
# Any changes to the directives between these markers will be overwritten.
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress
# BEGIN Imagify: webp file type
<IfModule mod_mime.c>
AddType image/webp .webp
</IfModule>
# END Imagify: webp file type
</Location>
</VirtualHost>
</IfModule>
My Queries:-
1. Is it the right way to do it? I mean, can we directly paste the contents of .htaccess file into the virtualhost file/directive inside <Location /> </Location>
?
2. <IfModule mod_rewrite.c>
and <IfModule mod_mime.c>
are used inside <IfModule mod_ssl.c>
. Can we use it like this or have I made any mistakes?
The website was loading without any issues when I checked it (after restarting the Apache server) but I wanted to be sure that I am not doing anything wrong.
Thanks in advance!
CodePudding user response:
- can we directly paste the contents of .htaccess file into the virtualhost file/directive inside
<Location /> </Location>
Not inside a <Location>
block. Whilst this may "work" in this instance, it's not officially supported and other directives might break (the URL matched is the absolute file path, not the root-relative URL-path - so the first RewriteRule
is not actually doing anything, since it never matches).
However, you can directly paste the contents of the .htaccess
file into an appropriate <Directory>
block. And disable .htaccess
overrides at the same time - otherwise any .htaccess
file will override the <Directory>
in the server config!
<IfModule mod_rewrite.c>
and<IfModule mod_mime.c>
are used inside<IfModule mod_ssl.c>
. Can we use it like this
You can, however, there should be no need to. These <IfModule>
wrappers should be removed. This is your server, you know whether these modules are enabled or not.
The # BEGIN
/ # END
comment markers are only strictly relevant in .htaccess
since WordPress looks for these in order to automatically update the .htaccess
file.
For example, have it like this instead (replacing the <Location />
block):
<Directory /var/www/example.com>
Require all granted
# Disable .htaccess overrides
AllowOverride None
# BEGIN WordPress
RewriteEngine On
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
# END WordPress
# BEGIN Imagify: webp file type
AddType image/webp .webp
# END Imagify: webp file type
</Directory>
In your <VirtualHost>
you are not actually permitting access (ie. Require all granted
) - I have added this here. But I assume this must be enabled in a parent config somewhere for this to be working?
Aside: I'm not sure why WordPress write the directives like this, but the RewriteBase
directive is not being used here (and should be removed entirely IMO). The slash prefix on the last RewriteRule
substitution can also be removed (this makes the code much more portable).
For example:
# BEGIN WordPress
RewriteEngine On
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
# END WordPress
(I also change the .*
regex to simply ^
on the first RewriteRule
- this is just a more efficient regex, since we don't need to actually match anything here.)
Alternative - directly in the <VirtualHost>
The alternative is to move the directives directly into the <VirtualHost>
container (not in a directory context). However, this requires some changes since the directives are processed much earlier (before the request is mapped to the filesystem) and the URL-paths matched (and written to) are now always root-relative (starting with a slash), instead of being relative. There is also no "looping" by the rewrite engine, unless this is explicitly triggered. The RewriteBase
directive is not permitted in this context (and results in an error).
For example:
# BEGIN WordPress
RewriteEngine On
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
RewriteCond %{LA-U:REQUEST_FILENAME} !-f
RewriteCond %{LA-U:REQUEST_FILENAME} !-d
RewriteRule ^/. /index.php [L]
# END WordPress
# BEGIN Imagify: webp file type
AddType image/webp .webp
The LA-U:
prefix creates a look-ahead in order to determine the final value of the REQUEST_FILENAME
variable (otherwise this is the same as the REQUEST_URI
server variable).
However, strictly speaking, you should still have a <directory /var/www/example.com>
container in order to allow access and disable .htaccess
overrides.