Optimise Apache for EC2 micro instance
- by Shiyu Sekam
I'm running apache2 on a EC2 micro instance with ~600 mb RAM. The instance was running for almost a year without problems, but in the last weeks it just keeps crashing, because the server reached MaxClients.
The server basically runs few websites, one wordpress blog(not often used), company website(most used) and 2 small sites, which are just internal.
The database for the blog runs on RDS, so there's no Mysql running on this web server.
When I came to the company, the server already was setup and is running apache + mod_php + prefork. We want to migrate that in the future to a nginx + php-fpm, but it still needs further testing. So for now I have to stick with the old setup.
I also use CloudFlare DDOS protection in front of the server, because it was attacked a couple of the times in the last weeks.
My company don't want to pay money for a better web server at this point, so I have to stick with the micro instance also. Additionally the code for the website we run is really bad and slow and sometimes a single page load can take up to 15 seconds. The whole website is dynamic and written in PHP, so caching isn't really an option here. It's a customized search for users.
I've already turned off KeepAlive, which improved the performance a little bit.
My prefork config looks like the following:
StartServers 2
MinSpareServers 2
MaxSpareServers 5
ServerLimit 10
MaxClients 10
MaxRequestsPerChild 100
The server just becomes unresponsive after a while running and I've run the following command to see how many connections there are:
netstat | grep http | wc -l
75
Trying to restart apache helps for a short moment, but after that a while the apache process(es) become unresponsive again.
I've the following modules enabled(output of apache2ctl -M)
Loaded Modules:
core_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
mpm_prefork_module (static)
http_module (static)
so_module (static)
alias_module (shared)
authz_host_module (shared)
deflate_module (shared)
dir_module (shared)
expires_module (shared)
mime_module (shared)
negotiation_module (shared)
php5_module (shared)
rewrite_module (shared)
setenvif_module (shared)
ssl_module (shared)
status_module (shared)
Syntax OK
apache2.conf
# Security
ServerTokens OS
ServerSignature On
TraceEnable On
ServerName "web.example.com"
ServerRoot "/etc/apache2"
PidFile ${APACHE_PID_FILE}
Timeout 30
KeepAlive off
User www-data
Group www-data
AccessFileName .htaccess
<Files ~ "^\.ht">
Order allow,deny
Deny from all
Satisfy all
</Files>
<Directory />
Options FollowSymLinks
AllowOverride None
</Directory>
DefaultType none
HostnameLookups Off
ErrorLog /var/log/apache2/error.log
LogLevel warn
EnableSendfile On
#Listen 80
Include /etc/apache2/mods-enabled/*.load
Include /etc/apache2/mods-enabled/*.conf
Include /etc/apache2/ports.conf
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
Include /etc/apache2/conf.d/*.conf
Include /etc/apache2/sites-enabled/*.conf
Vhost of main site
<VirtualHost *:80>
ServerName www.example.com
## Vhost docroot
DocumentRoot /srv/www/jenkins/Web
## Directories, there should at least be a declaration for /srv/www/jenkins/Web
<Directory /srv/www/jenkins/Web>
AllowOverride All
Order allow,deny
Allow from all
</Directory>
## Load additional static includes
## Logging
ErrorLog /var/log/apache2/www.example.com.error.log
LogLevel warn
ServerSignature Off
CustomLog /var/log/apache2/www.example.com.access.log combined
## Rewrite rules
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www.example.com$
RewriteRule ^.*$ http://www.example.com%{REQUEST_URI} [R=301,L]
## Server aliases
ServerAlias www.example.invalid
ServerAlias example.com
## Custom fragment
<Location /srv/www/jenkins/Web/library>
Order Deny,Allow
Deny from all
</Location>
<Files ~ "^\.(.+)">
Order deny,allow
deny from all
</Files>
</VirtualHost>