We have come a long way from the early days of the internet, there are many choices regarding to services and servers. It can be a bit tricky trying to setup your own server, especially if you’re new to it – either coming from a shared host or deciding to simply take the plunge. There are many choices for web servers. Although by far one of the most popular and easiest to configure on a server is Apache, it is not necessarily the best for all needs. Luckily there are other server demons that are around such as IIS (Even though it is a Windows only product, it is quite popular), Ligttpd, and ningx. The latter two are both light resources; however, I decided to switch to nginx.
What is nginx?
nginx is a open source lightweight high-performance web server and reverse proxy (for both email and http) that runs on most common operating systems including Linux and Windows (http://www.kevinworthington.com/nginx-for-windows/). Of course not everything works straight out of the box for example PHP support is not built in but is easy to add to the system. Before you begin you should know that the configuration in nginx is different than in Apache. If you’re wondering why to bother switching any other web server since there are compatibility issues; the reason is simple – memory usage. Switching to nginx (at least for me) cut back my http server resources from 30-50% to just 2-4%. Granted sites such as wordpress.com and sourceforge.net use it.
Getting Started
For the past few months I’ve been tinkering with nginx on different Linux systems (Ubuntu and Arch Linux) and while the package manager builds have most things needed for a web server, they do lack some features that could be helpful. I decided to compile my own version with the features I needed, however if your not comfortable with this then in the configuration just skip down to the part for setting up nginx.
First there are some prerequisites that we’ll need to compile spawnfcgi and nginx. There are other packages you might need depending on what you add in the configuration, I may have inadvertently forgotten some in which case let me know.
Setting up nginX
Here’s the configuration script I used for nginx on Arch
--sbin-path=/usr/sbin/nginx \
--pid-path=/var/run/nginx.pid \
--lock-path=/var/lock/nginx.lock \
--http-client-body-temp-path=/var/spool/nginx/client_body_temp \
--http-proxy-temp-path=/var/spool/nginx/proxy_temp
--http-fastcgi-temp-path=/var/spool/nginx/fastcgi_temp
--http-log-path=/var/log/nginx/access.log
--error-log-path=/var/log/nginx/error.log
--user=http \
--with-ipv6 \
--group=http \
--with-http_ssl_module \
--with-http_flv_module \
--with-http_gzip_static_module \
--without-mail_pop3_module \
--without-mail_imap_module \
--without-mail_smtp_module
Basically I disabled all the mail proxy modules and added a few other modules that were not loaded in the pacman version, (such as http_flv). This lets us add custom modules if we wanted to with this flag –add-module=/path/to/module. Once down adding what you want then just configure and get compiling. Depending on your system you may need to change the paths I setup, but they should be the exact same as the pacman package. That said, if you want to install the pacman package you should be able to and then follow along below. Next we need to compile.
$ sudo make install
Setting up spawn-fcgi
Until recently the spawn-fcgi source was only available as part of lighttpd however it is now its own package so we simply need to fetch it and get started. There is nothing really tricky about spawn a href=”http://redmine.lighttpd.net/projects/spawn-fcgi/news”>fcgi, I just used the defaults /usr/local/ as the path, if you need to change it feel free to. The current version at the time of writing was 1.6.3, so the tutorial will be using that.
$ ./configure && make && make install
We also need to make a rc script so we can get php-cgi to start and stop easily, below is one I made up:
# general config
NGINX_CONFIG="/etc/nginx/conf/nginx.conf"
. /etc/rc.conf
. /etc/rc.d/functions
function check_config {
stat_busy "Checking configuration"
/usr/sbin/nginx -t -c "$NGINX_CONFIG"
if [ $? -ne 0 ]; then
stat_die
else
stat_done
fi
}
case "$1" in
start)
check_config
stat_busy "Starting Nginx"
if [ -s /var/run/nginx.pid ]; then
stat_fail
# probably ;)
stat_busy "Nginx is already running"
stat_die
fi
/usr/sbin/nginx -c "$NGINX_CONFIG" &>/dev/null
if [ $? -ne 0 ]; then
stat_fail
else
add_daemon nginx
stat_done
fi
;;
stop)
stat_busy "Stopping Nginx"
kill -QUIT `cat /var/run/nginx.pid` &>/dev/null
if [ $? -ne 0 ]; then
stat_fail
else
rm_daemon nginx
stat_done
fi
;;
restart)
$0 stop
sleep 1
$0 start
;;
reload)
check_config
if [ -s /var/run/nginx.pid ]; then
status "Reloading Nginx Configuration" kill -HUP `cat /var/run/nginx.pid`
fi
;;
check)
check_config
;;
*)
echo "usage: $0 {start|stop|restart|reload|check}"
esac
cat: restart: No such file or directory
Getting nginx setup
Now that everything is compiled and installed, nginx needs to be configured for any virtual-hosts that you may have. Also we need to setup wordpress which requires a few other configuration options other then the normal ones. As I said before configuration in nginx is different then in Apache, there is no httpd-vhost.conf, we will have to make one. Go to your /etc/nginx/conf directory, and make a new directory called sites, in here we will store all the virtual hosts that will be loaded. Once this directory is created go to it and create a new file called default.conf in your favorite editor. Now we will begin configuration of nginx for the first site and for Wordpress.
nginx.conf
worker_processes 2; # Adjust to your needs
error_log logs/error.log;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer"
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
sendfile on;
tcp_nopush on;
server_names_hash_bucket_size 128; # this seems to be required for some vhosts
keepalive_timeout 65;
gzip on;
gzip_min_length 1100;
gzip_buffers 4 8k;
gzip_types text/plain;
include sites/*.conf;
}
default.conf
listen 80;
server_name mostlynothing.info www.mostlynothing.info;
charset koi8-r;
access_log /etc/nginx/logs/access.log main;
root /etc/nginx/http;
index = index.php;
location / {
# This is the equivalent of modrewrite here
try_files $uri $uri/ /index.php?q=$uri&$args;
}
# Configurre All Error Pages
error_page 404 /404.html;
error_page 403 /403.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# Give all php data to the Fast CGI handler that should be running.
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /etc/nginx/http$fastcgi_script_name;
include fastcgi_params;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
location ~ /\.ht {
deny all;
}
}
- The listen and server_name lines set what port to listen on and what domains are setup for this vhost.
- The root line sets the document root directory and index sets what page should be looked for to load. This is very important.
- The error pages are static, and on a Wordpress site not often called but its better to be safe.
- If you notice on the server block, there are several locations, the first sets the default location and rewrite rules, the second configures the fast cgi handler, the third stops people from accessing any leftover .htaccess files you may have had.
Fresh Ideas