Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Install Apache with Homebrew

Install Apache with Homebrew

Installing Apache

# Start by stopping the built-in Apache, if it's running, and prevent it from starting on boot.
# This is one of very few times you'll need to use sudo:
sudo launchctl unload /System/Library/LaunchDaemons/org.apache.httpd.plist 2>/dev/null

# We need to tap homebrew-dupes because "homebrew-apache/httpd22" relies on "homebrew-dupes/zlib"
# and install Apache 2.2 with the event MPM, and we'll use Homebrew's OpenSSL library
# since it's more up-to-date than OS X's:
brew tap homebrew/dupes
brew install -v homebrew/apache/httpd22 --with-brewed-openssl --with-mpm-event

# In order to get Apache and PHP to communicate via PHP-FPM, we'll install the mod_fastcgi module:
brew install -v homebrew/apache/mod_fastcgi --with-brewed-httpd22

Setting up Apache

# To prevent any potential problems with previous mod_fastcgi setups,
# let's remove all references to the mod_fastcgi module (we'll re-add the new version later):
sed -i '' '/fastcgi_module/d' $(brew --prefix)/etc/apache2/2.2/httpd.conf

# Add the logic for Apache to send PHP to PHP-FPM with mod_fastcgi, and reference
# that we'll want to use the file ~/Sites/httpd-vhosts.conf to configure our VirtualHosts.
# We need to run this command in a subprocess
(export USERHOME=$(dscl . -read /Users/`whoami` NFSHomeDirectory | awk -F"\: " '{print $2}') ; export MODFASTCGIPREFIX=$(brew --prefix mod_fastcgi) ; cat >> $(brew --prefix)/etc/apache2/2.2/httpd.conf <<EOF

# Vitor Britto - Changes

# Load PHP-FPM via mod_fastcgi
LoadModule fastcgi_module    ${MODFASTCGIPREFIX}/libexec/mod_fastcgi.so

<IfModule fastcgi_module>
  FastCgiConfig -maxClassProcesses 1 -idle-timeout 1500

  # Prevent accessing FastCGI alias paths directly
  <LocationMatch "^/fastcgi">
    Order Deny,Allow
    Deny from All
    Allow from env=REDIRECT_STATUS
  </LocationMatch>

  FastCgiExternalServer /php-fpm -host 127.0.0.1:9000 -pass-header Authorization -idle-timeout 1500
  ScriptAlias /fastcgiphp /php-fpm
  Action php-fastcgi /fastcgiphp

  # Send PHP extensions to PHP-FPM
  AddHandler php-fastcgi .php

  # PHP options
  AddType text/html .php
  DirectoryIndex index.php index.html
</IfModule>

# Include our VirtualHosts
Include ${USERHOME}/Sites/httpd-vhosts.conf
EOF
)

# We'll also create folders for logs and SSL files:
mkdir -pv ~/Sites/{logs,ssl}

# Let's populate the ~/Sites/httpd-vhosts.conf file:
touch ~/Sites/httpd-vhosts.conf

(export USERHOME=$(dscl . -read /Users/`whoami` NFSHomeDirectory | awk -F"\: " '{print $2}') ; cat > ~/Sites/httpd-vhosts.conf <<EOF
#
# Listening ports.
#
#Listen 8080  # defined in main httpd.conf
Listen 8443

#
# Use name-based virtual hosting.
#
NameVirtualHost *:8080
NameVirtualHost *:8443

#
# Set up permissions for VirtualHosts in ~/Sites
#
<Directory "${USERHOME}/Sites">
    Options Indexes FollowSymLinks MultiViews
    AllowOverride All
    Order allow,deny
    Allow from all
</Directory>

# For http://localhost in the users' Sites folder
<VirtualHost _default_:8080>
    ServerName localhost
    DocumentRoot "${USERHOME}/Sites"
</VirtualHost>
<VirtualHost _default_:8443>
    ServerName localhost
    Include "${USERHOME}/Sites/ssl/ssl-shared-cert.inc"
    DocumentRoot "${USERHOME}/Sites"
</VirtualHost>

#
# VirtualHosts
#

## Manual VirtualHost template for HTTP and HTTPS
#<VirtualHost *:8080>
#  ServerName project.dev
#  CustomLog "${USERHOME}/Sites/logs/project.dev-access_log" combined
#  ErrorLog "${USERHOME}/Sites/logs/project.dev-error_log"
#  DocumentRoot "${USERHOME}/Sites/project.dev"
#</VirtualHost>
#<VirtualHost *:8443>
#  ServerName project.dev
#  Include "${USERHOME}/Sites/ssl/ssl-shared-cert.inc"
#  CustomLog "${USERHOME}/Sites/logs/project.dev-access_log" combined
#  ErrorLog "${USERHOME}/Sites/logs/project.dev-error_log"
#  DocumentRoot "${USERHOME}/Sites/project.dev"
#</VirtualHost>

#
# Automatic VirtualHosts
#
# A directory at ${USERHOME}/Sites/webroot can be accessed at http://webroot.dev
# In Drupal, uncomment the line with: RewriteBase /
#

# This log format will display the per-virtual-host as the first field followed by a typical log line
LogFormat "%V %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combinedmassvhost

# Auto-VirtualHosts with .dev
<VirtualHost *:8080>
  ServerName dev
  ServerAlias *.dev

  CustomLog "${USERHOME}/Sites/logs/dev-access_log" combinedmassvhost
  ErrorLog "${USERHOME}/Sites/logs/dev-error_log"

  VirtualDocumentRoot ${USERHOME}/Sites/%-2+
</VirtualHost>
<VirtualHost *:8443>
  ServerName dev
  ServerAlias *.dev
  Include "${USERHOME}/Sites/ssl/ssl-shared-cert.inc"

  CustomLog "${USERHOME}/Sites/logs/dev-access_log" combinedmassvhost
  ErrorLog "${USERHOME}/Sites/logs/dev-error_log"

  VirtualDocumentRoot ${USERHOME}/Sites/%-2+
</VirtualHost>
EOF
)

# Create the SSL files:
(export USERHOME=$(dscl . -read /Users/`whoami` NFSHomeDirectory | awk -F"\: " '{print $2}') ; cat > ~/Sites/ssl/ssl-shared-cert.inc <<EOF
SSLEngine On
SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW
SSLCertificateFile "${USERHOME}/Sites/ssl/selfsigned.crt"
SSLCertificateKeyFile "${USERHOME}/Sites/ssl/private.key"
EOF
)

openssl req \
  -new \
  -newkey rsa:2048 \
  -days 3650 \
  -nodes \
  -x509 \
  -subj "/C=US/ST=State/L=City/O=Organization/OU=$(whoami)/CN=*.dev" \
  -keyout ~/Sites/ssl/private.key \
  -out ~/Sites/ssl/selfsigned.crt

# Start Homebrew's Apache and set to start on login:
ln -sfv $(brew --prefix httpd22)/homebrew.mxcl.httpd22.plist ~/Library/LaunchAgents
launchctl load -Fw ~/Library/LaunchAgents/homebrew.mxcl.httpd22.plist

# The following command will create the file /Library/LaunchDaemons/co.echo.httpdfwd.plist
# as root, and owned by root, since it needs elevated privileges:
sudo bash -c 'export TAB=$'"'"'\t'"'"'
cat > /Library/LaunchDaemons/co.echo.httpdfwd.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
${TAB}<key>Label</key>
${TAB}<string>co.echo.httpdfwd</string>
${TAB}<key>ProgramArguments</key>
${TAB}<array>
${TAB}${TAB}<string>sh</string>
${TAB}${TAB}<string>-c</string>
${TAB}${TAB}<string>echo "rdr pass proto tcp from any to any port {80,8080} -> 127.0.0.1 port 8080" | pfctl -a "com.apple/260.HttpFwdFirewall" -Ef - &amp;&amp; echo "rdr pass proto tcp from any to any port {443,8443} -> 127.0.0.1 port 8443" | pfctl -a "com.apple/261.HttpFwdFirewall" -Ef - &amp;&amp; sysctl -w net.inet.ip.forwarding=1</string>
${TAB}</array>
${TAB}<key>RunAtLoad</key>
${TAB}<true/>
${TAB}<key>UserName</key>
${TAB}<string>root</string>
</dict>
</plist>
EOF'

# Load it!
sudo launchctl load -Fw /Library/LaunchDaemons/co.echo.httpdfwd.plist
@tomzi
Copy link

tomzi commented Nov 4, 2016

Hello,
Awesome tuto!
I did everything you mentioned but when i try to execute my project url i have a 500 error and the log file says :
[Fri Nov 04 15:43:08 2016] [error] [client 127.0.0.1] FastCGI: incomplete headers (0 bytes) received from server "/php-fpm"

Could you plase help me ?
Thanks a lot!

Thomas

@derkhadim
Copy link

derkhadim commented Apr 19, 2017

Thank you so much @vitorbritto

@BoDonkey
Copy link

BoDonkey commented Apr 23, 2017

Thanks @vitorbritto!
Things seem to be working, but I got the warning that "--with-brewed-openssl" was not an option for the formula.

One change you might want to consider is changing:
"brew install -v homebrew/apache/mod_fastcgi --with-brewed-httpd22"
to
"brew install -v homebrew/apache/mod_fastcgi --with-homebrew-httpd22"
I got the warning that the brewed option was deprecated.

@vukanac
Copy link

vukanac commented Apr 25, 2018

brew install -v homebrew/apache/httpd22 --with-brewed-openssl --with-mpm-event
Error: homebrew/apache was deprecated. This tap is now empty as all its formulae were migrated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment