Skip to main content

Running apache and php-fpm as services in a gitlab-ci job

I've been using gitlab-ci to automate the end-2-end tests for my PHP-applications for several years now, but I wasn't really happy about the way I got it to work: it involved injecting IP-addresses into configuration files, and starting a web server as a part of the test job.

an elephpant, and the apache and gitlab logo's

Today I can run apache and php-fpm as services, so that the job's script doesn't have to care about the web server, and can fully concentrate on running the actual tests.

As a proof of concept, I created a demo project on gitlab, that has a gitlab-ci-pipeline, using curl to run a hello-world-php-script by sending a request to an apache server. (So no fancy things with selenium here.)

I have been trying this before, but it always failed, because I had mainly two problems:

  • I was not sure how I could share the source code of my application with the php server.
  • The different services seemed to be unaware of each other. Typically a selenium service couldn't find the IP address of my webserver.

I had searched the web for solutions, but I only seemed to find discussions involving docker-in-docker, which I don't completely understand, and which are too complex for the problem I was trying to solve. And as it turns out, what we're trying to do here is really not difficult, you just need to know what to do.

Solving the problem of services being unaware of each other, was the easiest. You just need to set FF_NETWORK_PER_BUILD to 1 in .gitlab-ci.yml.

Then there is the issue of sharing the source code from the git repository (or the code built in previous stages) with the apache container.

When the gitlab runner is executing jobs, your source code is located in the directory /builds/group-name/project_name. (This directory is available to the runner as the CI_PROJECT_DIR environment variable.) Now it seems there is some gitlab magic in place that creates a volume in each service's container, so that this directory is shared between all services.

So the only thing we need to make the webserver work, is a custom apache container, configured to look in this particular directory for the files, to pass those to php.

I was a little worried because when the pipeline runs, this message showed up in the job log:

2022-06-16T13:17:38.351483903Z AH00112: Warning: DocumentRoot [/builds/johanv/php-ci-demo/public] does not exist

But in the end, it did produce the expected 'Hello world!' message, so maybe the volume takes some time to mount. Or maybe something else is going on, I really don't know that much about docker and gitlab ci. But it seems to work, so I am happy 😅

Anyway, I hope that this will be useful to you. The demo project is located at gitlab.com/johanv/php-ci-demo. Have fun!

P.S.: If you want to read more about running e2e-tests in gitlab-ci, check my posts tagged with ci.

Comments

Comments powered by Disqus