Skip to content

Commit

Permalink
upstream changes
Browse files Browse the repository at this point in the history
  • Loading branch information
ustramooner committed May 14, 2013
1 parent f816eb5 commit 060678f
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 49 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ Nginx+PHP-FPM build pack
========================

This is a build pack bundling PHP and Nginx for Heroku apps.
Includes additional extensions: apc, memcache, memcached, phpredis, mcrypt, mysql, postgres, and newrelic.
Includes additional extensions: apc, memcache, memcached, phpredis, mcrypt, mysql, postgres, gd with freetype and newrelic.
Dependency management is handled by Composer.

Configuration
Expand All @@ -23,6 +23,12 @@ Create a `conf/` directory in the root of the your deployment. Any files with na

This way, you can customise settings specific to your application, especially the document root in `nginx.conf.erb`. (Note the .erb extension.)

Alternatively, the bundled `nginx.conf.erb` will automatically include all nginx configuration snippets within the application directory: `conf/nginx.d/*.conf`. This is another way that you can modify the `root` and `index` directives. Further, if the config snippets end with `.erb`, they will be parsed and have `.conf` extension appended to its filename.

### Running App-specific Scripts
Heroku now supports running a single `.profile` script in the root of your application during startup, right before `boot.sh` is executed. See <https://devcenter.heroku.com/articles/dynos#startup>.

For more advanced usage of .profile scripts, see <https://devcenter.heroku.com/articles/profiled>.

Pre-compiling binaries
----------------------
Expand All @@ -31,6 +37,7 @@ Pre-compiling binaries
Edit `support/set-env.sh` and `bin/compile` to update the version numbers.
````
$ gem install vulcan
$ vulcan create build-server-name
$ export AWS_ID="1BHAJK48DJFMQKZMNV93" # optional if s3 handled manually.
$ export AWS_SECRET="fj2jjchebsjksmMJCN387RHNjdnddNfi4jjhshh3" # as above
$ export S3_BUCKET="heroku-buildpack-php-ustramooner" # set to your S3 bucket.
Expand Down Expand Up @@ -67,7 +74,7 @@ $ support/package_newrelic
The binary package will be produced in the current directory. Upload it to Amazon S3.

### PHP
PHP requires supporting libraries to be avaliable when being built. Please have the preceeding packages built and uploaded onto S3 before continuing.
PHP requires supporting libraries to be available when being built. Please have the preceding packages built and uploaded onto S3 before continuing.

Review the `support/vulcan-build-php.sh` build script and verify the version numbers in `support/set-env.sh`.

Expand Down Expand Up @@ -121,7 +128,7 @@ heroku config:add PATH="/app/vendor/bin:/app/local/bin:/app/vendor/nginx/sbin:/a
Push deploy your app and you should see Nginx, mcrypt, and PHP being bundled.

### Declaring Dependencies using Composer
[Composer][] is the de fecto dependency manager for PHP, similar to Bundler in Ruby.
[Composer][] is the de facto dependency manager for PHP, similar to Bundler in Ruby.

- Declare your dependencies in `composer.json`; see [docs][cdocs] for syntax and other details.
- Run `php composer.phar install` *locally* at least once to generate a `composer.lock` file. Make sure both `composer.json` and `composer.lock` files are committed into version control.
Expand Down
113 changes: 74 additions & 39 deletions bin/compile
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ OUTPUT=`md5sum ${BUNDLE_DIR}/${TARGET} | cut -d ' ' -f 1`
! [ "$SUM" = "$OUTPUT" ]
}

function download_url() {
TARGET_URL="$1"
curl -s -S -O -L -m 300 --connect-timeout 60 "$TARGET_URL"
}

BIN_DIR=$(dirname $0)
BUILD_DIR=$1
CACHE_DIR=$2
Expand All @@ -58,11 +63,20 @@ export COMPOSER_HOME="${CACHE_DIR}/.composer"
# include .files when moving things around
shopt -s dotglob

mkdir -p $BUILD_DIR $CACHE_DIR ${BUNDLE_DIR} ${BUILD_DIR}/local ${BUILD_DIR}/vendor/bin ${COMPOSER_HOME}
mkdir -p $BUILD_DIR $CACHE_DIR ${BUNDLE_DIR} ${BUILD_DIR}/local ${BUILD_DIR}/vendor/bin ${COMPOSER_HOME} ${BUILD_DIR}/.profile.d

echo "-----> Fetching Manifest"
pushd ${BUNDLE_DIR} > /dev/null
curl --silent --max-time 60 -O --location $MANIFEST_URL

if [ -n "`find . -type f -atime +30`" ]
then
echo "-----> Pruning Unused Cached Bundles"
find . -type f -atime +30 -delete | indent
fi

echo "-----> Fetching Manifest"
echo ${MANIFEST_URL} | indent
download_url ${MANIFEST_URL}

# Nginx
echo "-----> Installing Nginx"
Expand All @@ -72,14 +86,16 @@ then
if check_md5 "${NGINX_FILE}"
then
echo "Bundling Nginx v${NGINX_VERSION}" | indent
curl --silent --max-time 60 -O --location $NGINX_URL
echo ${NGINX_URL} | indent
download_url ${NGINX_URL}
else
echo "Using cached Nginx v${NGINX_VERSION}" | indent
fi
else
# fetch
echo "Bundling Nginx v${NGINX_VERSION}" | indent
curl --silent --max-time 60 -O --location $NGINX_URL
echo ${NGINX_URL} | indent
download_url ${NGINX_URL}
fi

mkdir -p ${BUILD_DIR}/vendor/nginx
Expand All @@ -92,13 +108,15 @@ then
if check_md5 "${MCRYPT_FILE}"
then
echo "Bundling libmcrypt v${LIBMCRYPT_VERSION}" | indent
curl --silent --max-time 60 -O --location $MCRYPT_URL
echo ${MCRYPT_URL} | indent
download_url ${MCRYPT_URL}
else
echo "Using cached libmcrypt v${LIBMCRYPT_VERSION}" | indent
fi
else
echo "Bundling libmcrypt v${LIBMCRYPT_VERSION}" | indent
curl --silent --max-time 60 -O --location $MCRYPT_URL
echo ${MCRYPT_URL} | indent
download_url ${MCRYPT_URL}
fi

tar xzf ${MCRYPT_FILE} -C ${BUILD_DIR}/local
Expand All @@ -110,13 +128,15 @@ then
if check_md5 "${MEMCACHED_FILE}"
then
echo "Bundling libmemcached v${LIBMEMCACHED_VERSION}" | indent
curl --silent --max-time 60 -O --location ${MEMCACHED_URL}
echo ${MEMCACHED_URL} | indent
download_url ${MEMCACHED_URL}
else
echo "Using cached libmemcached v${LIBMEMCACHED_VERSION}" | indent
fi
else
echo "Bundling libmemcached v${LIBMEMCACHED_VERSION}" | indent
curl --silent --max-time 60 -O --location ${MEMCACHED_URL}
echo ${MEMCACHED_URL} | indent
download_url ${MEMCACHED_URL}
fi

tar xzf ${MEMCACHED_FILE} -C ${BUILD_DIR}/local
Expand All @@ -128,13 +148,15 @@ then
if check_md5 "${PHP_FILE}"
then
echo "Bundling PHP v${PHP_VERSION}" | indent
curl --silent --max-time 120 -O --location $PHP_URL
echo ${PHP_URL} | indent
download_url ${PHP_URL}
else
echo "Using cached PHP v${PHP_VERSION}" | indent
fi
else
echo "Bundling PHP v${PHP_VERSION}" | indent
curl --silent --max-time 120 -O --location $PHP_URL
echo ${PHP_URL} | indent
download_url ${PHP_URL}
fi

mkdir -p ${BUILD_DIR}/vendor/php
Expand All @@ -147,38 +169,41 @@ then
if check_md5 "${NEWRELIC_FILE}"
then
echo "Bundling newrelic daemon v${NEWRELIC_VERSION}" | indent
curl --silent --max-time 60 -O --location $NEWRELIC_URL
echo ${NEWRELIC_URL} | indent
download_url ${NEWRELIC_URL}
else
echo "Using cached newrelic daemon v${NEWRELIC_VERSION}" | indent
fi
else
echo "Bundling newrelic daemon v${NEWRELIC_VERSION}" | indent
curl --silent --max-time 60 -O --location $NEWRELIC_URL
echo ${NEWRELIC_URL} | indent
download_url ${NEWRELIC_URL}
fi

tar xzf ${NEWRELIC_FILE} -C ${BUILD_DIR}/local

popd > /dev/null

# Composer Installation
pushd $BUILD_DIR > /dev/null
pushd ${BUILD_DIR} > /dev/null
if [ -f "composer.json" ]
then
echo "-----> Installing dependencies using Composer"
GIT_DIR_ORIG=$GIT_DIR
GIT_DIR_ORIG=${GIT_DIR}
unset GIT_DIR

if [ ! -f "composer.phar" ]
then
echo "Fetching composer.phar" | indent
curl --silent --max-time 60 -O --location "$COMPOSER_URL"
echo ${COMPOSER_URL} | indent
download_url ${COMPOSER_URL}
fi

# do the deed!
echo "Running: php composer.phar install" | indent
LD_LIBRARY_PATH="${BUILD_DIR}/local/lib" ${BUILD_DIR}/vendor/php/bin/php composer.phar install -n | indent

export GIT_DIR=$GIT_DIR_ORIG
export GIT_DIR=${GIT_DIR_ORIG}
fi
popd > /dev/null

Expand All @@ -189,18 +214,21 @@ cp ${BUILD_DIR}/vendor/php/php/fpm/status.html ${BUILD_DIR}/status.html
cp $LP_DIR/conf/php.ini ${BUILD_DIR}/vendor/php/php.ini
cp -a $LP_DIR/conf/etc.d ${BUILD_DIR}/vendor/php/
cp $LP_DIR/conf/nginx.conf.erb ${BUILD_DIR}/vendor/nginx/conf/nginx.conf.erb
cp -n ${LP_DIR}/.profile.d/* ${BUILD_DIR}/.profile.d/
#erb $LP_DIR/conf/nginx.conf.erb > ${BUILD_DIR}/vendor/nginx/conf/nginx.conf

echo "-----> Installing boot script"
cd $BUILD_DIR
cat >boot.sh <<EOF
cat >>boot.sh <<EOF
#!/usr/bin/env bash
echo "Booting nginx"
# Override config files if provided in app.
if [ -d /app/conf ]; then
mkdir -p /app/conf/nginx.d
if [ -d /app/conf/etc.d ]; then
cp -f /app/conf/etc.d/* /app/vendor/php/etc.d/
fi
Expand All @@ -219,40 +247,47 @@ if [ -d /app/conf ]; then
fi
# Set correct port variable.
erb /app/vendor/nginx/conf/nginx.conf.erb > /app/vendor/nginx/conf/nginx.conf
if [ -d /app/conf/nginx.d ]; then
# Parse .erb into .conf.
for f in /app/conf/nginx.d/*.erb
do
if [ -r "\${f}" ];
then
erb "\${f}" > "\${f}.conf"
fi
done
fi
# Set NEWRELIC key
if [ -x "/app/local/bin/newrelic-license" ]; then
/app/local/bin/newrelic-license
fi
#set the env variables
if [ ! -f /app/vendor/php/etc/php-fpm.conf.envd ]; then
env | cut -f1 -d=| grep -v '^_\$'|grep -v PATH|grep -v COLOR| grep -v PS1 |grep -v PORT | while read var; do
echo "env[\$var]=\"\${!var}\"" >> /app/vendor/php/etc/php-fpm.conf;
done
touch /app/vendor/php/etc/php-fpm.conf.envd
# Preserve current php-fpm.conf so that env list does
# not go out of hand across restarts.
if [ -r /app/vendor/php/etc/php-fpm.conf.current ]; then
cp -f /app/vendor/php/etc/php-fpm.conf.current /app/vendor/php/etc/php-fpm.conf
else
cp -f /app/vendor/php/etc/php-fpm.conf /app/vendor/php/etc/php-fpm.conf.current
fi
touch /app/vendor/nginx/logs/access.log /app/vendor/nginx/logs/error.log /app/vendor/php/var/log/php-errors.log /app/local/var/log/newrelic/newrelic-daemon.log /app/local/var/log/newrelic/php_agent.log
mkdir -p client_body_temp fastcgi_temp proxy_temp scgi_temp uwsgi_temp
(tail --quiet -f -n 0 /app/vendor/nginx/logs/*.log /app/vendor/php/var/log/*.log /app/local/var/log/newrelic/*.log &)
# Expose Heroku config vars to PHP-FPM processes
for var in \`env | cut -f1 -d=\`; do
echo "env[\$var] = \\$\${var}" >> /app/vendor/php/etc/php-fpm.conf
done
if [ "" != "\$WARMUP_COMMAND" ]; then
bash -c "\$WARMUP_COMMAND"
fi
touch /app/vendor/nginx/logs/access.log /app/vendor/nginx/logs/error.log /app/vendor/php/var/log/php-fpm.log /app/vendor/php/var/log/php-errors.log /app/local/var/log/newrelic/newrelic-daemon.log /app/local/var/log/newrelic/php_agent.log
mkdir -p client_body_temp fastcgi_temp proxy_temp scgi_temp uwsgi_temp
(tail -f -n 0 /app/vendor/nginx/logs/*.log /app/vendor/php/var/log/*.log /app/local/var/log/newrelic/*.log &)
if [ "" != "\$NEW_RELIC_LICENSE_KEY" ]; then
newrelic-daemon -c /app/local/etc/newrelic.cfg -d error
else
echo "Disabling newrelic, no NEW_RELIC_LICENSE_KEY set"
rm /app/vendor/php/etc.d/*newrelic.ini
if [ "\${NEW_RELIC_LICENSE_KEY}" ]; then
/app/local/bin/newrelic-daemon -c /app/local/etc/newrelic.cfg -d error
fi
php-fpm
nginx
/app/vendor/php/sbin/php-fpm
/app/vendor/nginx/sbin/nginx
EOF
chmod +x boot.sh

Expand Down
4 changes: 2 additions & 2 deletions conf/php-fpm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,8 @@ process_control_timeout = 10s
; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
; will be used.
user = nobody
group = nobody
;user = nobody
;group = nobody

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
Expand Down
2 changes: 1 addition & 1 deletion conf/php.ini
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ disable_classes =
; threat in any way, but it makes it possible to determine whether you use PHP
; on your server or not.
; http://php.net/expose-php
expose_php = On
expose_php = Off

;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
Expand Down
1 change: 0 additions & 1 deletion support/ec2-build-php.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ libjpeg-dev \
libxml2-dev \
libmysqlclient-dev \
libpq-dev \
libpq-dev \
libpcre3-dev \
php5-dev \
php-pear \
Expand Down
32 changes: 32 additions & 0 deletions support/package_freetype
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

set -e
set -x
if [ "$LIFREETYPE_VERSION" == "" ]; then
echo "must set LIFREETYPE_VERSION, i.e LIFREETYPE_VERSION=2.4.12"
exit 1
fi

basedir="$( cd -P "$( dirname "$0" )" && pwd )"

# make a temp directory
tempdir="$( mktemp -t libfreetype_XXXX )"
rm -rf $tempdir
mkdir -p $tempdir
pushd $tempdir

# download and extract libfreetype
curl -L "http://download.savannah.gnu.org/releases/freetype/freetype-$LIFREETYPE_VERSION.tar.bz2" -o - | tar xj

# build and package libfreetype for heroku
vulcan build -v -s freetype-$LIFREETYPE_VERSION -o $tempdir/freetype-$LIFREETYPE_VERSION.tar.gz -p /app/local -c './configure --prefix=/app/local --disable-rpath && make install'

popd

cp $tempdir/freetype-$LIFREETYPE_VERSION.tar.gz .

echo "+ Binaries available at ./libfreetype-$LIFREETYPE_VERSION.tar.gz"
echo "+ Upload this package to Amazon S3."

# upload to s3
#s3cmd put -rr $tempdir/*.tar.gz s3://$S3_BUCKET
4 changes: 2 additions & 2 deletions support/package_php
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@ if [ "$PHP_VERSION" == "" ]; then
exit 1
fi


DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

# build and package nginx for heroku
vulcan build -v -o php-${PHP_VERSION}-with-fpm-heroku.tar.gz -p /app/vendor/php -c './vulcan-build-php.sh'
vulcan build -v -o php-${PHP_VERSION}-with-fpm-heroku.tar.gz -p /app/vendor/php -c './vulcan-build-php.sh' -s "$DIR"

echo "+ Binaries available at ./php-${PHP_VERSION}-with-fpm-heroku.tar.gz"
echo "+ Upload this package to Amazon S3."
Expand Down
1 change: 1 addition & 0 deletions support/vulcan-build-php.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ set -o pipefail

orig_dir=$( pwd )

mkdir -p /app/vendor/php
mkdir -p build && pushd build

echo "+ Fetching libmcrypt libraries..."
Expand Down
Loading

0 comments on commit 060678f

Please sign in to comment.