All posts in “Apache”

(13)Permission denied

This apache error is the bane of my existence. It is sometimes nearly impossible to figure out even though I know the fundamentals of the httpd web server. On mountain lion, you should generally debug this like so:

  1. Make sure the user/group specified in httpd.conf is www/www
  2. Make sure the directory has execute permissions for www
  3. Make sure the directory has a default (index.php or index.html)
  4. Make sure that default is readable by www
  5. Make sure that ALL encapsulating directories are executable by www (readable)

It is this last point that I want the emphasize because I had this issue moving to Mountain Lion (OS X 10.8). Your user Documents directory is 700 and is owned by you. If you try to serve a file anywhere below this directory, you’ll have problems. So there are two things you can do to find out if the error is due to parent permissions:

  1. go to the web root and do `ls -leahG` on that directory, cd ../, rinse, repeat; taking note of all permissions.
  2. use the spectacular parsepath.pl tool. Throw this into /usr/local/bin and give it execute permissions and run it on your default index file.

From number 2 above, you’ll get something like this:

d 0755 root:wheel /
d 0755 root:admin /Users
d 0755 beetle:staff /Users/beetle
d 0700 beetle:staff /Users/beetle/Documents
d 0755 beetle:staff /Users/beetle/Documents/Projects
d 0755 beetle:staff /Users/beetle/Documents/Projects/aaa
d 0755 beetle:staff /Users/beetle/Documents/Projects/aaa/bbb
d 0755 beetle:staff /Users/beetle/Documents/Projects/aaa/bbb/web
f 0644 beetle:staff /Users/beetle/Documents/Projects/aaa/bbb/web/index.php

Boom. /Users/beetle/Documents has 700 permissions and www is denied. chmod this to 755 and everything should be good. You could also modify the parsepath.pl file to give you `ls -leahG` info as well.

Another thing I learned during this process is /etc/paths is a fine location to store your path info. Update this file and source /etc/bashrc will get you on your way. Neato.

 

Setting Up Django With Mod_WSGI On Snow Leopard

django

Updated below (08/26/2014).

As you’ve probably noticed, I like to compile things. Package management, although useful, just really doesn’t do it for me. Recently, I had to set up a customized install of PHP on CentOS and was forced to use RPM. Well, the experience was funky to say the least. The basic php install had all compile-ins disabled. I had to root around and find the specific package, such as GD, then RPM it into PHP via an ini directive in /etc/php.d/. This sort of drove me nuts.

Anyway, onto Django. Snow Leopard comes with Python 2.6.1 and Apache 2.2.11. Of course I compiled my own version of Apache, resulting in a 2.2.13 version in /usr/local. I left Python alone. Installing Django was a snap and once again I had to go the bleeding edge route and use the Django trunk as my install, symlinking it into /Library/Python/2.6/site-packages/. This worked just great. Now I needed Apache to serve up my Django framework. I had the choice of mod_python or mod_wsgi and seeing the benefits of mod_wsgi, I went with that (also I’ve had horrible experiences with mod_python in the past).

I downloaded mod_wsgi, and did the following:

# tar -xzvf mod_wsgi-2.6.tar.gz
# cd mod_wsgi-2.6
# ./configure --with-apxs=/usr/local/apache2/bin/apxs
# make
# make install

And it blew up with the following error:

Warning! dlname not found in /usr/local/apache2/modules/ mod_wsgi.la.
Assuming installing a .so rather than a libtool archive.
chmod 755 /usr/local/apache2/modules/mod_wsgi.so
chmod: cannot access `/usr/local/apache2/modules/mod_wsgi.so’: No such file or directory
apxs:Error: Command failed with rc=65536
.
make: *** [install] Error 1

Great, mod_python nightmares started returning. I did some research and found many people were having problems with mod_wsgi on Snow Leopard. Graham Dumpleton, the maintainer has been very active in helping people out. His main suggesting was to modify the Makefile to have it point to the correct version of Python by modifying the LDFLAGS and LDLIBS. None of these suggestions worked for me, and even Graham seemed baffled as to why it would work on some Snow Leopard systems and not on others. One of his points was that people with a MacPorts build of Python were corrupting the mod_wsgi process as this build is a bit shaky. Without specifying your version of Python during ./configure, the MacPorts libraries would supersede the default install or other compiled versions. I checked an indeed I had a MacPorts Python in /opt/local/. How did that get there? I hate package managers.

But this wasn’t the problem as I could see the correct version of Python in the Makefile. Most of the people having problems had a customized Python build, but I was on the other side with a customized Apache build. So I looked into the difference between my APXS and the default APXS. The only major difference was on line 199:

($httpd = $0) =~ s:support/apxs$:httpd:;

My version did not have that httpd in there and looked like:

($httpd = $0) =~ s:support/apxs$::;

Making this change solved the problem. I’m not sure what I did to get a funky APXS, so if anyone knows I’d love to hear it.

I had some other issues with permissions, paths, and eggs, but they were fairly simple and if you follow the documentation, you can get everything working. I don’t always RTFM.

Hopefully this saves someone else the time and misery of setting up Django using mod_wsgi under Snow Leopard.

Update:

So here I am years later, having completely abandoned apache for nginx, and somehow get stuck with getting graphite up and running. After the fun of py2cairo, I just wanted to keep to the script as much as possible so I went with apache httpd. I ran into my good friend, the apxs:Error: Command failed with rc=65536 error above.

I’ve seen this before. I google it and find this page but the missing httpd doesn’t do anything. Uh oh. Looks like another person or two has had the same problem so I follow their advice “rebuild apache without –enable-module or –enable-shared”, and bam, it works.

If I have time to dive into the details of why, I’ll update this post again. Here is the helpful thread (that references this page).

Installing Tomcat 6.0.x Behind Apache 2.2.x

Apache TomcatInstalling Tomcat is relatively easy as most of the work has already been done for you. These instructions pertain to OS 10.5.6 and will probably work for OS 10.5.x and 10.4.x. Going before 10.4 will probably required you to install a newer JDK. I’m going to run through this as root again. Any time you see #, this is the command line prompt. Ok, let’s get started:

1) Check Apache
Find where httpd is with “find httpd”. You are either running the default in /usr/sbin/httpd or running your own version in /usr/local/apache2/ or similar. I’m going to assume you are running in /usr/local/apache2/ and that you followed my other tutorial on installing 64-bit Apache/PHP. Now check what modules you have installed with “/usr/local/apache2/bin/httpd -l” and you should see a list of mod_* entries.

We’re going to stick with the reverse proxy and not go the mod_jakarta route (trust me, this is easier and I’m not even sure mod_jakarta is even being worked on anymore). So what we need to see in this mod_* list is mod_rewrite and mod_proxy. If you followed my previous instructions, you’ll note that mod_proxy is NOT there. We will have to recompile Apache.

2) Compile Apache
Go into /usr/local/src/httpd-2.2.11/config.nice and add the line

"--enable-proxy"

right after the line

"--enable-rewrite"

then from the command line:

# ./config.nice
# make
# make install

This will only compile/install the bits needed unless you ran “make clean” previously. The config.nice is handy as it is a record of your config options allowing you to easily make updates and recompile. So now try the “/usr/local/apache2/bin/httpd -l” command again and you should now see mod_proxy (plus some others).

3) Install Tomcat
Download the binary tarball into your /usr/local/src/ directory using “curl -O”. The current version is 6.0.18 – http://apache.inetbridge.net/tomcat/tomcat-6/v6.0.18/bin/apache-tomcat-6.0.18.tar.gz

Once you have this, move it into the proper place:

# tar -xzvf apache-tomcat-6.0.18.tar.gz
# mv apache-tomcat-6.0.18 /usr/local/
# ln -s /usr/local/apache-tomcat-6.0.18/ /usr/local/tomcat

As I mentioned in a previous tutorial, I like to leave the version info intact and symlink from a generic name. This allows me to have different versions of tomcat installed in the same location and switch between them by changing the symlink. We now need to set the JAVA_HOME environment variable. This is most easily done in /etc/bashrc by adding the line:

export JAVA_HOME="/Library/Java/Home"

to the end of the file.

So now check to make sure Tomcat is working by executing the startup script /usr/local/tomcat/bin/startup.sh. The default port is 8080 so fire up a browser and check http://localhost:8080/. You should see a page stating you set up Tomcat successfully.

4) Secure Tomcat
Open the file /usr/local/tomcat/conf/tomcat-users.xml and uncomment everything between “tomcat-users”. You will need to add two more roles and at least change the default passwords. The “tomcat-users” stanza should look something like this:

<tomcat-users>
<role rolename="tomcat"/>
<role rolename="role1"/>
<role rolename="manager"/>
<role rolename="admin"/>
<user username="tomcat" password="{password}" roles="tomcat,admin,manager"/>
<user username="role1" password="{password}" roles="role1"/>
<user username="both" password="{password}" roles="tomcat,role1"/>
</tomcat-users>

I believe this change will be picked up by Tomcat, but just in case, from the Tomcat bin directory run “shutdown.sh” then “startup.sh”. You should now be able to access the Admin links on the default page at localhost:8080.

5) Configure Apache
In your Apache config file – /usr/local/apache2/conf/httpd.conf – create a VirtualHost stanza for the hostname to pass on to Tomcat. Here is an example for the hostname tomcat.latko.org:

<VirtualHost tomcat.latko.org:80>
ServerName tomcat.latko.org
ServerAlias tomcat.latko.org
ServerAdmin chris [at] latko [dot] org
DocumentRoot /Library/WebServer/Documents/tomcat
#APP
ProxyPass        / http://127.0.0.1:8080/app
ProxyPassReverse / http://127.0.0.1:8080/app
#MANAGER
ProxyPass        /manager http://127.0.0.1:8080/manager/
ProxyPassReverse /manager http://127.0.0.1:8080/manager/
RewriteEngine On
RewriteRule ^(.*)$ http://127.0.0.1:8080/app/$1 [P,L]
</VirtualHost>

The app is the specific application you want running at this hostname. If there is no specific app, you can remove it from the arguments so

ProxyPass        / http://127.0.0.1:8080/app

becomes

ProxyPass        / http://127.0.0.1:8080/

For further security, you should comment out both manager lines, making it inaccessible to anyone. Now going to http://tomcat.latko.org will take you directly to your Tomcat app or to the Tomcat root we saw at http://localhost:8080.

6) Tomcat Startup Configuration
You can increase the memory allocated to Tomcat by modifying the startup.sh script and adding the following line at the top:

JAVA_OPTS="-Xms128m -Xmx512m"

To have Tomcat automatically start on boot, create a file in /Library/LaunchDaemons/ called “org.apache.tomcat.plist” with the contents:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Disabled</key>
<false/>
<key>Label</key>
<string>com.apache.tomcat</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/tomcat/bin/startup.sh</string>
</array>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>

If you have any questions about this process, I would be happy to answer them.

Compiling 64-bit Apache/PHP on Mac OS X 10.5.6

Update: The below installation still works on Snow Leopard with PHP 5.3. You can use the latest and greatest of each library/project below and it will still work. However, there is one gotcha. There is a bug somewhere (PHP blames Apple and vice versa) when compiling PHP. To get around this, run the following on the command line before the ./configure string:

# export EXTRA_LIBS=-lresolv;

I will update this with a new tutorial once I compile everything with Clang.

Warning: This installation was not done on a virgin machine. Everything has been tested and works on my heavily hacked system.

Ok. We’re going to compile Apache with PHP on OSX 10.5.6. To make things interesting, we’re going to do a 64-bit install. If you don’t know if your machine is 64-bit or not, follow this rule: Core Duo == 32 bit, Core 2 Duo == 64 bit. I haven’t found a way to reliably display the chip architecture from the OS X command line, but on most GNU/Linux variants, you can use lshw. On the mac, you can try `uname -p`, `arch`, `system_profiler SPHardwareDataType` but all of this will make you think you are running 32 bit. As the man page for `arch` states:

The most common use is to select the 32-bit architecture on a 64-bit processor, even if a 64-bit architecture is available.

So everything is defaulted to 32-bit. What we need to do is set some environment variables so gcc knows the architecture we want to compile against. Another thing, I’m going to do all of this as root (back off unix weenies – I know what sudo is and use it regularly, I’m not here to argue about this). You can do this with the following (the # represents the prompt):

# MACOSX_DEPLOYMENT_TARGET=10.5
# CFLAGS="-arch x86_64 -g -Os -pipe -no-cpp-precomp"
# CCFLAGS="-arch x86_64 -g -Os -pipe"
# CXXFLAGS="-arch x86_64 -g -Os -pipe"
# LDFLAGS="-arch x86_64 -bind_at_load"
# export CFLAGS CXXFLAGS LDFLAGS CCFLAGS MACOSX_DEPLOYMENT_TARGET

I’m also going to ratchet up the complexity a bit because I need a GD library, IMAP, iconv, and OpenSSL. So here goes:

1) Grab All The Tarballs
Here are the links to the tarballs needed. Most of these you can grab with `curl -O` or `curl -O -L` to follow a redirect:

I’m not going full bore with the GD Library here, I just want to create some basic graphs, manipulate images, etc. so I’m not getting XBM or WBMP. I’m going to download all this stuff into /usr/local/src/.

2) Compile The GD Libraries
First we’ll start with the GD libraries as these are pretty straight forward and shouldn’t give you any problems. When on the `make` step of each of these libraries, you’ll see the familiar “-arch x86_64”, this means we’re doing it right.

FreeType

# tar -xzvf freetype-2.3.8.tar.gz
# cd freetype-2.3.8
# ./configure
# make
# make install

libjpeg

# tar -xzvf jpegsrc.v6b.tar.gz
# cd jpeg-6b
# ./configure
# make
# make install

libpng

# tar -xzvf libpng-1.2.34.tar.gz
# libpng-1.2.34
# ./configure
# make
# make install

t1lib
You will need to modify the “configure” file after you untar the file. So open “configure” and modify line 8656 to read:

archive_cmds='$CC -arch ppc -arch ppc64 -arch i386 -arch x86_64 -g -Os  -pipe -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'

The architecture types must be explicitly stated for configure to work properly. There is an alternate method of modifying the resulting Makefile, but I won’t go into that. Commands are:

# tar -xzvf t1lib-5.1.2.tar.gz
# cd t1lib-5.1.2
# vi configure (make changes above)
# ./configure
# make without_doc
# make install

Some of these installs might give you lip about certain directories not being found. Make sure you have the following directories on your system:

/usr/local/include
/usr/local/bin
/usr/local/lib
/usr/local/man/man1

3) Compile OpenSSL
Since many components rely on this. We want to get it compiled and in place fairly early.

# tar -xzvf openssl-0.9.8j.tar.gz
# cd openssl-0.9.8j
# ./config --prefix=/usr/local/ssl
# make
# make install

4) Compile IMAP
This is pretty easy, but some extra steps need to be taken because make install doesn’t seem to exist:

# tar -xzvf imap.tar.gz
# cd imap-2007e
# make oxp
# mkdir /usr/local/imap
# cp -pr c-client /usr/local/imap/

5) Compile libicon
A very useful library that doesn’t seem to get much love. This will convert between character sets (UTF-8, etc.). Maybe dealing with Japanese characters for so long gave me this appreciation.

# tar -xzvf libiconv-1.12.tar.gz
# cd libiconv-1.12
# ./configure
# make
# make install

6) Compile Apache
This assumes you already have MySQL on your machine. The 64-bit package installer at http://dev.mysql.com/downloads/ should be all you need to install this. I would stick with 5.0.x even though 5.1 is GA (Monty of MySQL fame has some choice words about this). Even though I love compiling my own apps, MySQL does such a good job with their installer, I’ve left it to them for the past couple years.

# tar -xzvf httpd-2.2.11.tar.gz
# cd httpd-2.2.11
# './configure' '--prefix=/usr/local/apache2.2.11' '--with-included-apr' '--enable-module=most' '--enable-shared=max' '--enable-headers' '--enable-rewrite'
# make
# make install

A couple things to note:

  • You normally don’t have to explicitly state which apr to use, your system will figure this out. I had a version installed by darwin ports for subversion and the compiler wanted to use that one and would choke (this is Versions‘ fault).
  • You don’t need the enable-headers and enable-rewrite. I like to do funky things like mod_rewrite for pretty URLs and mod_proxy for Tomcat. Choice is yours.
  • From httpd-2.2.9, the configure options got all out of whack with slight syntax modifications to some important flags. To normalize this, you need to run `./buildconf` in the src directory before configuring. Seems like things are back to normal for 2.2.11.
  • In my config string, I spell out which version of the software I’m using – apache2.2.11 – then later symlink /usr/local/apache2 to /usr/local/apache2.2.11. This is useful for running multiple versions.

7) Compile PHP
The final step. Here is where you’ll be able to see if you’ve done everything above correctly.

# tar -xzvf php-5.2.8.tar.gz
# cd php-5.2.8
# './configure' '--prefix=/usr/local/php' '--with-apxs2=/usr/local/apache2.2.11/bin/apxs' '--with-zlib=/usr' '--with-mysql=/usr/local/mysql/' '--with-mysqli=/usr/local/mysql/bin/mysql_config' '--with-gd' '--with-png-dir=/usr/local/php' '--with-jpeg-dir=/usr/local/php' '--with-freetype-dir=/usr/local/php' '--with-t1lib=/usr/local/php' '--with-xmlrpc' '--with-pear' '--enable-mbstring' '--enable-cli' '--with-curl=/usr/local/' '--enable-soap' '--with-openssl=/usr/local/ssl/'
# make
# make install

Some things to note:

  • You may not need all these compile options. Pick and choose what you feel you need.
  • I compiled my own version of curl, but you can leave this out of the config string if you are ok with the default OSX curl. I’m a huge fan and power user of curl. Maybe someday I’ll write about what that means.

Other Configuration Stuff:

  • Change user/group to www:www in conf/httpd.conf
  • I’m not going to get into it too much, but make sure you compare your old httpd.conf file (/etc/apache2/httpd.conf) with the new one. There are several Apple specific directives in there to keep your webserver safe.
  • Make sure to add support for mod_php:

<IfModule mod_php5.c>
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
</IfModule>

  • If you want this new version of Apache to start automatically at startup, make sure it is enabled in sharing, then do this:

# cd /usr/sbin/
# mv apachectl apachectl.bak
# ln -s /usr/local/apache2/bin/apachectl apachectl

Now fire up apache and load a page with <? phpinfo(); ?> to see that everything has installed correctly.

I’m more than happy to answer any questions you have about this process, so fire away!

Warning: This installation was not done on a virgin machine. Everything has been tested and works on my heavily hacked system.