Let's walk through a scenario.
Imagine a developer with a machine running the Ubuntu 16 operating system. This developer installs apache2 on their system to run a PHP Laravel project, along with a MySQL database server and a Redis caching server. After they've completed the development process and it's time to deploy the app, they spin up a new instance on AWS, complete with elastic-cache and RDS for required data stores.
But then, trouble starts brewing.
The developer didn't pay attention to the service versions, and now, it's clear there are conflicts between the versions of different platforms and services used in the local and production environments, looking something like this
What can go wrong in this scenario? The possibilities are endless, especially considering that software development often involves a continuous cycle of maintenance, optimizations, bug fixes, as well as planned upgrades and deprecations, but here are a few examples of potential issues based on my past experiences:
A Laravel package that doesn't meet the production PHP version requirement
A Laravel package that doesn't meet the production MySQL or Redis server-client requirement
An untracked package is deprecated and can't be installed for production deployment
A composer installation might fail due to version incompatibility
Unanticipated production downtime or page errors
Difficulties in debugging during deployment because problems that occur in the production environment can't be replicated in the local development environment
So how can we solve these issues?
Understanding the cause of the issue on production and debugging it in the local development environment would be a good start. However, this reactive approach might cause downtime for the production application. As the saying goes, "Precaution is better than cure."
Let's look at how we can better sync all environments to improve known issues before release or make debugging easier across all environments. Here are a couple tools that solve for this issue:
Docker automates repetitive, mundane configuration tasks and can be used throughout the development lifecycle for fast, easy, and portable application development. Docker's comprehensive end-to-end platform includes UIs, CLIs, APIs, and security that are engineered to work together across the entire application delivery lifecycle. Best of all, it's quick and easy to set up.
Vagrant provides a uniform workflow regardless of your role as a developer, operator, or designer. It uses a declarative configuration file that describes all your software requirements, packages, operating system configuration, users, and more.
In essence, getting up a well-configured environment is like laying the first brick for your backend project. It provides the stability and consistency required to handle the ebb and flow of development activities. Investing the necessary time and effort to configure your environment properly not only prevents potential headaches down the line, it also underpins your projects with a solidity that can help it withstand unforeseen challenges.
As developers, we strive to create systems that are resilient, reliable, and robust — and by prioritizing our environment setup, we can ensure our backend development projects are built on a solid foundation.