Apr 28, 2023

Software deployment best practices

Software deployment best practices cover image

Table of Contents:

  1. What is deployment
  2. Deployment strategies
  3. Deployment methods
  4. Deployment rules

What is deployment?

Software deployment refers to the process of installing an application or updates on a server. It is a crucial component of the software development process as it enables the delivery of new features to be used in real-world applications. Now that we have established what software deployment entails, let us briefly touch on its technical aspects and my personal experience. While there are numerous articles available that delve into the various methods, variants, and approaches to deployment, I will provide a concise overview and share my own experience.

Basic deployment strategies

  1. Blue-Green Deployment: This approach involves creating two identical production environments, one active and one inactive. The active environment serves production traffic, while the inactive environment is updated with the new code or configuration. Once the update is complete, traffic is switched from the active environment to the inactive environment, making it the new active environment.

Pros:

  • Minimal downtime: there is no downtime during the deployment process because the new version of the application is deployed to a separate environment, and traffic is switched over only after the new version has been fully tested and verified.
  • Easy rollback: If there are any issues with the new version of the application, it is easy to roll back to the previous version by simply switching traffic back to the old environment.

Cons:

  • Increased complexity & costs: as it requires maintaining two environments.
  • Longer deployment time: it involves deploying to two separate environments and verifying the new version of the application before switching traffic to it (no mention that switching can take time as well depending on a switch strategy).
  • Configuration drift: If the two environments are not kept in sync, there is a risk of configuration drift, which can lead to issues when switching traffic between environments.

This approach is good for apps that are very sensitive to downtime. We use it for apps with 24x7 SLA and 99.99% uptime requirements.

  1. Rolling Deployment: This strategy involves deploying new code or configuration to a subset of servers in a staggered manner. This helps to minimize the impact of any issues that may arise during the deployment process. Once the deployment is complete on one subset of servers, it is then rolled out to the remaining servers.

Pros:

  • Reduced downtime: Rolling Deployment reduces downtime during deployment because it deploys the new version of the application gradually, one server or instance at a time, while the rest of the servers or instances continue to serve traffic.
  • Lower failure cost: by rolling out updates to only part of users we lower the cost of failure. If we detect a problem we can stop deployment thus leaving a major part of users unaffected.

Cons:

  • Increased complexity: Rolling Deployment can be more complex than other deployment strategies because it involves coordinating updates across multiple servers or instances.
  • Longer deployment times: Rolling Deployment can take longer to deploy than other strategies because it updates servers or instances one at a time, which can be time-consuming for large applications or large numbers of servers.

This approach is good if we have a big user base and we don’t want anything unexpected to be discovered (even though everything was double-checked). We use this for deploying updates for the app with a 1M+ user base.

  1. Canary Deployment: This methodology involves deploying new code or configuration to a small subset of users or servers before rolling it out to the entire user base. This allows for early detection of any issues with the new code or configuration before it is rolled out to a larger audience.

Pros:

  • Early feedback: a small group of users will give early feedback before a big update will be rolled out to the whole user base.
  • Reduced risk: since a small group of users is involved risk is lower. In case of bad.

Cons:

  • Increased complexity & costs: it requires setting up and managing a separate environment for testing the new version of the application.
  • A longer time of shipping a feature to users

This approach is good for big feature releases when we want to test the feature on a small subset of users first. We use this approach for new features with breaking changes we want to test on a small subset of users first.

  1. Immutable Infrastructure: This strategy involves treating servers as disposable and creating new servers for each deployment. This helps to ensure that each deployment is identical and eliminates the risk of configuration drift.

We don’t use this approach so it won’t be fair for me to share my experience based on theory knowledge only.

  1. Zero-Downtime Deployment: This methodology involves deploying new code or configuration without any interruption to the production environment. This can be achieved using techniques such as load balancers or container orchestration platforms.

This approach is similar to Rolling Deployment but with much less tolerance for downtime.

We don’t use it so far because the setup is usually more complicated than Blue-Green Deployment one. So we prefer to use the last one instead.


Some identify a whole range of different strategies such as Feature Flag Deployment, A/B Testing Deployment, Dark Launch Deployment, etc. In my opinion, all of this is not related to deployment variations, as it is not related to how we "deliver" new code to the server. Rather, these are different release strategies.

Deployment methods

Deployment can be done both manually and automatically.

Manual deployment involves accessing the server, configuring the environment (if necessary), pulling changes, installing them, and restarting the server.

Automatic deployment involves running a command, and all necessary operations will be executed automatically. Automatic deployment is almost a must-have, as it helps to reduce the potential for human error and speeds up the deployment process thus saving project resources.

There are many different methods and services for automatic deployment. Below, I will provide the list of tools that we typically use:

  • Capistrano: to deploy Ruby (RoR) applications
  • PM2: to deploy Node.js and front-end applications (React, Vue.js, etc.)
  • Heroku pipelines: to deploy projects hosted on Heroku
  • CircleCI: CI/CD to make builds and run tests
  • Docker: to deploy various projects with a tech-complicated stack
  • Deployer: to deploy PHP applications
  • Ansible: to automate server-related tasks or deploy some custom config apps

Other popular tools are Jenkins, Travis CI, GitLab CI/CD, AWS CodeDeploy, etc. To find more tools suitable for your stack just search for “deployment automation for X” where X is

General deployment rules that we try to adhere to

  1. Version Control: Use a version control system (VCS) to manage your codebase (e.g. git, we use git). This will help you keep track of changes made to the code over time and enable you to roll back to a previous version if necessary. Yes, even though it is already 2023, nevertheless, sometimes you can still come across "craftsmen" who simply upload an archive to the server and unpack it. I have come across such projects 🤦
  2. Automated Testing: Implement automated testing at every stage of the deployment process, including unit tests, integration tests, and end-to-end tests. This will help to catch any bugs or issues before they reach production.
  3. Deployment Pipeline: Create a deployment pipeline that includes various stages, such as development, staging, and production. Each stage should have its own set of tests, and code should only be promoted to the next stage if it passes all the tests. Use Continuous Integration and Continuous Deployment (CI/CD) to automate the entire process of building, testing, and deploying code to production. By implementing CI/CD, you can ensure that every change made to the codebase is automatically tested and deployed to production if it passes all the tests.
  4. Make sure to check everything at each stage of deployment: Locally, before pushing any updates to the staging environment. On the staging environment after deployment. In the production environment after promoting the changes to production.
  5. Rollback Strategy: Have a rollback strategy in place in case something goes wrong during the deployment process. This will enable you to quickly revert to a previous version of the application if necessary.
  6. Don’t deploy anything on Friday unless it’s critical. Otherwise, you have chances to spend some time fixing problems on Friday evening or the weekend. I’ve had some cases where even the smallest update unexpectedly broke everything, forcing me to dive into the project and find and fix the cause of the failure. On large projects, there can be various reasons for this, and to protect yourself from overtime work, it is better to schedule the deployment for the beginning of the week.


originally posted on linkedin.com

CV