Virtual Webhosting with nginx

Trying to set up nginx, it can be tough to find a complete guide/howto to get everything working. Here we'll try to put everything in one spot for the Gentoo user. Nginx (pronounced "engine x") is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. Written by Igor Sysoev in 2005, Nginx now hosts between 1% and 4% of all domains worldwide. Although still in beta, Nginx is known for its stability, rich feature set, simple configuration, and low resource consumption.

Installation
Packages we will use:
 * nginx
 * php with php-fpm patch
 * mysql, or db of choice (optional)
 * pure-ftpd (optional)

Use flags
If you are just serving static HTML pages these aren't that important. If you want your PHP pages to work then you will need these.
 * needed for nginx:
 * fastcgi ssl (if you are going to use it) zlib (compression output can be helpful)
 * needed for php:
 * fpm cgi cli force-cgi-redirect gd (for dynamic imaging) mysql (or preferred DB) session ssl truetype xml

Then we need to get PHP on there. When trying to get nginx to process php pages, several different methods are available (a.o. the fcgi package, spawn-fcgi scripts from the lighttpd project, the standalone spawn-fcgi script based off the lighttpd scripts). We are going to use the php-fpm patchset, which is now enabled by using the fpm useflag on the dev-lang/php package.

Edit /etc/portage/package.use and add a new line:

A Modified version of php-toolkit ebuild has to be downloaded from the Gentoo bug 301279 to /usr/local/portage/app-admin/php-toolkit, as well as php-toolkit-fpm.patch to /usr/local/portage/app-admin/php-toolkit/files :

Then we can install the php ebuild, after downloading the latest php-5.2.13.ebuild (as of this writing) from Gentoo bug 208155 to /usr/local/portage/dev-lang/php :

If it says cannot find file: php-5.2.12-libpng14.patch just go to http://www.kz.kernel.org/gentoo/rsync/dev-lang/php/files/ and download php-5.2.12-libpng14.patch to it prompt path, otherwise just skip to next.

It complains about emerging by path, but it still worked. I am sure there is a more proper way to do it, if someone would like to add it here.

Go to Gentoo Bugzilla download the php-fpm init script to /etc/init.d/php-fpm and make executable.

Also note that if you have been using older versions of the php ebuild, /etc/php/cgi-php5/php-fpm.conf moved to /etc/php/fpm-php5/php-fpm.conf.

follow the prompts to do the initial setup for mysql. There are plenty of references for this i won't go into it here.

Configuring
Mysql: Should be setup with the after-install commands

Pure-ftpd: Edit /etc/conf.d/pure-ftpd

IS_CONFIGURED="yes" MISC_OTHER="-E -A -x -j -R -B"—there is a nice legend in the file that explains all the options here. These are just the ones that looked good to me.

Php-fpm: The ebuild added the php-fpm user so no need to do anything there. I left the /etc/php/cgi-php5/php-fpm.conf with its defaults. Of course look it over to avoid port conflicts or whatever. Php: I will not go into the php.ini to much there for this page. Default should work edit for your situation. File system: With a couple of basic rules we can make a new fully functional site in a matter of seconds.
 * 1) All hosts’ root directories are located in one main directory. i.e. /var/www/
 * 2) all directories in the main directory match the hostname being served i.e. www.mydomain.com or subdom.herdomain.com.
 * 3) users have their home dir with a symlink to their host inside.

So nginx will look to see if a directory exists in the main directory and if so serves up the content inside. With this a user can login, access his/her home dir get into their host root directory via the symlink and everyone is happy. I have a set of scripts that: With three commands I have a new site with db and a new user with full ftp access to that site. If you want to add ssh to the mix you could do that as well. Nginx: There are two main files to work with. Both in /etc/nginx/ Fastcgi_params—the only thing I did with this is to comment the SCRIPT_NAME line. This is required for the virtual hosting. fastcgi_param QUERY_STRING       $query_string; fastcgi_param REQUEST_METHOD     $request_method; fastcgi_param CONTENT_TYPE       $content_type; fastcgi_param CONTENT_LENGTH     $content_length;
 * 1) Check if the directory exists, if not creates it, creates a mysql DB with a random passwd.
 * 2) Creates a user with a home dir
 * 3) links a user to a site (puts the symlink in the home dir and chowns the site directory to the user.

fastcgi_param SCRIPT_NAME        /etc/nginx/spawn-fcgi; fastcgi_param REQUEST_URI        $request_uri; fastcgi_param DOCUMENT_URI       $document_uri; fastcgi_param DOCUMENT_ROOT      $document_root; fastcgi_param SERVER_PROTOCOL    $server_protocol;
 * 1) fastcgi_param SCRIPT_NAME        $fastcgi_script_name;

fastcgi_param GATEWAY_INTERFACE  CGI/1.1; fastcgi_param SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param REMOTE_ADDR        $remote_addr; fastcgi_param REMOTE_PORT        $remote_port; fastcgi_param SERVER_ADDR        $server_addr; fastcgi_param SERVER_PORT        $server_port; fastcgi_param SERVER_NAME        $server_name;

fastcgi_param REDIRECT_STATUS    200;
 * 1) PHP only, required if PHP was built with --enable-force-cgi-redirect

nginx.conf—I will just comment the changes I made in the file below. user nginx nginx; worker_processes 1; ##nice for SMP

error_log /var/log/nginx/error_log info;

events { worker_connections 8192; use epoll; }

http { include        /etc/nginx/mime.types; default_type   application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] ' '"$request" $status $bytes_sent ' '"$http_referer" "$http_user_agent" ' '"$gzip_ratio"';

client_header_timeout  10m; client_body_timeout    10m; send_timeout           10m;

connection_pool_size           256; client_header_buffer_size      1k; large_client_header_buffers    4 2k; request_pool_size              4k;

gzip on; ##recommended on, but make sure your site package/cms/blog/bb has theirs turned off. gzip_min_length 1100; gzip_buffers   4 8k; gzip_types     text/plain;

output_buffers 1 32k; postpone_output 1460; sendfile       on; tcp_nopush     on; tcp_nodelay    on;

keepalive_timeout      75 20;

ignore_invalid_headers on;

server { listen         80; ## you can put ip’s or localhost here. Or change the port. server_name    $host;  ##normally you would put the hostname here and there would be a “server” section for each host…but that is like work. server_name_in_redirect off; access_log     /var/log/nginx/localhost.access_log main; error_log      /var/log/nginx/localhost.error_log info; ## I added the most common index pages. index index.php index.html index.htm default.html default.htm; root /var/www/$host; ##make sure this points to your main site directory. location ~ .*\.php$ { include /etc/nginx/fastcgi_params; ##Includes our fastcgi setup fastcgi_pass 127.0.0.1:9000; ##make sure the port matches what it in the php-fpm.conf fastcgi_index index.php; fastcgi_param SCRIPT_FILENAME /var/www/$host$fastcgi_script_name; ##again check the directory path }       }       ##I am not using this section so I didn’t touch it. ##ssl portion # server { #      listen          127.0.0.1:443; #      server_name     localhost; #       #       ssl on; #      ssl_certificate         /etc/ssl/nginx/nginx.pem; #      ssl_certificate_key     /etc/ssl/nginx/nginx.key; #       #       access_log      /var/log/nginx/localhost.ssl_access_log main; #      error_log       /var/log/nginx/localhost.ssl_error_log info; #       #       root /var/www/localhost/htdocs; # } }

Starting services
Make sure the services start after boot:

Start them manually for the moment:

Common Issues

 * 502 bad gateway or displays php code and not content
 * check to make sure php-fpm is running and that the ip and ports match in the .conf files.
 * No input file specified
 * The problem with your configuration is that $document_root is set to "/usr/local/nginx/html" for "location ~ \.php$" context.
 * You need either move "root  html/myvhost1.com;" from "location /" context to server or add "root   html/myvhost1.com;" into "location ~ \.php$" context.
 * going to www.foo.com/bar returns nothing but www.foo.com/bar/ (with trailing /) works fine.
 * make sure server_name_in_redirect off; is set
 * .htaccess files may not work. There are guides out there to fix this.