How to Redirect an HTTP Site From WWW to non-WWW (or the other way around)

I like to run my sites without a www. You’re looking at this site like that e.g. http://bash-prompt.net.

Some traffic always arrives at http://www.bash-prompt.net which sometimes breaks things, especially with dynamic sites.

This problem can be solved using the Apache module mod_rewrite. But I’ve had problems with that and it’s an overcomplicated way to do things.

The problem is more easily solved using Apache’s Redirect directive supplied by mod_alias.

Step 1 - Preparation

First, make sure that the mod_alias module is loaded and reload Apache:

# a2enmod alias
# systemctl reload apache2

Next, remove the undesired hostname (usually it’s a ServerAlias) from the existing VirtualHost file. In the following, I want to redirect all traffic from www.example.com to example.com. This would be the very simple VirtualHost file for this site:

<VirtualHost 1.2.3.4:80>

    DocumentRoot /var/www/example-com
    ServerName   example.com
    ServerAlias  www.example.com

</VirtualHost>

This becomes:

<VirtualHost 1.2.3.4:80>

    DocumentRoot /var/www/example-com
    ServerName   example.com

</VirtualHost>

Step 2 - Create the new VirtaulHost

Create a new VirtualHost file for www.example.com which will include the Redirect instruction:

<VirtualHost 1.2.3.4:80>

    DocumentRoot /var/www/example-com
    ServerName   www.example.com

    Redirect permanent / http://example.com/

</VirtualHost>

Reload Apache again to get the new config live.

Apache will now reply with an instruction to the requesting client that the requested page/file etc has a new location with a 301 Permanent Move response.

Here’s the curl output for requesting http://www.bash-prompt.net:

# curl -Ia http://www.bash-prompt.net/guides/openssl-benchmark/index.html
HTTP/1.1 301 Moved Permanently
Date: Mon, 31 Jul 2023 07:47:59 GMT
Server: Apache/2.4.57 (Debian)
Location: http://bash-prompt.net/guides/openssl-benchmark/index.html
Cache-Control: max-age=172800
Expires: Wed, 02 Aug 2023 07:47:59 GMT
Content-Type: text/html; charset=iso-8859-1

As you can see, everything after the hostname i.e. /guides/openssl-benchmark/index.html is preserved in the redirect response.

You can also set the new address to be https if you want:

<VirtualHost 1.2.3.4:80>

    DocumentRoot /var/www/example-com
    ServerName   www.example.com

    Redirect permanent / https://example.com/

</VirtualHost>