tech·an·ic \te-ˈka-nik\ n. Thoughts on technology from Josh Dick.

Troubleshooting Apache in OS X 10.8 Mountain Lion

My experience fixing the built-in Apache installation after upgrading.

Apple released OS X 10.8 Mountain Lion to great fanfare this past Wednesday. The initial reviews of Mountain Lion that have been making the rounds on the Internet have been overwhelmingly positive. For the most part, my Mountain Lion experience over the past few days has also been positive; it's certainly a worthwhile upgrade. Mountain Lion has already been extensively reviewed. Rather than write yet another review, I decided instead to write about the only issue I've run into with Mountain Lion so far.

The Upgrade

Upgrading the existing Lion installation on my MacBook Pro to Mountain Lion ended up being exactly as straightforward as I figured it would be: after a simple download from the App Store, a single click kicks off the upgrade process. Done.

Except, not quite.

I was pleasantly surprised to find that none (!) of the third-party Mac applications I use had any issues with Mountain Lion whatsoever. I had already installed Mountain Lion-compatible updates for many applications far before Mountain Lion itself was released, and the few applications that hadn't yet been specifically updated for Mountain Lion appeared to work fine anyway.

However, I was not-so-pleasantly surprised to run into some changes in Mountain Lion related to web development. I use the Apache and PHP installations that are built into OS X for web development, and they were affected by (and required manual fixing after) the Mountain Lion upgrade.

Surprise!

Surprise 1: Web Sharing

If you're a Mac user and are reading this, you're probably familiar with Web Sharing. In case you're not, Web Sharing was a section of the Sharing preference pane that allowed users to control the Apache web server installation that was built in to Mac OS X. Did you notice how that explanation was written in the past tense? That's because starting with Mountain Lion, Web Sharing no longer exists:

OS X Mountain Lion does not include Web Sharing as an option in the Sharing preference pane. Mountain Lion does include the Apache HTTP Server, an open-source web server. For information about enabling and using Apache, see http://httpd.apache.org.

So, even though the graphical Web Sharing interface was removed from Mountain Lion, it turned out that Apache (and PHP) were still available. So then why weren't they working correctly for me? I suspected that upgrading to Mountain Lion had affected my Apache and PHP configuration files, and I turned out to be right.

Surprise 2: Custom Apache Configuration File

In OS X, user-specific Apache configuration files live in the /private/etc/apache2/users directory. Since the name of my account on my MacBook Pro is 'Josh', I had created an Apache configuration file located at /private/etc/apache2/users/Josh.conf.

After upgrading to Mountain Lion, that file had been completely deleted.

I noticed that the upgrade installer had made backup/alternate copies of other Apache configuration files (there was both a /private/etc/apache2/original directory and a /private/etc/apache2/httpd.conf~previous file), but there was no backup/alternate copy of my user-specific Apache configuration file. This was quite surprising. Luckily, I had made my own backup copy of the file that I was able to restore.

But it would have been too easy if my problems had ended there.

More Problems

Apache

After restoring my custom Apache configuration file, Apache would not start via sudo apachectl start. Instead, it would just silently terminate. There were no errors in Apache's logs (either manually viewable inside /var/log/apache2, or viewable inside Console.app).

Some Googling led me to a helpful Stack Overflow thread which explained how to debug silent termination of Apache:

$ sudo bash -x /usr/sbin/apachectl -k start

This command will show error output from Apache that isn't written to any log, and was quite helpful for debugging my problem. (Since this command attempts to start Apache, you'll see errors if you try to use it when Apache is already running.)

My custom Apache configuration file, henceforth referred to as Josh.conf, contains configuration for virtual hosts that listen on two different ports, including Listen directives for two ports (TCP ports 80 and 8080).

In the error output from the command above, I noticed that Apache was unable bind to port 80 since it was already in use. At first this didn't make sense because no other process should have been using port 80, and Apache wasn't already running.

Through experimentation, I figured out that Apache was actually conflicting with itself. Here's my understanding of what was happening: During startup, Apache started listening on port 80 as instructed by the default configuration file /private/etc/apache2/httpd.conf. When Apache loaded Josh.conf which contained a Listen 80 directive, it attempted to listen on port 80 again, except it was already listening on port 80. Since the second attempt to listen on port 80 failed, Apache would terminate at that point.

Removing the Listen 80 directive from Josh.conf resolved the issue.

I can only guess what changed from Lion to Mountain Lion that made the superfluous Listen 80 directive suddenly cause a problem when it didn't before:

  • Perhaps Apple bumped the Apache version and this is simply a behavioral change in the latest version of Apache. Mountain Lion ships with the latest Apache 2.2 release as of this writing (Apache 2.2.22), but I'm not sure what version of Apache was included with Lion. Further, I wonder why Mountain Lion includes Apache 2.2 and not Apache 2.4?

  • Perhaps I had commented out the Listen directive in the previous httpd.conf, eliminating the potential conflict with the Listen directive in Josh.conf. httpd.conf had been replaced with a stock copy after the upgrade, which would have re-introduced the conflict. I don't remember ever modifying httpd.conf in that way though, so I doubt this is the case.

  • Added on February 27, 2013: A reader did some experimenting and reported that in Mountain Lion, Apache breaks when multiple Listen directives are configured, despite the fact that multiple Listen directives are supposed to be supported. It's possible that this is a bug or that Apple somehow customized Apache to have this behavior.

Either way, after removing the Listen 80 directive from Josh.conf, Apache was finally able to start.

Since httpd.conf had been replaced with a stock version, I had to uncomment the following line and then restart Apache (sudo apachectl restart) to get PHP working again:

LoadModule php5_module libexec/apache2/libphp5.so

PHP

PHP's configuration file located at /private/etc/php.ini was also affected by the Mountain Lion upgrade. The installer created a backup of it, then replaced it with a stock version. In fact, there were lots of related backups:

/private/etc/php.ini-5.2-previous
/private/etc/php.ini-5.2-previous~orig
/private/etc/php.ini.default
/private/etc/php.ini.default-5.2-previous
/private/etc/php.ini.default-5.2-previous~orig

The only change I made to the stock php.ini was to set the date.timezone setting.

Wrapping Up

Hopefully, this post will help others who may have similar problems--either with Mountain Lion or with Apache 2.2 in general.

There are usually growing pains with any operating system upgrade, and this experience was no exception. I'm sure I'll continue to be surprised by the many subtle changes in OS X Mountain Lion, and I hope the pleasant surprises will continue to outnumber the unwanted ones.


comments powered by Disqus