Modern web applications are large, complex, and resource-intensive. The methods of hosting these applications have changed drastically as as result. It is no longer ideal to simply host a modern web application on a Linux/Apache/MySQL/PHP (LAMP) stack, as doing so will severely limit the performance capabilities of modern web applications.
A web application stack is a collection of software that works together to provide modern, secure, and fast application delivery. These modern application stacks go beyond a typical LAMP stack and include additional components such as Nginx and Varnish. Extensive tuning keeps these components working together for the best end user experience.
This article covers the different applications and technology that make up our Hostdedi Cloud web application stack, focusing specifically on application delivery.
Discover the Hostdedi Stack
Nginx is a full-featured, high-performance web server that we use as a reverse proxy within our web application stack. Favored by many websites, Nginx has been a popular replacement for the Apache Web Server because it excels at serving static content.
With this in mind, we use Nginx together with Apache web server in our application stack. The use of Nginx in front of Apache as a reverse proxy allows each to focus on their respective strengths.
This benefits low-traffic and high-traffic sites, as cached objects prevent the need to retrieve the object from the web server with every request. Many modern CMSs can have well over 100 static objects per page load, all of which can be served by the Nginx micro cache. This removes significant load from the dynamic content web server, noticeably so during peak web traffic times.
TLS terminators handle the decryption of HTTPS connections. Typically, the web server application handles TLS decryption, although this is often not ideal. Varnish and other caching proxies do not currently support HTTPS connections, and so require decryption of TLS connections before they reach your caching layer. Load-balanced solutions also require the TLS certificate to be installed on every application server when not using a TLS terminator.
A solution to these limitations is to let Nginx handle TLS decryption. While alternatives such as Pound and HAProxy exist, Nginx handles it natively and can also provide load balancing if necessary, removing the need for additional load balancer services.
Modern TLS Support
Transport Layer Security (TLS) is the successor to the older encryption protocol, Secure Sockets Layer (SSL). TLS provides the encryption for HTTPS connections, which is nearly a requirement for all modern websites.
Current security standards (most notably, PCI DSS) have flagged older SSL and even some early TLS as inadequate, and only modern TLS ciphers make it possible to meet these evolving standards.
Like SSL, TLS has several versions, the most recent being TLS 1.3. As a PCI-compliant hosting provider, we enable only secure ciphers according to the Mozilla Modern standards.
Nginx fully supports the latest HTTP/2 protocol. HTTP/2 is a revision of the original HTTP 1.1 protocol released in 1999. It focuses on improved performance, perceived end-user latency, and use of a multiplex connection between web servers and browsers. HTTP/2 is currently supported by all major browsers and is enabled by default in Nginx on Hostdedi Cloud solutions.
Nginx also has plans to support the new QUIC – HTTP/3 protocol, which we will also support as soon as it becomes available.
Data compression is not a new idea. If site data can be quickly compressed on the server and uncompressed in the browser, this reduces the size of transferred data, thereby saving time.
Web servers and browsers have supported several compression algorithms such as gzip and deflate for years. While both of these have historically worked well for content delivery, a modern and more efficient option is available: Brotil.
Brotli is a data specification that uses a dictionary-based compression algorithm designed specifically for the transfer of text-based web application static files such as HTML and CSS. Due to its specialized role, it offers significant upgrades over other common web compression algorithms in both compression ratio and compression speed. All modern browsers and web servers now support Brotli including Nginx, which is enabled in our configuration.
Apache is an industry-standard open source web server that first saw the light of day in 1995. In 2012, the release of version 2.4 began the support of a significant feature set that continues to improve to this day.
One of Apache’s strengths is the ability to deliver dynamic content at high concurrencies through various application interfaces like the FastCGI Process Manager (FPM). We utilize PHP-FPM for all PHP-based applications on our cloud application stack. Beyond fast dynamic application support, Apache 2.4 has several other notable features, as described below.
The Event MPM
Apache 2.4 saw the release of the event multiprocessing module (MPM), which provided significant performance gains over previous prefork and worker MPMs of previous versions. The event MPM makes Apache much more efficient with memory usage and increases thread handling for incoming connections in a manner similar to Nginx. Hostdedi Cloud plans use a carefully tuned event MPM configuration as part of our application stack.
Web Application Firewall
A web application firewall (WAF) is an essential security feature for any website. Their purpose is to provide an HTTP content filter for common vulnerabilities, including SQL injection, cross-site scripting, and request forgeries, among others. WAFs also provide protection for known application vulnerabilities and backdoors, protecting known remote shells and unpatched software from being exploited.
Our application stack uses ModSecurity, an open source WAF for application protection. Having ModSecurity in place with Apache provides additional protection to web applications, and helps meet security and compliance requirements such as PCI DSS.
While front end optimizations are smart for site development, time constraints sometimes kick these to the wayside. In these cases, Mod_Pagespeed is invaluable.
While Mod_Pagespeed is available for both Nginx and Apache, we have enabled it with Apache web server. This allows it to optimize the code as part of Apache, when it then can be cached optimally in the Nginx micro cache.
As mentioned earlier, any web application can be configured under Nginx or Apache, but the latter’s support of .htaccess sometimes makes Apache a more suitable candidate. Some CMSs use .htaccess configurations not fully supported by Nginx. While there are pros and cons to using .htaccess files as a whole, it is generally preferable to make them available, rather than force our clients to modify their site to Nginx standards.
Varnish is a caching HTTP accelerator that provides high-performance static and dynamic content delivery. When enabled and properly configured, content requests normally handled by Apache and Nginx are now handled by Varnish, which directly delivers cached assets from memory to users’ browsers. Dynamic sites with complex back ends that require considerable PHP interpretation (such as Magento) can benefit greatly from the use of Varnish.
One downside to Varnish is its complexity in implementation. Controlling which content is cached can be tricky, especially with dynamic content. Extra care must be taken when dealing with session-based eCommerce sites to keep shopping carts updating properly. Varnish handles these configurations using its Varnish Configuration Language (VCL). The VCL can be customized for websites, and some applications such as Magento 2 provide a base VCL file to get the application up and running.
Currently, Varnish only supports the HTTP protocol, not HTTPS. This requires the use of an SSL terminator in front of Varnish, which is handled by Nginx in our web application stack.
PHP – Software Collections
Our web application stack utilizes RedHat’s Software Collections (SCL) for application language support. SCL allows multiple languages and versions such as PHP, Ruby, and Node.js immediately available for any given site. SCL also makes it easy to switch language versions. As an example, our clients may set their PHP version for any given account to any version between 5.6 and 7.3 from their Client Portal.
Opcache is a PHP-caching accelerator that increases performance by optimizing and storing precompiled script bytecode in shared memory. The integration of a properly tuned Opcache instance with PHP allows frequently used scripts to be read directly from memory, skipping the intensive compilation process. This has dramatically reduces load times for most applications.
Opcache is included with modern versions of PHP and the latest release of 7.3, and has replaced older PHP script-caching methods such as eAccelerator and APC. To fully realize the benefits of Opcache, we have spent considerable time tuning the Opcache default variables within our application stack. This is frequently overlooked but nonetheless critical, as neglecting to tune the default Opcache configuration to the size of the hosted application can negate any performance gains.
While not a local part of our application stack, nearly any website will benefit from using a content delivery network (CDN). A CDN caches frequently used static content on servers around the globe, thus giving users’ browsers a local option for retrieving site content and reducing latency. We offer a CDN solution with our cloud solutions and strongly recommend its use.
Tying It All Together
Modern web applications are mammoth and have considerable system requirements for best performance. While it is possible to host an application on a simple Apache or Nginx instance, it sacrifices performance for convenience. Apache, Nginx, and Varnish have complementary strengths, and using them together grants the best results for performance and scalability.
While our application stack is complex, it has been engineered with two decades of experience using these systems, and was tested and tuned for a variety of applications. It is also constantly evolving. As new technology and features becomes available for respective components of our application stack, we test these new elements before rolling them out.
The first of these considerations are the various headers used across the different services, each of which must be carefully managed. Nginx, Apace, and Varnish each provide default and custom headers for content control, cache control, and debugging information. Headers from external CDN or accelerator services can complicate this even further. Configuring headers properly ensures proper placement of caching and streamlines the flow of data through the stack.
Logging also presents a challenge, both for debugging and compliance requirements. Each service in the stack generates a log, all of which must be stored in a secure remote location to facilitate tracking of each request and response through these various components.
Threading, connection limits, and resource utilization must also be taken into account. Any component in this application stack can be a bottleneck if not properly tuned.. Many of these configurations are outlined in our paper, The Definitive Guide to Magento 2 Optimization.
Brad is Director of System Operations at Hostdedi. With over a decade in systems administration, he oversees out internal systems and was the author of The Definitive Guide to Magento 2 Optimization.
Few systems at Hostdedi escape his insight. When not monitoring our hosting infrastructure or upholding PCI security standards, Brad celebrates life with his family and plays a mean game of Puerto Rico.