How To Install A Complete LEMP (Linux - EngineX (Nginx HTTP SERVER) - Mysql - PHP) Server (Not LAMP...) On Ubuntu/Debian

Want to support HowtoForge? Become a subscriber!
 
Submitted by 3uropa (Contact Author) (Forums) on Wed, 2007-10-17 18:19. :: Debian | Ubuntu | nginx

How To Install A Complete LEMP (Linux - EngineX (Nginx HTTP SERVER) - Mysql - PHP) Server (Not LAMP...) On Ubuntu/Debian

This HowTo will describe the setup of an efficient http server and mail server for small or medium configurations (as low as 96 mb). So this config is ideal for a small VPS. You can find a good choice of cheap and performant VPS (XEN) at x|encon, a german hosting company. they provide many scalable VPS solutions with pre-installed Debian and Ubuntu disc images.

Why LEMP instead of LAMP? NGINX is a great replacement for Apache with very low memory footprint and great stability.

Note: i will use the name yourdomain.com for all configurations on a fresh minimal installation of Ubuntu Feisty Fawn server edition.

We will have to install first Postfix to deal with emails and then Dovecot to deliver them with pop3 only (imap uses too much memory). But before that, let's install some useful tools we need:

apt-get install wget telnet build-essential

1. Installation of Postfix

apt-get install postfix libsasl2 sasl2-bin libsasl2-modules libdb3-util procmail

Now the beautiful blue screen will appear and Postfix will ask you some questions. Answer as follow:

General type of configuration? <-- Internet Site
Mail name? <-- yourdomain.com

Then run:

dpkg-reconfigure postfix

Again, you'll be asked some questions:

General type of configuration? <-- Internet Site
Where should mail for root go <-- [blank]
Mail name? <-- yourdomain.com
Other destinations to accept mail for? (blank for none) <-- yourdomain.com, localhost.yourdomain.com, localhost.localdomain, localhost
Force synchronous updates on mail queue? <-- No
Local networks? <-- 127.0.0.0/8
Use procmail for local delivery? <-- Yes
Mailbox size limit <-- 0
Local address extension character? <-- +
Internet protocols to use? <-- all

Type then the following commands (you can copy everything below and paste it in your terminal in one row, it will work but don't forget to hit enter to validate the last command):

postconf -e 'smtpd_sasl_local_domain ='
postconf -e 'smtpd_sasl_auth_enable = yes'
postconf -e 'smtpd_sasl_security_options = noanonymous'
postconf -e 'broken_sasl_auth_clients = yes'
postconf -e 'smtpd_recipient_restrictions = permit_sasl_authenticated,permit_mynetworks,reject_unauth_destination'
postconf -e 'inet_interfaces = all'
echo 'pwcheck_method: saslauthd' >> /etc/postfix/sasl/smtpd.conf
echo 'mech_list: plain login' >> /etc/postfix/sasl/smtpd.conf

Now we have to create the certificates for TLS that will be available both for Postfix and Dovecot:

mkdir /etc/ssl/yourdomain (the folder name can be of course anything such as the name of your mother...)
cd /etc/ssl/yourdomain
openssl genrsa -des3 -rand /etc/hosts -out yourdomain.key 1024

chmod 600 yourdomain.key
openssl req -new -key yourdomain.key -out yourdomain.csr

openssl x509 -req -days 3650 -in yourdomain.csr -signkey yourdomain.key -out yourdomain.crt

openssl rsa -in yourdomain.key -out yourdomain.key.unencrypted

mv -f yourdomain.key.unencrypted yourdomain.key
openssl req -new -x509 -extensions v3_ca -keyout cakey.pem -out cacert.pem -days 3650

Next we configure Postfix for TLS:

postconf -e 'smtpd_tls_auth_only = no'
postconf -e 'smtp_use_tls = yes'
postconf -e 'smtpd_use_tls = yes'
postconf -e 'smtp_tls_note_starttls_offer = yes'
postconf -e 'smtpd_tls_key_file = /etc/ssl/yourdomain/yourdomain.key'
postconf -e 'smtpd_tls_cert_file = /etc/ssl/yourdomain/yourdomain.crt'
postconf -e 'smtpd_tls_CAfile = /etc/ssl/yourdomain/cacert.pem'
postconf -e 'smtpd_tls_loglevel = 1'
postconf -e 'smtpd_tls_received_header = yes'
postconf -e 'smtpd_tls_session_cache_timeout = 3600s'
postconf -e 'tls_random_source = dev:/dev/urandom'
postconf -e 'myhostname = yourdomain.com'

Restart Postfix:

/etc/init.d/postfix restart

Authentication will be done by saslauthd. We have to change a few things to make it work properly. Because Postfix runs chrooted in /var/spool/postfix we have to do the following:

mkdir -p /var/spool/postfix/var/run/saslauthd

Now we have to edit /etc/default/saslauthd in order to activate saslauthd. Set START to yes and change the line OPTIONS="-c" to OPTIONS="-c -m /var/spool/postfix/var/run/saslauthd -r":

vi /etc/default/saslauthd

#
# Settings for saslauthd daemon
#
# Should saslauthd run automatically on startup? (default: no)
START=yes
# Which authentication mechanisms should saslauthd use? (default: pam)
#
# Available options in this Debian package:
# getpwent  -- use the getpwent() library function
# kerberos5 -- use Kerberos 5
# pam       -- use PAM
# rimap     -- use a remote IMAP server
# shadow    -- use the local shadow password file
# sasldb    -- use the local sasldb database file
# ldap      -- use LDAP (configuration is in /etc/saslauthd.conf)
#
# Only one option may be used at a time. See the saslauthd man page
# for more information.
#
# Example: MECHANISMS="pam"
MECHANISMS="pam"
# Additional options for this mechanism. (default: none)
# See the saslauthd man page for information about mech-specific options.
MECH_OPTIONS=""
# How many saslauthd processes should we run? (default: 5)
# A value of 0 will fork a new process for each connection.
THREADS=5
# Other options (default: -c)
# See the saslauthd man page for information about these options.
#
# Example for postfix users: "-c -m /var/spool/postfix/var/run/saslauthd"
# Note: See /usr/share/doc/sasl2-bin/README.Debian
OPTIONS="-c  -m /var/spool/postfix/var/run/saslauthd -

Start then saslauthd:

/etc/init.d/saslauthd start

To see if SMTP-AUTH and TLS work properly now run the following command:

telnet yourdomain.com 25

After you have established the connection to your Postfix mail server type

ehlo yourdomain.com

The output should look something like:

250-yourdomain.com
250-PIPELINING
250-SIZE 10240000
250-VRFY
250-ETRN
250-STARTTLS
250-AUTH PLAIN LOGIN
250-AUTH=PLAIN LOGIN
250-ENHANCEDSTATUSCODES
250-8BITMIME
250 DSN

We have now Postfix running. If you add users (adduser command) Postfix will deliver then directly emails in users mail box located in the home folder.

2. Installation of Dovecot

Dovecot configuration is pretty straight forward (remember we will use only pop3 protocol to save memory):

apt-get install dovecot-common dovecot-pop3d

Open then dovecot conf situated in /etc/dovecot/. You have to add manually the protocol you want to use (pop3 pop3s

# Protocols we want to be serving: imap imaps pop3 pop3s
# If you only want to use dovecot-auth, you can set this to "none".
#protocols = imap imaps
protocols = pop3s pop3

And uncomment the two following lines to tell Dovecot where to fint the certificate you have creted earlier

ssl_cert_file = /etc/ssl/yourdomain/yourdomain.crt
ssl_key_file = /etc/ssl/yourdomain/yourdomain.key

You have then to restart Dovecot

/etc/init.d/dovecot restart

and we have now a functionnal mail server.

3. Installation of PHP5 (along with xcache)

apt-get install php5-cli php5-cgi php5-mysql php5-xcache

Note that xcache has to be implemented manually by adding the following lines in the php.ini located in /etc/php5/cgi/ (please tune this config according to your system).

[xcache-common]
extension = xcache.so
[xcache.admin]
xcache.admin.user = "mOo"
; xcache.admin.pass = md5($your_password)
xcache.admin.pass = ""
[xcache]
; ini only settings, all the values here is default unless explained
; select low level shm/allocator scheme implemenation
xcache.shm_scheme =        "mmap"
; to disable: xcache.size=0
; to enable : xcache.size=64M etc (any size > 0) and your system mmap allows
xcache.size  =                32M
; set to cpu count (cat /proc/cpuinfo |grep -c processor)
xcache.count =                 1
; just a hash hints, you can always store count(items) > slots
xcache.slots =                8K
; ttl of the cache item, 0=forever
xcache.ttl   =                 0
; interval of gc scanning expired items, 0=no scan, other values is in seconds
xcache.gc_interval =           0
; same as aboves but for variable cache
xcache.var_size  =            32M
xcache.var_count =             1
xcache.var_slots =            8K
; default ttl
xcache.var_ttl   =             0
xcache.var_maxttl   =          0
xcache.var_gc_interval =     300
xcache.test =                Off
; N/A for /dev/zero
xcache.readonly_protection = Off
; for *nix, xcache.mmap_path is a file path, not directory.
; Use something like "/tmp/xcache" if you want to turn on ReadonlyProtection
; 2 group of php won't share the same /tmp/xcache
; for win32, xcache.mmap_path=anonymous map name, not file path
xcache.mmap_path =    "/dev/zero"
; leave it blank(disabled) or "/tmp/phpcore/"
; make sure it's writable by php (without checking open_basedir)
xcache.coredump_directory =   ""
; per request settings
xcache.cacher =               On
xcache.stat   =               On
xcache.optimizer =            On
[xcache.coverager]
; per request settings
; enable coverage data collecting for xcache.coveragedump_directory and xcache_coverager_start/stop/get/clean() functions (will hurt executing performance)
xcache.coverager =          Off
; ini only settings
; make sure it's readable (care open_basedir) by coverage viewer script
; requires xcache.coverager=On
xcache.coveragedump_directory = ""

Note: you have to adjust manually the xcache.size and xcache.var_size according to your server (it's on 0 by default, meaning that xcache isn't enabled at all). One other thing is the xcache.count variable. If you have a vps that takes advantage of 2 processors, you can put 2 instead of one.

You can do that right now even if your php configuration isn't loaded yet so everything will be in good order when Nginx and fcgi process will be started.

4. Installation of Mysql and PhpMyAdmin

apt-get install mysql mysql-server

There is often a problem with mysql to setup the root password. So the best thing to do is first stopping mysql:

/etc/init.d/mysql stop

Then update the user table

mysqld --skip-grant-tables --skip-networking &

mysql mysql

UPDATE user SET password=PASSWORD('yourrootpassword') WHERE User="root" AND Host="localhost";

quit

/etc/init.d/mysql restart

5. Installation of NGINX (Ubuntu only, see below for Debian users)

The nginx version proposed by Feisty is a prehistoric one (not to mention drapper). Fortunately, there's a place you can get the latest stable version, or if you are adventurous, the latest dev version.

Note for Debian users: I didn't find a recent .deb package so you have either the choice to compile from sources or to do a apt-get install nginx to have a not so new version. For more informations about Nginx please go to the Nginx Wiki website. You can find there the sources and a good doc about all the modules (ssl, auth_basic and so on).

wget http://technokracy.net/nginx/nginx_0.5.32~grrr-1_i386.deb

(Note that if you are running on AMD replace i386 by amd64.)

Then type:

dpkg -i nginx_0.5.32~grrr-1_i386.deb

Nginx is now up and running on default port 8000 (just in case you already have Apache or anything else on port 80).

The default root folder is Nginx-default and is located in /var/www/

To change that and to start to listen to the fast-cgi we will launch next, you have to open /etc/nginx/sites-available/default.

vi /etc/nginx/sites-available/default

You can find there all the obvious options to change and add (or uncomment the original php paragraph):

        location ~ \.php$ {
        include /etc/nginx/fastcgi_params;
        fastcgi_pass  127.0.0.1:9000;
        fastcgi_index index.php;
        fastcgi_param  SCRIPT_FILENAME  /var/www/nginx-default$fastcgi_script_name;
    }

We've just asked Nginx to listen to fcgi on port 9000. So we have to start now the fcgi process. I've chosen to use spawn-fcgi and to make my own init script of it (so the process will start after reboot). To have spawn-fcgi you have to get lighttpd configured but without the need to install it. Let's grab the latest version:

wget http://www.lighttpd.net/download/lighttpd-1.4.18.tar.bz2

tar -xvjf lighttpd-1.4.18.tar.bz2 

cd lighttpd-1.4.18

./configure

make

cp src/spawn-fcgi /usr/bin/spawn-fcgi

Note that we did not type make install so lighttpd is not running!

Then we create a shell script we can call php-fastcgi or whatever you want and place that file in /usr/bin/ to make it simple (as php5-cgi and spawn-fcgi are already there...).

touch /usr/bin/php-fastcgi

Then edit it:

vi /usr/bin/php-fastcgi

and add the following:

#!/bin/sh
/usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u www-data -f /usr/bin/php5-cgi

That means every time this script will be called, fcgi will be spawned on port 9000 for user www-data (default user).

To make it work at startup we need now to create an init script:

touch /etc/init.d/init-fastcgi

Edit and add:

vi /etc/init.d/init-fastcgi

#!/bin/bash
PHP_SCRIPT=/usr/bin/php-fastcgi
RETVAL=0
case "$1" in
    start)
      $PHP_SCRIPT
      RETVAL=$?
  ;;
    stop)
      killall -9 php
      RETVAL=$?
  ;;
    restart)
      killall -9 php
      $PHP_SCRIPT
      RETVAL=$?
  ;;
    *)
      echo "Usage: php-fastcgi {start|stop|restart}"
      exit 1
  ;;
esac      
exit $RETVAL

You may have to change the permissions there by typing:

chmod 755 /etc/init.d/init-fastcgi

Check then if it works by typing:

/etc/init.d/init-fastcgi start

You should have an answer from spawn-fcgi attributing a PID process. To make now everything working after reboot type:

update-rc.d init-fastcgi defaults

And we are done. To check if php is working as fast-cgi you can first type:

ps ax | grep php

To check then if Nginx is listening to php, create an echo command in an empty php file:

<? echo phpinfo(); ?>

Please do not use the comment function to ask for help! If you need help, please use our forum.
Comments will be published after administrator approval.
Submitted by Cramerz (not registered) on Thu, 2014-07-17 03:37.
some of those mysql commands are no longer needed and can create errors.

 mysql 5.6 is faster and needs less commands: http://www.collegetimes.tv/lemp-server/

 

 

 

Submitted by wgregori (registered user) on Sat, 2011-11-19 20:23.

thanks for the article.  It wall worked very well.  However, I can't access myphpadmin site... any quick fixes?

 

Thanks,

Wayne

Submitted by Reynold P J (not registered) on Sun, 2010-08-29 17:57.
Thank's for sharing this article -:)
Submitted by warrenonline (registered user) on Wed, 2008-03-12 16:33.

I had zero experience with Nginx and PHP FastCGI before going through this tutorial. Now that I've worked through it to the end my Nginx web server is up and running no problem.

 Thanks !!