Preface:
I had posted a stack overflow question and there seemed to be little documentation or explanation about how this separation of power works. I've decided to document this for future reference.
This is a very small proof of concept for running a docker environment.
This test environment contains the following separate containers working together:
- php:7.4-fpm-alpine
- httpd:2.4-alpine
- mysql:5.6
There is also an nginx section commented out in the docker-compose file that can be interchanged with apache.
For more info please see docker-compose.yml
git clone https://github.com/dambrogia/docker-testing.git
cd docker-testing
docker-compose up -d
Please wait up to 60 seconds for the MySQL service to be available to connect to! Until then you may run into the following error:
Warning: mysqli::__construct(): (HY000/2002): Connection refused in /var/www/html/index.php on line 14
Connect failed: Connection refused
After MySQL is ready, visit 127.0.0.1:8000
in your browser. You should see a the output from public_html/index.php
.
First and foremost, the biggest problem was getting apache to run PHP files rather than display their source code. Because Apache and PHP are running in separate containers we couldn't simply have apache call PHP to render the files.
The answer to this was to to use PHP FPM which will accept incoming requests. We proxy our Apache requests to PHP FPM. You can find this direct setting here.
I found out this was possible in nginx first - docs here
And then I applied what I found in nginx to Apache through some help here.
After being able to run PHP files through apache the next error I ran into was that I was missing the MySQL extension for PHP. Because we're using lightweight alpine linux distros, we can't simply add php extensions through yum
or apt
or event apk
(alpines package manager). After a while of googling my fingers off I found out that docker has a solution for this. You can see it in action here, and that link also includes commentary to where I stumbled across the solution.
Finally, now that I can run MySQL functions in PHP. Of course I run into my last problem - the good ol' connection refused
error. I knew that my credentials were valid because through port forwarding I could connect with a MySQL GUI. I googled my fingers off for a few minutes and came across a networking concept within Docker that I wasn't aware of of. This stackoverflow answer states that along with networking your PHP & MySQL services, you want to declare your MySQL host as the name of your MySQL service. You can see related aspects in index.php and docker-compose.yml
If you have any Questions feel I skipped over an import detail, I'd be glad to elaborate.