Setting up a PHP development environment with nginx on Ubuntu 10.04
Nginx is a lightweight http, proxy and load balancing server. It's a serious alternative for a widely used apache. Most important advantages of nginx on a production environments are speed and small amount of memory it uses. In a development environment I really like the simple and flexible configuration.
Here's a guide how to quickly prepare PHP development environment with nginx on Ubuntu 10.04 (Lucid Lynx).
PHP
Install PHP with chosen modules:
sudo aptitude install php5-cgi php5-cli php5-common php5-curl php5-gd \ php5-imagick php5-json php5-mcrypt php5-mysql php5-pgsql php5-sqlite \ php5-xmlrpc php5-xsl php5-xdebug php-apc
Spawn FCGI
Install spawn-fcgi script:
sudo aptitude install spawn-fcgi
Copy the init script to /etc/init.d/php-cgi:
#! /bin/sh
### BEGIN INIT INFO
# Provides: php-cgi
# Required-Start: $local_fs $remote_fs $network $syslog
# Required-Stop: $local_fs $remote_fs $network $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: spawns the php-cgi
# Description: spawns the php-cgi
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
NAME=php-cgi
DESC=php-cgi
test -x $DAEMON || exit 0
PIDFILE="/var/run/$NAME.pid"
DAEMON="/usr/bin/php-cgi"
SPAWN_FCGI="/usr/bin/spawn-fcgi"
FCGI_PORT=9000
FCGI_USER="www-data"
FCGI_GROUP="www-data"
FCGI_CHILDREN=0
# Include php-cgi defaults if available
if [ -f /etc/default/php-cgi ] ; then
. /etc/default/php-cgi
fi
SPAWN_FCGI_OPTS="-f $DAEMON -a 127.0.0.1 -p $FCGI_PORT -u $FCGI_USER -g $FCGI_GROUP -C $FCGI_CHILDREN -P $PIDFILE"
set -e
. /lib/lsb/init-functions
case "$1" in
start)
echo -n "Starting $DESC: "
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec "$SPAWN_FCGI" -- $SPAWN_FCGI_OPTS || true
echo "$NAME."
;;
stop)
echo -n "Stopping $DESC: "
start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec "$DAEMON" || true
echo "$NAME."
;;
restart)
echo -n "Restarting $DESC: "
start-stop-daemon --stop --quiet --pidfile $PIDFILE --exec "$DAEMON" || true
sleep 1
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec "$SPAWN_FCGI" -- $SPAWN_FCGI_OPTS || true
echo "$NAME."
;;
status)
status_of_proc -p $PIDFILE "$DAEMON" php-cgi && exit 0 || exit $?
;;
*)
echo "Usage: $NAME {start|stop|restart|status}" >&2
exit 1
;;
esac
exit 0And allow to execute it:
sudo chmod +x /etc/init.d/php-cgi
Put the configuration to /etc/default/php-cgi:
PIDFILE="/var/run/php-cgi.pid" DAEMON="/usr/bin/php-cgi" SPAWN_FCGI="/usr/bin/spawn-fcgi" FCGI_PORT=9000 FCGI_USER="www-data" FCGI_GROUP="www-data" FCGI_CHILDREN=0
Note: You will find most recent version of my init scripts on github: http://github.com/jakzal/php-cgi.
Nginx
Install the nginx:
sudo aptitude install nginx
Save the following configuration file as a /etc/nginx/sites-available/dev.conf:
server {
listen 80;
server_name *.dev;
root /var/www/$host/web;
access_log /var/log/nginx/$host.access.log;
error_log /var/log/nginx/error.log error;
location / {
root /var/www/$host/web/;
index index.php;
# serve static files directly
if (-f $request_filename) {
access_log off;
expires 30d;
break;
}
rewrite ^(.*) /index.php last;
}
location ~ \.php {
fastcgi_index index.php;
set $script $uri;
set $path_info "";
if ($uri ~ "^(.+\.php)(/.*)") {
set $script $1;
set $path_info $2;
}
fastcgi_pass 127.0.0.1:9000;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /var/www/$host/web$script;
fastcgi_param PATH_INFO $path_info;
fastcgi_param SCRIPT_NAME $script;
}
location ~ /\.ht {
deny all;
}
}And make it available for nginx:
sudo ln -s /etc/nginx/sites-available/dev.conf /etc/nginx/sites-enabled/dev.conf
System configuration
Add yourself to www-data group and relogin:
sudo usermod -a -G www-data kuba sudo su kuba
Allow everyone in www-data group to edit websites:
sudo chown -R www-data:www-data /var/www sudo chmod -R 775 /var/www
Define your domains in /etc/hosts (this can be done much better with a dnsmasq but for now it should be sufficient):
127.0.0.1 localhost info.dev myproject.dev
Create your first website:
mkdir /var/www/info.dev/web -p echo "<?php echo phpinfo(); ?>" > /var/www/info.dev/web/index.php chown -R :www-data /var/www/info.dev chmod -R 775 /var/www/info.dev
Start php-cgi and nginx services:
sudo service php-cgi start sudo service nginx start
Open http://info.dev in your browser. We've just configured PHP to work with nginx.
Comments
5 months ago wrote:Thanks for the nginx setup walkthrough.
I have some questions about your APC setup here... you installed the php-apc module but you never actually configured APC as far I can tell. I don't think Ubuntu configures it for you when you install it. Also, I'm not sure whether your fastcgi configuration here gives you a setup where PHP is actually managing multiple child processes, which is prerequisite for shared APC caches (although it's true that you get some benefit from reusing individual PHP processes serially, you lose a lot of memory by not sharing APC between the processes). What are your APC cache stats like?
5 months ago wrote:Wow. Thanks. 2 hours ago I installed ubuntu on my laptop (first time user) and now you already helped me get my webserver up. Your instructions worked absolutely perfect. Thanks again.
5 months ago wrote:@Tom I'm not sure about apc now as I only used xcache before. I know that it gives direct, visible result just by installing it. However, I need to investigate this further. From your comment I can see that I can still do more. Thanks for noticing! BTW: Remember that it's a setup for development environment and not production.
4 months ago wrote:It's real nice article ,,, my first time using nginx and works !and could you add more info how to config .htaccess / mod_rewrite like in Apache ? coz i' always use .htaccess on my webThanks,,,
4 months ago wrote:@coder5 Glad you liked it! Basic rewrites are set in my config. You can add more if your application needs it. Unfortunately nginx has no support for anything like .htaccess.
4 months ago wrote:Hi, thanks! You installed php5-cgi but you call the php-cgi. Why? Secondly, for the initscript php-cgi, where did you get this script? instead of its URL. Is it come from Ubuntu installation? or you create yourself? Many thanks!
4 months ago wrote:@Bayu I installed php5-cgi with aptitude. That's all. No additional steps are needed. php-cgi is a symbolic link created by Ubuntu during the installation. It points to php5-cgi.
php-cgi init script was written by me based on other init script (nginx as far as I remember). It's not in Ubuntu repository and that's why it's pasted here. I've also put it on github.
4 months ago wrote:I see, I just look at /etc/alternatives/php-cgi - and not go through the final symbolic link of it :) But the your nginx's dev.conf made me should modify the contents, since it have the same port value with "default" file of Ubuntu repository. Anyway thanks a lot!
3 months ago wrote:Thanks a lot for this tuto, it made my day.
To create more php processes and handle better multiple connections, you can change this line in /etc/default/php-cgi:
FCGI_CHILDREN=10
3 months ago wrote:@Thibault thanks for your comment! I know about FCGI_CHILDREN but it's not necessarily needed on development environment.
On production it's indeed useful but I don't feel like an expert on presenting proper nginx configuration for production yet. I'd probably use php-fpm instead of spawn-fcgi.
2 months ago wrote:Hi,Thank you for your nice article. But I have small problem with this configuration if you have i.e. http://www.example.com/admin/ URL( and you've configured so that http://www.example.com/ is "root" ) the nginx doesn't send the 'admin' folders index.php to cgi, instead it throws(in FF) File Open dialog with application/x-httpd-php mime .. any ideas? Should I configure each folder separately into site conf?
2 months ago wrote:@Tero actually the only way I know is to add another location part (location /admin/). You can have common settings in "location /" section and only overwrite parts for you subdirectories. In most cases you'll need only rewrite there (rewrite ^(.*) /admin/index.php last;).
It's weird that it throws file open dialog. I didn't experience it.- Write a comment
















