Emil CHERICHES

Emil CHERICHES

Hosting Websites with Apache and Nginx on Debian Wheezy

October 25, 2013 Emil C
1 Comment

Ever since the “Linux From Scratch” craziness went away I’m loving to do things “the distro way”. Doing so ensures you that your configurations won’t break when you do system upgrades and thus you can do the upgrades and be always patched and as safe as possible.

Nginx is the new comer to the web server business and people seem to love it a lot. I love it myself, but sometimes you just have web apps that won’t work on nginx or web developers that did not embrace it so you need Apache to just do the job.

Ever since PHP 5.3.3 the FPM (FastCGI Process Manager) has been included so we could have PHP’s own FastCGI interface to run PHP code and serve the output to the web server. I’ve been using it with Nginx for a while, but I was never really interested in using this technology with Apache. Now it just seems fit to use it.

Let’s say that we have a server running Debian 7 Wheezy, that has two public IP addresses. Here, for the demonstration purpose I will use 192.168.216.10 and 192.168.216.11 as the public IPs. This server was just installed, with just the standard system utilities and the OpenSSH Server.

I use vim as a text editor, so one of the first things to do on our server is to install it:

apt-get install vim-nox

And for some bits of configuration vim /etc/vim/vimrc and uncomment the lines containing:

syntax on

if has("autocmd")
  au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
endif

The first line is to ensure that the syntax will be highlighted when you open a file that has some syntax and the other lines make your editor put the cursor on the same position as it was the last time you edited the file.

We install sudo

apt-get install sudo

Than we edit the /etc/apt/sources.list and we put inside:

deb http://http.debian.net/debian wheezy main contrib non-free
deb-src http://http.debian.net/debian wheezy main contrib non-free

deb http://http.debian.net/debian wheezy-updates main contrib non-free
deb-src http://http.debian.net/debian wheezy-updates main contrib non-free

deb http://security.debian.org/ wheezy/updates main contrib non-free
deb-src http://security.debian.org/ wheezy/updates main contrib non-free

deb http://packages.dotdeb.org wheezy all
deb-src http://packages.dotdeb.org wheezy all

Notice that I also put there a non-standard repository, called dotdeb. It's basicaly a repository maintained by .... which contains always the latest stable versions of PHP, Nginx and some other software that may help you when you develop or host web pages. The next step will be to import the GPG key used to sign packages in this archive:

wget http://www.dotdeb.org/dotdeb.gpg -q -O- | apt-key add -

Our next step would be to update the repositories information and eventually update any package that might need it:

apt-get update && apt-get dist-upgrade

The next step is to install the PHP

apt-get install php5-xsl php5-xmlrpc php5-xcache php5-tidy php5-sybase php5-sqlite php5-sasl php5-rrd php5-remctl php5-redis php5-recode php5-readline php5-radius php5-pspell php5-ps php5-pinba php5-mysqlnd php5-memcache php5-mcrypt php5-imap php5-http php5-geoip php5-gd php5-gearman php5-ffmpeg php5-curl php5-cli php5-fpm

And nginx and Apache...

apt-get install nginx nginx-full apache2 apache2-mpm-worker

As a basic configuration on Apache, we make it not to listen anymore on all IPs, we edit /etc/apache2/ports.conf so it should be like this:

NameVirtualHost 192.168.216.11:80
Listen 192.168.216.11:80


    Listen 192.168.216.11:443



    Listen 192.168.216.11:443

And we also modify /etc/apache2/sites-enabled/000-default


        ServerAdmin webmaster@localhost
        ServerName localhost

        DocumentRoot /var/www
        
                Options FollowSymLinks
                AllowOverride None
        
        
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        

        ScriptAlias /cgi-bin/ /usr/lib/cgi-bin/
        
                AllowOverride None
                Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
                Order allow,deny
                Allow from all
        

        ErrorLog ${APACHE_LOG_DIR}/error.log

        # Possible values include: debug, info, notice, warn, error, crit,
        # alert, emerg.
        LogLevel warn

        CustomLog ${APACHE_LOG_DIR}/access.log combined

and restart the Apache web server

service apache2 restart

Then the same thing on Nginx. For that we edit /etc/nginx/sites-enabled/default and change the line containing:

listen 80 default_server;

to:

listen 192.168.216.10:80 default_server;

And restart nginx

service nginx restart

Then we check that everything it's ok:

root@wheezy:~# netstat -natpd |grep 80
tcp        0      0 192.168.216.10:80       0.0.0.0:*               LISTEN      9600/nginx
tcp        0      0 192.168.216.11:80       0.0.0.0:*               LISTEN      9412/apache2
root@wheezy:~#

From now on we will need to set passwords. In order to do that easily we install pwgen

apt-get install pwgen

We install a database engine, for this I have chosen to install MariaDB. For this we need to access Repository Configuration Tool to chose an appropriate mirror. We choose Debian, Debian 7 "Wheezy" and 5.5. Then we insert the repository and install mariadb-server:

apt-get install python-software-properties
apt-key adv --recv-keys --keyserver keyserver.ubuntu.com 0xcbcb082a1bb943db
add-apt-repository 'deb http://mirrors.linsrv.net/mariadb/repo/5.5/debian wheezy main'
sudo apt-get update
pwgen 16
sudo apt-get install mariadb-server

And we "secure" it:

mysql_secure_installation

And chose the appropriate options:

NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB
      SERVERS IN PRODUCTION USE!  PLEASE READ EACH STEP CAREFULLY!

In order to log into MariaDB to secure it, we'll need the current
password for the root user.  If you've just installed MariaDB, and
you haven't set the root password yet, the password will be blank,
so you should just press enter here.

Enter current password for root (enter for none):
OK, successfully used password, moving on...

Setting the root password ensures that nobody can log into the MariaDB
root user without the proper authorisation.

You already have a root password set, so you can safely answer 'n'.

Change the root password? [Y/n] n
 ... skipping.

By default, a MariaDB installation has an anonymous user, allowing anyone
to log into MariaDB without having to have a user account created for
them.  This is intended only for testing, and to make the installation
go a bit smoother.  You should remove them before moving into a
production environment.

Remove anonymous users? [Y/n] y
 ... Success!

Normally, root should only be allowed to connect from 'localhost'.  This
ensures that someone cannot guess at the root password from the network.

Disallow root login remotely? [Y/n] y
 ... Success!

By default, MariaDB comes with a database named 'test' that anyone can
access.  This is also intended only for testing, and should be removed
before moving into a production environment.

Remove test database and access to it? [Y/n] y
 - Dropping test database...
ERROR 1008 (HY000) at line 1: Can't drop database 'test'; database doesn't exist
 ... Failed!  Not critical, keep moving...
 - Removing privileges on test database...
 ... Success!

Reloading the privilege tables will ensure that all changes made so far
will take effect immediately.

Reload privilege tables now? [Y/n] y
 ... Success!

Cleaning up...

All done!  If you've completed all of the above steps, your MariaDB
installation should now be secure.

Thanks for using MariaDB!

So, the way things go every website's files reside under a different system user, under which we isolate each website's own PHP processes pool so that they could read and write on the disc only as that user. Website files should be in /home/$user/htdocs, web server log files should be in /home/$user/logs and we also need a tmp folder that holds temporary files.

cd /etc/skel/
mkdir htdocs
mkdir logs
mkdir tmp
chmod 1777 tmp

Then we add two users, for the purpose of demonstration

adduser website1
adduser website2

And we configure PHP, for that we edit the default www pool, and of course backup the original:

cd /etc/php5/fpm/pool.d
mv www.conf /root/www.conf.orig

The contents of the fie /etc/php5/fpm/pool.d/www.conf:

[www]

;prefix = /path/to/pools/$pool

user = www-data
group = www-data
listen = /var/run/php5-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0666
listen.allowed_clients = 127.0.0.1

pm = ondemand
pm.max_children = 5
pm.process_idle_timeout = 10s;
pm.max_requests = 50

;pm.status_path = /status
;ping.path = /ping
;ping.response = pong

; slowlog = logs/$pool.log.slow
; request_slowlog_timeout = 7s

; chdir = /
security.limit_extensions = .php .php3 .php4 .php5

;env[HOSTNAME] = $HOSTNAME
;env[PATH] = /usr/local/bin:/usr/bin:/bin
;env[TMP] = /tmp
;env[TMPDIR] = /tmp
;env[TEMP] = /tmp

;php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f www@my.domain.com
;php_flag[display_errors] = off
;php_admin_value[error_log] = /var/log/fpm-php.www.log
;php_admin_flag[log_errors] = on
;php_admin_value[memory_limit] = 32M

And than we edit website1.conf

[website1]

user = website1
group = website1
listen = /home/website1/php5-fpm.sock
listen.owner = website1
listen.group = website1
listen.mode = 0666
listen.allowed_clients = 127.0.0.1

pm = ondemand
pm.max_children = 5
pm.process_idle_timeout = 10s;
pm.max_requests = 50

pm.status_path = /status
ping.path = /ping
ping.response = pong

slowlog = /home/website1/logs/php.log.slow
request_slowlog_timeout = 7s

chdir = /home/website1/htdocs
security.limit_extensions = .php .php3 .php4 .php5

env[HOSTNAME] = $HOSTNAME
env[PATH] = /usr/bin:/bin
env[TMP] = /home/website1/tmp
env[TMPDIR] = /home/website1/tmp
env[TEMP] = /home/website1/tmp

php_flag[display_errors] = off
php_admin_value[error_log] = /home/website1/logs/fpm-php.log
php_admin_flag[log_errors] = on
php_admin_value[memory_limit] = 256M
php_admin_value[open_basedir] = /home/website/:/usr/share/pear/;

and copy website1.conf as website2.conf:

cp website1.conf website2.conf
vim website2.conf
:%s#website1#website2#gc
:x

And restart the PHP-FPM:

service php5-fpm restart

We configure vhost in nginx. For this we edit /etc/nginx/sites-enabled/website1

#
server {
        listen 192.168.216.10:80;

        root /home/website1/htdocs;
        index index.html index.htm index.php;

        server_name website1 www.website1;

        location / {
                try_files $uri $uri/ /index.html;
        }

        location ~ \.php$ {
                fastcgi_pass unix:/home/website1/php5-fpm.sock;
                include fastcgi_params;
        }

        location ~ /\.ht {
                deny all;
        }
}

Then we restart the Nginx

service nginx restart

And do the same thing with Apache, we edit /etc/apache2/sites-enabled/website2


        ServerAdmin webmaster@localhost
        ServerName website2
        ServerAlias www.website2

        DocumentRoot /home/website2/htdocs

        
                Options Indexes FollowSymLinks MultiViews
                AllowOverride All
                Order allow,deny
                allow from all
        
        AddType application/x-httpd-php .php
        Action application/x-httpd-php /php.fcgi virtual
        Alias /php.fcgi /fcgi-bin-php5-fpm
        FastCgiExternalServer /fcgi-bin-php5-fpm -socket /home/website2/php5-fpm.sock -pass-header Authorization

        ErrorLog ${APACHE_LOG_DIR}/error.log
        LogLevel warn
        CustomLog ${APACHE_LOG_DIR}/access.log combined

Don't forget to install fastcgi module for apache and enable it

apt-get install libapache2-mod-fastcgi
a2enmod actions
service apache2 restart

And don't forget to test. In order to do that we write on each user's htdocs folder an "index.php" file that contains:

After that we just poit our brwser to it.

linux ApachedebianFPMNginxphp
Previous Post

TIP: Debian/Ubuntu prevent accidental halts/reboots

Next Post

OpenVPN and Android

  1. Pingback: Apache+Nginx+PHP на Debian 7 | tol1k's blog
Leave a Reply Cancel reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Recent Posts
  • Flash Tasmota on the Sonoff Mini – Linux user experience
  • DokuWiki a simple solution to sorting documentation
  • I discovered Wireguard
  • Using Let’s Encrypt with CentOS (for now)
  • Let’s Encrypt is Trusted
Categories
  • from the web
  • just blog
  • linux
    • Mail Server Series
  • News
  • phones
  • Phones & Tablets
  • programing
  • security
  • Smart Home
  • Tips & Tricks
  • Uncategorized
  • Web development
  • Windows
Blogroll
  • cheriches.fr
Subscribe by Email
Recent Posts
  • Flash Tasmota on the Sonoff Mini – Linux user experience
  • DokuWiki a simple solution to sorting documentation
  • I discovered Wireguard
  • Using Let’s Encrypt with CentOS (for now)
  • Let’s Encrypt is Trusted
Categories
  • from the web (3)
  • just blog (1)
  • linux (23)
    • Mail Server Series (7)
  • News (1)
  • phones (1)
  • Phones & Tablets (2)
  • programing (1)
  • security (2)
  • Smart Home (1)
  • Tips & Tricks (15)
  • Uncategorized (3)
  • Web development (1)
  • Windows (1)
Blogroll
  • cheriches.fr
Tags cloud
adb ADS aircrack-ng Android Apache apt-get CentOS Chrome ClamAV Cluster CSS Debconf debian DKIM Dovecot EasyRSA EPEL Firefox Firewall GNOME High Availability iptables KVM linux MariaDB Milter MySQL Nginx php Postfix Postfix Admin Proxy_ARP Python release Roundcube Samba SELinux Sonoff SpamAssassin ssh Tasmota ubuntu VRRP windows Youtube
Recent Comments
  • Frank on Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot
  • Andrew Schott on Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot
  • Emil C on Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot
  • Andrew Schott on Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot
  • Emil C on Dedicated Mail Server Hosting Multiple Domains – Step 3 – Postfix and Dovecot
Proudly powered by WordPress | Theme: Fmi by Forrss.
Manage Cookie Consent
We use cookies to optimize our website and our service.
Functional cookies Always active
The technical storage or access is strictly necessary for the legitimate purpose of enabling the use of a specific service explicitly requested by the subscriber or user, or for the sole purpose of carrying out the transmission of a communication over an electronic communications network.
Preferences
The technical storage or access is necessary for the legitimate purpose of storing preferences that are not requested by the subscriber or user.
Statistics
The technical storage or access that is used exclusively for statistical purposes. The technical storage or access that is used exclusively for anonymous statistical purposes. Without a subpoena, voluntary compliance on the part of your Internet Service Provider, or additional records from a third party, information stored or retrieved for this purpose alone cannot usually be used to identify you.
Marketing
The technical storage or access is required to create user profiles to send advertising, or to track the user on a website or across several websites for similar marketing purposes.
Manage options Manage services Manage vendors Read more about these purposes
View preferences
{title} {title} {title}