This is an old revision of the document!
Table of Contents
First, create the Universe...
In this guide, I'm just gonna do everything as root unless otherwise specified.
Install Debian 7, following the Naptastic Initial guide. During the install process:
- De-select Graphical Desktop Environment and Laptop.
- Select Web Server, SQL Database, and SSH server.
Apache
Apache is already installed by virtue of your having selected “Web Server” in the installer.
Change to a Threaded Multi-Process Module (MPM)
Change Apache to the Event MPM and install the development libraries
apt-get install apache2-mpm-event apache2-threaded-dev
Enable mod_proxy_fcgi
a2enmod proxy_fcgi
(something like that anyway. Tab-complete is your friend.)
Tune Apache
Find this section in /etc/apache2/apache2.conf:
<IfModule mpm_event_module> StartServers 2 MinSpareThreads 25 MaxSpareThreads 75 ThreadLimit 64 ThreadsPerChild 25 MaxClients 150 MaxRequestsPerChild 0 </IfModule>
Change it to look like this:
<IfModule mpm_event_module> StartServers 16 ServerLimit 16 MaxClients 1024 MinSpareThreads 32 MaxSpareThreads 96 ThreadLimit 64 ThreadsPerChild 64 MaxRequestsPerChild 0 </IfModule>
What we're doing here is tuning Apache to handle the largest possible number of simultaneous connections while consuming the least resources and producing the fewest errors.
ThreadLimit
and ThreadsPerChild
are set to 64. This is a good value, and also convenient because on the Apache scoreboard, each line is 64 clients wide, so it makes it easier to read.
MaxClients
needs to be equal to ThreadsPerChild
* ServerLimit
.
MinSpareThreads
and MaxSpareThreads
should not be multiples of ThreadLimit. That will lead to need to constant spawning and reaping of server processes, adding latency and wasting CPU time. If a server is very busy, or traffic is very spiky, these are the values you want to increase first.
Timeout
Then find the Timeout
variable and change it to 15 instead of 300. This is how long Apache will wait for a new connection to send a request before giving up on it. Having it so long allows attackers to just saturate the server with new connections. Lowering it makes that kind of attack more difficult. (20 times more difficult, to be precise.) You could probably lower this to 10 or 5 seconds, but… let's not get too crazy, eh?
KeepAlive
Make sure KeepAlive is turned on.
MySQL
apt-get -y install mysql-server mysql-client
Since Debian Buster, I haven't needed a .my.cnf. If you need it, the format of ~/.my.cnf is as follows:
[client] user="root" password="password"
You can create a .my.cnf file in any user's home directory so they can do mysql stuff from the shell without having to constantly supply their MySQL username and password.
- Don't give users the root password or grant them privileges on *.*.
- chmod 600
PHP
You'll need these:
apt-get -y install libxml2-dev zlib1g-dev libbz2-dev libcurl4-openssl-dev libjpeg8-dev libpng12-dev libmcrypt-dev libaspell-dev libpspell-dev libtidy-dev libxslt1-dev
Download and build PHP to include everything we'll need:
cd
curl http://www.php.net/get/php-7.0.16.tar.xz/from/this/mirror | xz -d | tar -x
cd php-7.0.16/
./configure --enable-fpm --prefix=/opt/php70 --enable-bcmath --enable-calendar --enable-ftp --enable-libxml --enable-mbstring --with-gd --with-jpeg-dir=/usr --with-png-dir=/usr --enable-gd-native-ttf --with-mcrypt --enable-pdo --enable-soap --enable-sockets --enable-wddx --with-pcre-regex --with-pdo-mysql=shared --with-pic --with-pspell --with-tidy --with-xmlrpc --with-xsl --with-zlib --with-curl --with-mysqli
make
make install
Path is wrong
Install
php.ini
:
cp php.ini-production /usr/local/lib/php.ini
We use systemd service definition files now, not init scripts.
Install the initscript:
cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm
chown root. !$
chmod 755 !$
update-rc.d php-fpm defaults
Path is wrong
Install the FPM-specific configuration files.
mkdir -p /usr/local/etc/pools.d/
Path is wrong
Edit the file
/usr/local/etc/php-fpm.conf
and put this in it:
include=/usr/local/etc/pools.d/*.conf [global] pid = /usr/local/var/run/php-fpm.pid error_log = /var/log/php-fpm.log
Path is wrong
In
/usr/local/etc/pools.d/
, you need to create a pool definition file for every user who will be using PHP scripts. I name them $username.conf
.
Here's what you put in each pool definition file:
[david] user = david group = david listen = /usr/local/var/run/php-fpm/david.sock listen.owner = www-data listen.group = www-data listen.mode = 0660 pm = dynamic pm.max_children = 24 pm.start_servers = 1 pm.min_spare_servers = 1 pm.max_spare_servers = 2 pm.max_requests = 32768 ;pm.status_path = /fpm-status
Path is wrong
Of course, change 'david' to whatever username you're using. And you might have to create /usr/local/var/run/php.fpm
At this point, PHP-FPM is ready to start if you want.
service php-fpm start
LAMP stack done.
Time to create some sites. By Debian convention, VirtualHost (vhost) definition files go in /etc/apache2/sites-available. By Naptastic convention, the vhost definition file is named the same as the ServerName directive contained within, plus .conf because Apache 2.4 expects .conf. So, the vhost file for naptastic.com is named naptastic.com.conf and www.naptastic.com is a ServerAlias.
Here's the format for virtualhost files:
<VirtualHost *:80> ServerName blog.naptastic.com ServerAdmin naptastic@gmail.com DocumentRoot /var/www/blog.naptastic.com/ <Directory /> Options -FollowSymLinks -Indexes -MultiViews AllowOverride all </Directory> <Directory /var/www/blog.naptastic.com/> DirectoryIndex index.php Options -Indexes -FollowSymLinks -MultiViews AllowOverride all </Directory> ErrorLog ${APACHE_LOG_DIR}/error.log LogLevel warn CustomLog ${APACHE_LOG_DIR}/access-logs/blog.naptastic.com combined <IfModule mod_fastcgi.c> AddType application/x-httpd-php .php Action application/x-httpd-php /php.fcgi Alias /php.fcgi /dev/shm/david-php.fcgi </IfModule> ProxyPassMatch ^/(.*\.php)$ fcgi://127.0.0.1:9000/var/www/blog.naptastic.com/$1 </VirtualHost>
- This is specific to one site. Needs to be generalized.
- This vhost is full of Apache 2.2 stuff and talks to FPM over a TCP socket instead of a socket file. Please update from an existing, optimized site.