How do I get my user directory working for web sharing again?

I had web sharing enabled in Lion and a web site at http://localhost/~user, where user is my User directory. When I upgraded to Mountain Lion, web sharing (Apache) remained enabled and I can go to localhost and get the "It works!" default web page, but I cannot access my user page anymore. The error is

Forbidden

You don't have permission to access /~user/ on this server.

How do I re-enable my user directory's web page?


Here is how you can re-enable the web page with the command line using Terminal.

First copy this and paste it into Terminal. You may have to press enter after pasting to run it. It will ask for your password because it is adding a file to your system directory.

USER_DIR=$(basename $(echo ~))
sudo bash -c "cat > /etc/apache2/users/$USER_DIR.conf" <<TEXT
<Directory "/Users/$USER_DIR/Sites">
     Options Indexes MultiViews
     AllowOverride None
     Order allow,deny
     Allow from all
</Directory>
TEXT

Then run this command to restart the web server:

sudo apachectl restart

I had to add FollowSymLinks as follows to my /etc/apache2/users/username.conf :

<Directory "/Users/username/Sites/">
Options Indexes MultiViews FollowSymLinks
AllowOverride None
Order deny,allow
Allow from all
</Directory>

(username has to be replaced by your real username)


Here is a one-line terminal command that will enable macOS's built-in apache server, and allow you to use the Sites directory in your User folder. It is compatible with the latest version of macOS as of this writing (Mojave), and has also been tested to work with Sierra and High Sierra. I suspect it will work with other versions as well—I did my best to write it in a future-proof manner.

mkdir ~/Sites ; sudo bash -c "printf '<Directory \"/Users/`whoami`/Sites/\">\n\tAddLanguage en .en\n\tAllowOverride All\n\tOptions Indexes MultiViews FollowSymLinks\n\tRequire all granted\n</Directory>' > /etc/apache2/users/`whoami`.conf ; echo 'AddDefaultCharset utf-8' >> /etc/apache2/httpd.conf ; sed -i '' '/LoadModule userdir_module libexec\/apache2\/mod_userdir.so/s/^#*//g' /etc/apache2/httpd.conf ; sed -i '' '/LoadModule php[0-9]_module libexec\/apache2\/libphp[0-9].so/s/^#*//g' /etc/apache2/httpd.conf ; sed -i '' '/Include \/private\/etc\/apache2\/extra\/httpd-userdir.conf/s/^#*//g' /etc/apache2/httpd.conf ; sed -i '' '/Include \/private\/etc\/apache2\/users\/\*.conf/s/^#*//g' /etc/apache2/extra/httpd-userdir.conf ; apachectl start"

† Well, it's technically one line, even if it's really really long...