11-Jan-2012: initial release.
Introduction.
Nginx is the second most used web server and it’s market share is still increasing. It has a different design then the most used Apache server. Because of that it is faster and can handle more load. In the Apache and Nginx articles on the Home Server series the installation of both servers on Arch Linux is already explained. This article is about migrating a running Apache server with virtual hosts to Nginx. If you only have one single server, you can skip a lot of steps here, all these steps are only useful if you don’t want possible long downtimes on your server.
The steps to migrate your web server are:
- Install php-fpm, fcgiwrap and nginx.
- Copy virtual hosts setup to port 81.
- Start new servers and test.
- Proxy the virtual hosts with Apache.
- Adjust other software.
- Final switch.
- Cleanup.
1. Install php-fpm, fcgiwrap and nginx.
On a normal Apache web server you will most likely already have PHP and MySQL installed. When you migrate from Apache to Nginx you should not need to change anything in these two packages. Besides the nginx server package, you may need to install the php-fpm and fcgiwrap packages. You need the php-fpm package if you use PHP somewhere, and fcgiwrap if you have CGI scripts.
For example:
root@web04: ~# pacman -S --needed php-fpm fcgiwrap nginx resolving dependencies... looking for inter-conflicts... Targets (5): php-fpm-5.3.8-6 fcgi-2.4.0-7 spawn-fcgi-1.6.3-2 fcgiwrap-1.0.3-2 nginx-1.0.11-1 Total Download Size: 1.97 MB Total Installed Size: 8.65 MB Proceed with installation? [Y/n] :: Retrieving packages from extra... php-fpm-5.3.8-6-i686 1586.8K 1090.4K/s 00:00:01 [######################] 100% fcgi-2.4.0-7-i686 47.3K 250.1K/s 00:00:00 [######################] 100% :: Retrieving packages from community... spawn-fcgi-1.6.3-2... 8.4K 163.9K/s 00:00:00 [######################] 100% fcgiwrap-1.0.3-2-i686 9.4K 182.1K/s 00:00:00 [######################] 100% nginx-1.0.11-1-i686 362.5K 760.2K/s 00:00:00 [######################] 100% (5/5) checking package integrity [######################] 100% (5/5) checking for file conflicts [######################] 100% (1/5) installing php-fpm [######################] 100% (2/5) installing fcgi [######################] 100% (3/5) installing spawn-fcgi [######################] 100% (4/5) installing fcgiwrap [######################] 100% (5/5) installing nginx [######################] 100% Optional dependencies for nginx passenger root@web04: ~#
2. Copy virtual hosts setup to port 81.
The complete configuration details for both web server packages will not be discussed here, see the official documentation for that. Next is just an example of a Apache virtual host:
# fido.mbse.eu # <VirtualHost [2001:1af8:feb8:7e95::202]:80 0.0.0.0:80> ServerAdmin webmaster@mbse.eu DocumentRoot /srv/http/fido ServerName fido.mbse.eu ErrorLog /var/log/httpd/fido_error_log CustomLog /var/log/httpd/fido_access_log combined <Directory /srv/http/fido> DirectoryIndex index.html index.htm Options Indexes FollowSymLinks Order deny,allow Allow from all </Directory> </VirtualHost>
And this is the same host configured in nginx:
# fido.mbse.eu
#
server {
listen [2001:1af8:feb8:7e95::202]:81;
listen 10.126.149.3:81;
listen [::1]:81;
listen 127.0.0.1:81;
server_name fido.mbse.eu;
error_log logs/fido_error_log;
access_log logs/fido_access_log main;
root /srv/http/fido;
location / {
index index.html index.htm;
}
}
Note that I also let the server listen on the localhost addresses, we need that for step 4.
3. Start new server and test.
All the virtual hosts are configured to listen to port 81 instead of the usual port 80. We can now start the new server and test it.
root@web04: ~# rc.d start fcgiwrap :: Starting fcgiwrap daemon [DONE] root@web04: ~# rc.d start php-fpm :: Checking configuration [DONE] :: Starting php-fpm [DONE] root@web04: ~# rc.d start nginx :: Checking configuration [DONE] :: Starting Nginx [DONE] root@web04: ~#
In your browser use url’s like http://www.mbse.eu:81 to connect to port 81. Note that you might need to open port 81 in your firewall if you want to test this from the Internet. I would only test from your internal network, the next step allows testing from the Internet without a firewall change.
4. Proxy the virtual hosts with Apache.
Apache still listens on port 80 for all our virtual hosts and we keep that so for a while. The next step is to configure Apache so that it will reverse proxy each virtual host to the nginx server. So, Apache just acts as a gateway and nginx will serve the pages. First make sure that proxy support is enabled in Apache, in /etc/httpd/conf/httpd.conf enable the next lines:
LoadModule proxy_module modules/mod_proxy.so LoadModule proxy_ftp_module modules/mod_proxy_ftp.so LoadModule proxy_http_module modules/mod_proxy_http.so
Now change one virtual host in /etc/httpd/conf/extra/httpd-vhosts.conf from:
# fido.mbse.eu # <VirtualHost [2001:1af8:feb8:7e95::202]:80 0.0.0.0:80> ServerAdmin webmaster@mbse.eu DocumentRoot /srv/http/fido ServerName fido.mbse.eu ErrorLog /var/log/httpd/fido_error_log CustomLog /var/log/httpd/fido_access_log combined <Directory /srv/http/fido> DirectoryIndex index.html index.htm Options Indexes FollowSymLinks Order deny,allow Allow from all </Directory> </VirtualHost>
to this:
# fido.mbse.eu # <VirtualHost [2001:1af8:feb8:7e95::202]:80 0.0.0.0:80> ProxyPass / http://localhost:81/ ProxyPassReverse / http://localhost:81/ ProxyPreserveHost On ProxyRequests off ServerName fido.mbse.eu ErrorLog /var/log/httpd/fido_error_log CustomLog /var/log/httpd/fido_access_log combined </VirtualHost>
Next restart Apache:
root@web04: ~# rc.d reload httpd :: Reloading Apache Web Server [DONE] root@web04: ~#
Now the server http://fido.mbse.eu should be served by nginx and proxied by Apache. Test this from your internal network, but also from the Internet.
5. Adjust other software.
There are several packages that do things with web logfiles, they now point to /var/log/httpd and should be changed to /var/log/nginx. With our setup, the layout of all *access_log files are the same as Apache combined setting. The packages you might need to change are ossec, logwatch and webalizer.
If you use net-snmp and watch the running processes you need to remove httpd and add the new processes, for example use the following lines in /etc/snmp/snmpd.conf:
proc php-fpm 50 2 proc nginx 2 2 proc fcgiwrap 1 1
If you have .htaccess files that do redirection to other url’s, you need to configure these into nginx.conf, for example:
rewrite ^(/files/local/)(.*)$ /files/$2 permanent;
On my fido site this rewrites http://fido.mbse.eu/files/local/somedir to http://fido.mbse.eu/files/somedir.
If you have things like webalizer, it is a good idea to let apache proxy for nginx for at least 24 hours so that the information in the logfiles won’t be interrupted. However, during this period in the nginx logfiles is the localhost ip written instead of the client ip address.
6. Final switch.
If everything works, make a backup of /etc/nginx/conf/nginx.conf and change the running config file to use port 80 instead of port 81. Then stop apache and reload nginx:
root@web04: ~# rc.d stop httpd :: Stopping Apache Web Server [DONE] root@web04: ~# rc.d reload nginx :: Checking configuration [DONE] :: Reloading Nginx Configuration [DONE] root@web04: ~#
Now you should test every site again.
7. Cleanup.
Remove php-apache and apache packages with the pacman -Rs command after a few days and the migration is complete.