Virtual Webhosting with nginx

From Gentoo Linux Wiki
Jump to: navigation, search
Please format this article according to the Style Guidelines and Wikification suggestions, then remove this notice {{Wikify}} from the article.

Reason(s):

  • split into Nginx/PHP and Nginx/Virtual hosting
  • remove duplicated info about mysql and pure-ftpd, it's not nginx specific.
  • fix PoV (I/me/we vs you/your)

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.

Contents

[edit] Installation

Packages we will use:

  • nginx
  • php with php-fpm patch
  • mysql, or db of choice (optional)
  • pure-ftpd (optional)

[edit] 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
emerge nginx

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:

dev-lang/php cgi force-cgi-redirect apache2 fpm gd mysql xml xmlreader xmlwriter json sqlite

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 :

cd /usr/local/portage/app-admin/php-toolkit

ebuild php-toolkit-1.0.2.ebuild digest

emerge php-toolkit-1.0.2.ebuild

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 :

cd /usr/local/portage/dev-lang/php/

ebuild php-5.2.13.ebuild digest

emerge php-5.2.13.ebuild

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.


chmod +x /etc/init.d/php-fpm

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.

emerge mysql

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

emerge pure-ftpd

[edit] 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:

  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.

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;

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

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;

# PHP only, required if PHP was built with --enable-force-cgi-redirect</nowiki>
fastcgi_param  REDIRECT_STATUS    200;

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;
        # }
}

[edit] Starting services

Make sure the services start after boot:

#root>

rc-update add nginx default rc-update add mysql default rc-update add pure-ftpd default rc-update add php-fpm default

Start them manually for the moment:

#root>

/etc/init.d/nginx start /etc/init.d/mysql start /etc/init.d/pure-ftpd start /etc/init.d/php-fpm start

[edit] 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.

[edit] Notes

There are also guides out there to convert apache rewrite rules to nginx if you need them. Thanks for looking I hope it helps someone

[edit] External links

Personal tools