Blue-Green Deployment of Spring Applications with Nginx Web Server

image







Note perev. - With this article we are starting a series of translations devoted to the topic of Zero Downtime Deployment. The following publications will highlight the deployment of new versions of the application with the database and deployment in Kubernetes.







Despite the fact that the technical solution described below is controversial, the purpose of this article is to familiarize the reader directly with the Blue-Green deployment approach, which, incidentally, is applicable not only to Spring applications.







The goal of the Blue-Green deployment is to eliminate downtime during the deployment of a new version of the application.







Downtime is related to server unavailability when a new version of an application is installed to replace the old one. The idea of ​​Blue / Green deployment is to deploy the new version of the application in a separate place where you can conduct testing, until the final decision is made to switch to it as the main one.







image







In this article, we will look at how to configure the Blue-Green Spring boot application deployment. We will use Nginx as the main web server to redirect incoming requests to our applications.







Server Tuning



This guide assumes that you have a server and a running Spring boot application that can be deployed to it.







On the server, go to your home directory and create two folders: blue



and green



. Then we need two symbolic links available



and testing



. These links will point to either a blue or a green folder. For example, if available



points to green



, then testing



points to blue



.







 mkdir blue mkdir green ln -s ./green ./available ln -s ./blue ./testing
      
      





Each folder will contain its own Spring application and Nginx configuration. At some point during the deployment, both applications will work simultaneously (although on different ports), and to switch from the blue application to green, we only need to change the Nginx configuration to either green or blue.







image







Nginx configurations



Let's say we have a springsite.com domain. The green configuration of Nginx will redirect all calls to springsite.com/api/ to the green



application on port 8080, and all calls to springsite.com/api-test/ to the blue



application on port 8090.







Let's create these configuration files. Open your favorite editor and add the following content.







 http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name mysite.com; location /api { proxy_pass http://localhost:8090/api; } location /api-test { proxy_pass http://localhost:8080/api; } } include servers/*; }
      
      





 http { include mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; server { listen 80; server_name mysite.com; location /api { proxy_pass http://localhost:8080/api; } location /api-test { proxy_pass http://localhost:8090/api; } } include servers/*; }
      
      





The file structure should look something like this:







 --root |--- blue |--- nginx.conf.blue |--- app-V2.jar |--- green |--- nginx.conf.green |--- app-V1.jar |--- available -> ./green |--- testing -> ./blue
      
      





Suppose we want to deploy a new version in a blue



container. We can test it while the previous version is still available . Once everyone is happy with the new version, we will only need to change the links!







Create a swap.sh



file in a folder containing both blue



and green



folders:







 touch swap.sh chmod +x swap.sh
      
      





Add the following contents to the swap.sh



file:







 #!/bin/bash testing_now=$(ls -l ./ | grep testing) if [[ "$testing_now" == *blue ]] then testing="blue" active="green" else testing="green" active="blue" fi #remove current links rm ./available rm ./testing rm -f /etc/nginx/nginx.conf #create new links with the active/inactive reversed ln -s ./$inactive ./available ln -s ./$active ./testing ln -s /home/ubuntu/spring/$active/nginx.conf /etc/nginx/nginx.conf #reload the http server service nginx reload echo swap completed $active is now available
      
      





At this point, we can run 2 Spring applications on ports 8090 and 8080 and change them by running sudo ./swap.sh



.







Deploy



Thanks to symbolic links, we know that the main application is always indicated by available



, and the test is always indicated by testing



. Therefore, we should always deploy the new version of the application in the testing



folder using a symbolic link. It is assumed that we have just packaged the application, and now we can download it using scp



.







 scp -r -i ~/.ssh/MyKeyPair.pem <package name.jar> <user>@<ip>:spring/testing
      
      





Move on



Setting up a Blue-Green deployment on your server will significantly reduce downtime . This guide explains how to deploy new versions of your application that reside on the same physical server. It can be adapted to situations with multiple physical servers and a load balancer. However, this will require having twice as many production environments as necessary. For a very large infrastructure, this is either impossible or extremely expensive.







This leads to the question: How do large companies manage to release new versions of their applications without downtime? Think of Google or Facebook that are always available!







Using the Blue-Green deployment here is unrealistic due to the huge number of necessary servers. Application updates are carried out gradually: the servers are taken out of service one by one, and returned after the update. Moreover, new versions are also released gradually: in the beginning, only a small part of the servers will work with the new version. Then, if no problems or bugs were found, more and more servers will start with the new code. At this point, important performance metrics are evaluated, such as CPU, memory, and query performance. If everything went well, the release is complete, and a new version of the application will be launched on every server around the world.







Conclusion



I hope you now understand how to solve the downtime problem thanks to the Blue-Green deployment. Now you can configure the basic Blue-Green deployment of your Spring application with NGINX.







As you may have noticed, when we use this solution, the old and current versions of your applications work simultaneously and both are connected to the database. This can lead to unexpected problems when changing the structure of the database. This great article https://spring.io/blog/2016/05/31/zero-downtime-deployment-with-a-database describes how to deal with such situations.







And finally, you might be interested in the fact that both AWS and Google Cloud Compute offer Blue-Green Deployment services out of the box:







https://aws.amazon.com/quickstart/architecture/blue-green-deployment/

https://cloud.google.com/solutions/continuous-delivery/







Also read other articles on our blog:






All Articles