Virtual Webhosting with nginx
| Please format this article according to the Style Guidelines and Wikification suggestions, then remove this notice {{Wikify}} from the article.
Reason(s):
|
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
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 :
ebuild php-toolkit-1.0.2.ebuild digest
emerge php-toolkit-1.0.2.ebuildThen 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 :
ebuild php-5.2.13.ebuild digest
emerge php-5.2.13.ebuildIf 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.
[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.
- All hosts’ root directories are located in one main directory. i.e. /var/www/
- all directories in the main directory match the hostname being served i.e. www.mydomain.com or subdom.herdomain.com.
- 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:
- Check if the directory exists, if not creates it, creates a mysql DB with a random passwd.
- Creates a user with a home dir
- 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:
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:
/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