Implementing blue-green deployment for Drupal site with Docker
Nulab
April 15, 2015
Are you or is your company using Docker to build, ship and run your apps? At Nulab, we are implementing blue-green deployments with Docker for our Nulab Developers site. In this blog post, we’ll take you through an overview of how we update the website.
Note: Nulab Developers launched last summer to create a developer community for our users.
Configuration of the middleware
On the EC2 instance as in the figure above, there are always two raised Docker containers of “blue” and “green,” and nginx is working as a reverse proxy on the same instance. We build a Drupal site running parallel in the “blue” and “green” environment and serve both from a MySQL database. Regarding the Docker image, we install Apache, PHP and Drupal in baseimage-docker.
Implementing Blue-Green Deployment
We often see the use of a load balancer to switch host, but nginx acts as the Nulab Developers site‘s reverse proxy server for switching host. In this example, we map Apache’s port in the Drupal container with the host side’s port.
# docker port drupal-blue 80/tcp -> 0.0.0.0:8080 # docker port drupal-green 80/tcp -> 0.0.0.0:8081
In nginx, we define each upstream’s corresponding ports.
upstream blue { server localhost:8080; } upstream green { server localhost:8081; }
And in the reverse proxy setting, we call the $ upstream variable.
location / { proxy_intercept_errors on; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://$upstream; }
We use the variable $upstream for proxy setting. We define the variable $upstream with value of “green” in the upstream_green.conf, and “blue” in the upstream_blue.conf.
# ls -lt upstream* lrwxrwxrwx 1 root root 41 Mar 24 05:34 upstream.conf -> /usr/local/nginx/conf/upstream_green.conf -rw-r--r-- 1 root root 206 Feb 17 03:52 upstream_green.conf -rw-r--r-- 1 root root 205 Feb 17 03:52 upstream_blue.conf
Then we create a symbolic link and name it upstream.conf. We include this symbolic link in the nginx configuration. The symbolic link points to upstream_blue.conf OR upstream_green.conf, depending on which environment you’d like to use for production.
The symbolic link enables us to switch between blue and green environment by switching the symbolic link target, which is a simpler process than editing the configuration file under Ansible control.
If we edit the config file, we would have to perform the following actions:
- Edit configuration file under Ansible control
- Run Ansible to update server
- Push configuration change to version control
This process is more complex and takes longer.
We manage the configuration file under Ansible, so we avoid rewriting the file contents whenever we switch “blue” to “green” and vice versa. We then use the Jenkins Typetalk plugin to enable our Typetalk members to perform the switch.
Our workflow for updating the website
Ok, so now we’ve implemented blue-green deployment with docker. By using Docker as a staging environment, we also take advantage of the standby side container. Here’s our workflow for updating the website using Docker.
The Git repository we’re using in our development team resembles that of the sample used in the announcement of Drupal Camp Taipei in 2014.
In this repository, three things are being managed:
- Drupal body and the module
- Themes for Nulab Developers site and a proprietary module (developed ourselves)
- Ansible’s settings file for Vagrant / Docker ‘s config
Whenever something changes like Drupal’s security update, style changing, adding PHP’s setting:
- Jenkins builds the new Docker image
- Pushes the newest version in the in-house Docker registry
- Replaces a new automatically generated image of a staging environment
- and performs Blue-Green Deployment if there is no problem
Current issues
Docker-compose has made it much easier to manage multiple Docker containers, though it took time to launch and manage each Drupal and MySQL container separately when we started building this environment. Now our dev team uses both Vagrant and Docker at the same time. We use Vagrant in our development environment because we haven’t been able to use Docker in both a development and production environment.
We install Drupal and MySQL to Vagrant and develop our Drupal “themes” and “modules” using Vagrant’s “Synced Folder” feature. In the near future, we’re considering to use Docker in Vagrant, similar to how Wocker functions to enable WordPress to work in Docker .
At the moment, we don’t provide any platform like a discussion forum for users to post new data on our production website. If we were to provide one under blue-green deployment, we will have to consider a solution for synchronizing data added by our users on production, with data on staging before switching between blue and green.
Conclusion
Above you can see how we monitor the blue and green Docker’s access number. Blue-Green deployment allows us the flexibility to experiment with security, by providing a fast mechanism to roll back to the original should anything go wrong (though we haven’t had to do that). So for example, if we want to conduct A/B testing or change a design quickly, under Blue-Green deployment, we can execute with ease and security.
We experienced the “immutable infrastructure” claimed to be a benefit of using Docker after we pushed some changes to the Git repo. Immediately after, the new Docker image was created and replaced in the staging environment.
Many people might use a staging site to operate their website. In this case, you would need a specific server when you try to make the environment independent. On the other hand, if you try to manage multiple websites within the same server, it may not easily upload the version of Apache and PHP for example. As an alternative solution, we recommend operating a Docker in the same server with a separated environment, which enables you the ability to experiment at the staging side.
With the experience of operating the service with AWS, we have been avoiding for single EC2 instance to have a variety of roles because of possibility of scalability and fault tolerance. As a result of this, we prepared an instance of specific numbers when we do the environment with a minimum configuration. By using Docker, it could be possible to ensure the container of independence, to maintain the configuration to scale easily and initially to suppress the resource small.
We are continuously working to improve our services. If you have any feedback or suggestions for us, let us know!