You are now on my Technical Blog. My other sites: Personal Blog - Genealogy Blog - Genealogy Site

DLMax Max Westen's ramblings on OSX and PHP

Blog Tags: apache


Easiest local development environment on OSX

Nov 19, 2012

Create a folder testsite.dev in your ~/Sites folder and immediately access it with your browser by using http://testsite.dev, without changing your apache config or adding sitenames to your DNS or /etc/hosts file. That’s what you can do after following the instructions in this post!

Background

Most of the time I’ve been using specific vhost files per webdevelopment project in a vhost folder of which all vhost files will be included. All development sites are added to the /etc/hosts file, so I could access them by a friendly-name lie http://dlmax.dev.

An article by Blain Smith on his local development setup made me rethink my own setup: "Can’t I just configure it to add the domainnames to the local DNS resolution too, so I only have to create a folder and immediately be able to access the site?"

Apache configuration

Current setup

I’m using the included Apache included in OSX Mountain Lion (10.8) and modified it, so it’s using 1 conf file per vhost in the /etc/apache2/vhosts folder. These get included at the end of the file /etc/apache2/httpd.config with the line:

Include /private/etc/apache2/vhosts/*.conf

in the vhosts folder I’ve created a file 1_default.conf that contains the following:

NameVirtualHost *

<VirtualHost *>
    ServerAdmin mwesten@localhost
    DocumentRoot "/Users/mwesten/Sites"
    ServerName max.local
    ServerAlias localhost
</VirtualHost>

An example of the other files, in this case dlmax.conf then contains:

<VirtualHost *>
    ServerAdmin mwesten@localhost
    ServerName dlmax.dev
    DocumentRoot "/Users/mwesten/Sites/dlmax"
    Options -Indexes +FollowSymLinks
</VirtualHost>

Changes to this setup:

In /etc/apache2/httpd.config change the line that calls all *.conf files in the vhosts folder, to only call the virtual.conf

Include /private/etc/apache2/vhosts/virtual.conf

now create the etc/apache2/vhosts/virtual.conf to use some wildcards:

NameVirtualHost *
UseCanonicalName Off

<VirtualHost *>
  VirtualDocumentRoot "/Users/mwesten/Sites/%0"

  <Directory "/Users/mwesten/Sites">
      Options Indexes FollowSymLinks MultiViews
      AllowOverride All
      Order allow,deny
      Allow from all
  </Directory>
 # If you are experiencing problems with the PHP DOCUMENT_ROOT setting, create a
 # PHP file containing the following lines:
 #   <?php
 #    $_SERVER['DOCUMENT_ROOT'] = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['SCRIPT_FILENAME']);
 # and uncomment the following line, pointing to the just created PHP file:
 #   php_admin_value auto_prepend_file /Users/mwesten/Sites/setdocroot.php

</VirtualHost>

DOCUMENT_ROOT problems with PHP

If you are experiencing problems with your DOCUMENT_ROOT server variable, uncomment the php_admin_value line in the virtual.conf file. Add the file setdocroot.php to the path specified above and put the following in, to fix the DOCUMENT_ROOT problem described in this apache bugreport

<?php
$_SERVER['DOCUMENT_ROOT'] = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['SCRIPT_FILENAME']);

Get the local DNS names working

Because the /etc/hosts file doesn’t parse wildcards, we cannot add something like: 127.0.0.1 *.dev.

The only option is to install a local DNS server like bind or a DNS proxy like DNSMasq.

I’m using DNSMasq, because it’s the easiest to configure and less prone to configuration errors.

Install and configure DNSMasq

I’m using Homebrew as my package manager, so if you don’t use one, or use another one, you should install brew(to keep it easy) or try to follow the next steps based on your package manager.

brew install dnsmasq

Then create a textfile /usr/local/etc/dnsmasq.conf and add the following line, to redirect all *.dev sites to the local ip 127.0.0.1:

address=/.dev/127.0.0.1

Now make dnsmasq start on system-startup and start it now:

sudo cp /usr/local/Cellar/dnsmasq/2.63/homebrew.mxcl.dnsmasq.plist /Library/LaunchDaemons
sudo launchctl load -w /Library/LaunchDaemons/homebrew.mxcl.dnsmasq.plist

Configure OSX to use your local system as first DNS server

Enter your network preferences and note the DNS servers named there. In my case I’m using my router, so 192.168.10.1. Now add your loopback IP (127.0.0.1) first and then your previous addres.

Now if you try to ping some address ending in .dev it should give a reply like this:

$ ping thisisatestdomain.dev
PING thisisatestdomain.dev (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.056 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.079 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.101 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.075 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.094 ms

--- thisisatestdomain.dev ping statistics ---
5 packets transmitted, 5 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.056/0.081/0.101/0.016 ms

Pinging to www.google.com should also work, so we know external name resolutions works well too.

Adding a new local site

Adding a site is now as easy as creating a new folder in the ~/Sites folder with the name of the local sitename, so for http://dlmax.dev you would create the dlmax.dev folder.

Setting ACL on webfolders when using GIT or SVN

Aug 27, 2012

When using a VCS(Version Control System) like SVN or GIT to deploy files to your webserver you are generally faced with some troubles with permissions.

If the website/webapplication needs permissions to write files in folders, you cannot easy chown these folders like:

sudo chown -R www-data:www-data content

When setting rights this way, the webapplication works like a charm, but updating with GIT or SVN give problems, because the user executing the update isn’t www-data.

A solution to this problem is to use ACL.

To install ACL on ubuntu

Then add the rwx right to the current running user and www-data on the folders content and config/user

sudo setfacl -R -m u:www-data:rwx -m u:`whoami`:rwx content config/user
sudo setfacl -dR -m u:www-data:rwx -m u:`whoami`:rwx content config/user

Mod_security settings for Wordpress 3.x

Jan 01, 2012

If you enable mod_security on your apache server and you install the base-rules, you’ll probably notice the WordPress blog isn’t functioning correct anymore.

To fix this, you could add the following between the <vhost> tags in your vhost file that powers your blog:

<LocationMatch "/">
  SecRuleRemoveById 910006 # Google robot activity - Useful in someways but noisy for sites where you want them crawled
  SecRuleRemoveById 960015 # Request Missing an Accept Header -  Allow for Google Reader
</LocationMatch>

<LocationMatch "/wp-admin/post.php">
  SecRuleRemoveById 950006 # System Command Injection - Another rule that probably doesn't need to be disabled by everyone it stops .exe and various other extensions being passed in arguments.
</LocationMatch>

<LocationMatch "(/wp-admin/|/wp-login.php)">
  SecRuleRemoveById 950005 # Remote File Access Attempt - Probably no need to be disabled by everyone; it allows me putting /etc/ and other linux paths in posts.
  SecRuleRemoveById 950117 # Remote File Inclusion Attack - Disable to allow http:// to be passed in args
</LocationMatch>

<LocationMatch "(/wp-admin/options.php|/wp-admin/theme-editor.php|/wp-content/plugins/)">
  SecRuleRemoveById 950907 # System Command Injection
  SecRuleRemoveById 950005 # Remote File Access Attempt - Probably no need to be disabled by everyone; it allows me putting /etc/ and other linux paths in posts.
  SecRuleRemoveById 950006 # System Command Injection - Another rule that probably doesn't need to be disabled by everyone it stops .exe and various other extensions being passed in arguments.
  SecRuleRemoveById 959006 # SQL Injection Attack -
  SecRuleRemoveById 960008 # Request Missing a Host Header
  SecRuleRemoveById 960011 # GET or HEAD requests with bodies
  SecRuleRemoveById 960904 # Request Containing Content, but Missing Content-Type header

  SecRuleRemoveById phpids-17 # Detects JavaScript object properties and methods
  SecRuleRemoveById phpids-20 # Detects JavaScript language constructs
  SecRuleRemoveById phpids-21 # Detects very basic XSS probings
  SecRuleRemoveById phpids-30 # Detects common XSS concatenation patterns 1/2
  SecRuleRemoveById phpids-61 # Detects url injections and RFE attempts
</LocationMatch>

<LocationMatch "/wp-includes/">
  SecRuleRemoveById 950006 # System Command Injection - Another rule that probably doesn't need to be disabled by everyone it stops .exe and various other extensions being passed in arguments.
  SecRuleRemoveById 959006 # SQL Injection Attack -
  SecRuleRemoveById 960010 # Request content type is not allowed by policy - Allows for amongst other things spell check to work on admin area
  SecRuleRemoveById 960012 # Require Content-Length to be provided with every POST request - Same as above

  SecRuleRemoveById phpids-17 # Detects JavaScript object properties and methods
  SecRuleRemoveById phpids-20 # Detects JavaScript language constructs
  SecRuleRemoveById phpids-21 # Detects very basic XSS probings
  SecRuleRemoveById phpids-30 # Detects common XSS concatenation patterns 1/2
  SecRuleRemoveById phpids-61 # Detects url injections and RFE attempts
</LocationMatch>

There are a lot more exceptions, but these work in my situation at the moment. If you have good additional suggestions for mod_security exceptions or idea’s on improving security within these rules for WordPress, contact me and I might update the post or write a follow-up….

Happy and safe sitebuilding…

Installing xDebug 2.0.4 or 2.1 on OSX

Jan 13, 2009

In my previous post we installed the latest apache and php from source and now I’d like to install xDebug to it. As stated in the comments on the previous post, I like living on the edge, so I build it myself, instead of using packages like MAMP or XAMMP or using binaries. With that out of the way we can prepare our system for the addition of PHP modules.

Because we didn’t need these commands for normal operation, phpize and php-config were still the standard Apple ones. We now need these commands, so we’ll make sure,just in case, the latest ones are used; open up your terminal and execute the next lines:

sudo mv /usr/bin/phpize /usr/bin/phpize-leopard
sudo ln -s /opt/local/php/bin/phpize /usr/bin/phpize
sudo mv /usr/bin/php-config /usr/bin/php-config-leopard
sudo ln -s /opt/local/php/bin/php-config /usr/bin/php-config

Create a folder to contain the sources for xDebug. It’s fine to use a filder in your userdir, so we’ll be using the ‘source’ folder in your homedirectory(if you want you can choose another folder).

mkdir ~/source
cd ~/source

Now you can go along two paths:

  1. Download the sources for the **stable release(2.0.4)** of the xDebug package and extract it to a folder(a folder source/xdebug in your homedirectory is fine). Enter the next commands to download and extract the source:
    curl -C - -O http://xdebug.org/files/xdebug-2.0.4.tgz
    tar xzf xdebug-2.0.4.tgz
    cd xdebug-2.0.4
    
  2. Get the **latest version(2.1 unstable)** by downloading from CVS. The advantage is you can use several newer features (like errors that contain a link to the file and linenumber, opening in your IDE or editor of choice). Execute the following commands:
    mkdir ~/source
    cd ~/source
    cvs -d :pserver:srmread@cvs.xdebug.org:/repository login
    
    Then enter the password srmread and issue the next commands;
    cvs -d :pserver:srmread@cvs.xdebug.org:/repository co xdebug
    cd xdebug
    

Now we have the sources in the source/xdebug folder in our homedirectory(make sure you are in the folder containing the config.m4 file). Prepare this package for the php version at hand by using the next command:

phpize

Then we need to set some parameters to ensure proper compiling on the mac(this should work on all flavors; Intel and PPC based Macs):

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

Then we can compile and build the module:

./configure --enable-xdebug
make

We’ll copy the module to the PHP modules folder, because that’s were it’s going to be used ;)

sudo cp modules/xdebug.so /opt/local/php/modules

Add the following to the end of the /opt/local/php/lib/php.ini file:

[xdebug]
zend_extension=/opt/local/php/modules/xdebug.so

Now restart your webserver to incorporate the changes to the php.ini file:

sudo apachectl restart

If you go to the testpage we created in the last blogpost(or if you create a new php file containing phpinfo(); in your webroot), it should then show the following bar at the top:

for version 2.0.4:

phpinfo() banner for xDebug 2.0.4

and for 2.1 dev:

phpinfo() banner for xDebug 2.1-dev

And almost at the bottom of the page there should be all xDebug parameters.

Now every time we use a var_dump() it looks like this:

xDebug var_dump()

And if an error occurs, it shows like this:

xDebug PHP Error

At this time we have more advanced error reporting and we have better looking var_dumps() and we can connect a debugger to xDebug and can use xDebug for application profiling.

More on how to do this on MacOSX in the next post.

Installing PHP 5.2.8 on OSX Leopard 10.5.6

Dec 29, 2008

Because I travel a lot by train, it’s easy to have a local development environment with me. Because OSX Leopard contains Apache2 and PHP 5.2.6, I installed MySQL, ZF, PEAR, setup the vhost conf for apache and added the path to the ZF and PEAR libraries to /etc/php.ini. This seemed to work fine for a day or two, but after that I needed to use the PDO_MySQL library. This didn’t really work… The fact is that PDO_SQLite and PDO_SQLite2 are compiled along the installed PHP library, but PDO_MySQL isn’t… Big FAIL!.

So, we’ll have to setup a new PHP/Apache2 combo…..

Okay let’s start:

1. Install the Apple Developer tools

If you haven’t done it already, install the Developer Tools(XCode 3) from the OSX DVD

2. Install and update MacPorts

If you haven’t installed MacPorts on your system, do so by downloading it from the MacPorts website and running the installer. Now open a terminal window and update MacPorts:

sudo port selfupdate
sudo port sync

3. Install apache2

Create the following directory and symlink for the correct use of MySQL (the install searches there for libraries):

sudo mkdir /usr/local/mysql/lib/mysql
sudo ln -sf /usr/local/mysql/lib/lib* /usr/local/mysql/lib/mysql/

Install Apache2:

sudo port install apache2

Let the apache2 process be autostarted by the system:

sudo launchctl load -w /Library/LaunchDaemons/org.macports.apache2.plist

Move the old Apache stuff out of the way:

sudo mv /usr/sbin/apachectl /usr/sbin/apachectl-leopard
sudo ln -s /opt/local/apache2/bin/apachectl /usr/local/bin/apachectl

Copy the sample conf file and make it the default

sudo cp /opt/local/apache2/conf/httpd.conf.sample /opt/local/apache2/conf/httpd.conf

Now you can modify your apache settings to your liking, but remember to use only the ones in the /opt/local/apache2/conf directory; the old configs(/etc/apache2/conf) are not used anymore.

4. Install the additional stuff needed

Then make sure we have everything installed we want in there; I want: GD libraries, iconv, PDO_MySQL, curl

sudo port install jpeg
sudo port install libpng
sudo port install freetype
sudo port install libmcrypt
sudo port install tidy
sudo port install libiconv

Rename the default iconv.h because it generates errors while compiling PHP

sudo mv /usr/include/iconv.h /usr/include/iconv.h.leo_orig
sudo ln -s /opt/local/include/iconv.h /usr/include/iconv.h

5. Download, configure and install PHP

Download the php5.2.8.tar.gz file from the PHP website. go to your download directory and run

tar xvzf php-5.2.8.tar.gz 

Then move this folder to the /opt/local/php-5.2.8 folder

sudo mv php-5.2.8 /opt/local/

Then create a symlink that you can compile against:

sudo ln -s /opt/local/php-5.2.8 /opt/local/php

Go into the newly created ‘folder’:

cd /opt/local/php/

Now configure PHP:

'./configure' \
'--prefix=/opt/local/php' \
'--with-apxs2=/opt/local/apache2/bin/apxs' \
'--with-xsl=/usr' \
'--with-tidy=/opt/local' \
'--with-ldap=/usr' \
'--with-kerberos=/usr' \
'--enable-mbregex' \
'--enable-ftp' \
'--with-iodbc=/usr' \
'--with-curl=/usr' \
'--enable-mbstring' \
'--with-gd' \
'--with-jpeg-dir=/opt/local' \
'--with-png-dir=/opt/local' \
'--with-zlib-dir' \
'--enable-sockets' \
'--enable-exif' \
'--with-mcrypt=/opt/local' \
'--enable-soap' \
'--with-mysql=/usr/local/mysql' \
'--with-mysqli=/usr/local/mysql/bin/mysql_config' \
'--with-pdo-mysql=/usr/local/mysql/bin/mysql_config' \
'--with-mysql-sock=/tmp/mysql.sock' \
'--with-freetype-dir=/opt/local' \
'--with-openssl=/opt/local' \
'--with-iconv=/usr' \
'--with-libxml-dir=/usr' \
'--with-xmlrpc' \
'--enable-cli'

Then make and install php:

sudo make
sudo make install

And rename the old PHP and create a symlink to the new binary:

sudo mv /usr/bin/php /usr/bin/php-leopard
sudo ln -s /opt/local/php/bin/php /usr/bin/php

copy the new php.ini file and edit it to your liking:

sudo cp php.ini-dist lib/php.ini

Note: The new php.ini file in use is the one located at: /opt/local/php/lib/php.ini

6. Restart the webserver

Up until now the old webserver was running. Shut it down and then start the new apache2:

sudo apachectl-leopard stop
sudo apachectl start

If all went well, Apache is running and PHP scripts get executed. Please check the installed features by calling a page with the following code on it, to ensure everything is installed.

In the next post we will add xDebug to the stack and later on the debugging environment is setup for different IDEs.

Part2: Installing xDebug on OSX