Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.
In my new job, I was assigned to move a typical apache/php/mysql application to the cloud. On-premises, all the components were installed in the same virtual machine.
In order to scale in the future, and again because failure is inevitable, I suggested that we use Docker to package the application and see which cloud provider’s orchestrator will be best for us at the moment, regarding price/performance/easy of use.
Remember, we’re living in a world of failure. So I already knew that simply pushing the code in a container wasn’t be enough to seat back and relax once it was done. In fact this will turn into a story- and I’m not saying probably, it will , I know it already. Period-because I want to share with you all the things we will do when facing a failure.
There’s a ton of sample out there to get started with. I decided to fork this github project as a starting point.
Everything went well, but at runtime, the MySql connection was not working in the first place. I’m not the author of the php code and the error was weird enough to challenge me for understanding what was wrong:
php docker mysqli::__construct(): (HY000/2002): No such file or directory in <b>/database.php</b> on line <b>76</b>
I’m not a php expert but it was clear to me that the constructor of the msqli object was throwing an exception, may be because of a network problem. Poking around on google, I found this helpful blog post that allowed me to do basic tests, just to confirm that everything was fine on that level.
The next step was to take a look at the php code, that basically looked like this:
$g_mysqli = new mysqli($hostname, $username, $password, $dbName, $port); if ($g_mysqli->connect_errno) ...
Nothing fancy. The next question that comes to mind is which one of these parameter is causing this error ?
It turns out that it was $hostname that was the source of our problem. It’s value was localhost. There seems to be a recurring pattern when a developer uses localhost instead of a DNS computer name. Worse, I’ve seen developers always using IP addresses arguing for performance reasons… The question is not wether it is true or false, but what is the safest option for the coming years ?
docker-compose is creating a network for you and use the container name as a host name. So if your mysql container is named mysql, you’ll be able to reach it by using mysql.
In the cloud, IP Addresses are likely to change a lot. This why you have to project yourself in the near future and reevaluate the choices you’re making now.
Another key takeaway here is exception management. As we have seen the mysqli constructor may throw exceptions under some circumstances. The code must be modified to be more fault tolerant and more resilient.
If you looked at the docker compose.yml file on the GitHub project, you’ll notice that Nginx and php are hosted in their own containers. This will allow us to upgrade one of them without touching the other. Separation of concerns is preserved.
Now the next challenge I have been facing is this one: php code in html files were not processed. I found the solution to this problem in this answer on askubuntu.com. The nginx and the php configuration should be modified to allow php code in html files. But should they ?
There is another key takeaway here. An HTML file containing php code should obviously be named with a .php extension. This would allow only php files to be processed by php, leaving all other files processed by the web server as static files.
Now this “dockerized” application is ready to reach staging. To be continued.