<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="../assets/xml/rss.xsl" media="all"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>blog.johanv.org (Berichten over ci)</title><link>https://blog.johanv.org/</link><description></description><atom:link href="https://blog.johanv.org/categories/ci.xml" rel="self" type="application/rss+xml"></atom:link><language>nl</language><copyright>Contents © 2025 &lt;a href="https://blog.johanv.org/pages/contact/"&gt;Johan Vervloet&lt;/a&gt; 
&lt;a rel="license" href="https://creativecommons.org/licenses/by-sa/4.0/"&gt;
&lt;img alt="Creative Commons License BY-NC-SA"
style="border-width:0; margin-bottom:12px;"
src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png"&gt;&lt;/a&gt;</copyright><lastBuildDate>Wed, 29 Oct 2025 18:31:22 GMT</lastBuildDate><generator>Nikola (getnikola.com)</generator><docs>http://blogs.law.harvard.edu/tech/rss</docs><item><title>Running apache and php-fpm as services in a gitlab-ci job</title><link>https://blog.johanv.org/posts/php-ci-demo/</link><dc:creator>Johan Vervloet</dc:creator><description>&lt;figure&gt;&lt;img src="https://blog.johanv.org/galleries/cards/ci-demo-2.png"&gt;&lt;/figure&gt; &lt;div&gt;&lt;p&gt;I've been using 
&lt;a href="https://blog.johanv.org/posts/gitlab-ci-codeception-and-selenium-web-tests/"&gt;gitlab-ci to automate the end-2-end tests&lt;/a&gt;
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.&lt;/p&gt;
&lt;p&gt;&lt;img alt="an elephpant, and the apache and gitlab logo's" src="https://blog.johanv.org/galleries/cards/ci-demo.png"&gt;&lt;/p&gt;
&lt;p&gt;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.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://blog.johanv.org/posts/php-ci-demo/"&gt;Lees verder…&lt;/a&gt; (2 min resterende leestijd )&lt;/p&gt;&lt;/div&gt;</description><category>ci</category><category>php</category><guid>https://blog.johanv.org/posts/php-ci-demo/</guid><pubDate>Thu, 16 Jun 2022 13:30:00 GMT</pubDate></item><item><title>Selenium web tests on gitlab-ci for an app using Mercure</title><link>https://blog.johanv.org/posts/gitlab-ci-selenium-and-mercure/</link><dc:creator>Johan Vervloet</dc:creator><description>&lt;div&gt;&lt;p&gt;I recently learned
&lt;a href="https://symfony.com/doc/current/mercure.html"&gt;how to use Mercure&lt;/a&gt;
so that the php/Symfony back-end of my
application can send out events that can be picked up by the
javascript on my front end. This is really cool technology, you should
definitely try this out if you haven't already done so.&lt;/p&gt;
&lt;p&gt;Now if you write this kind of software, of course you also want to
write some web tests, so that you can automatically check if existing
features of your program keep working after you add new things.&lt;/p&gt;
&lt;p&gt;&lt;img alt="gitlab-ci, codeception and mercure" src="https://blog.johanv.org/galleries/misc/gitlab-codeception-mercure-smaller.png"&gt;&lt;/p&gt;
&lt;p&gt;For these kind of tests, I use gitlab-ci and codeception, as I wrote
in &lt;a href="https://blog.johanv.org/categories/ci"&gt;previous posts&lt;/a&gt;. Today I got these test working
with a Mercure hub.&lt;/p&gt;
&lt;p&gt;You need to use a mercure service in the job running your web tests,
which you can configure in &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2020-12-03:&lt;/strong&gt; I use the 0.10 version of the mercure container,
because the acceptance test job started failing with 0.11, with these
error messages:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Message: "Couldn't connect to server for "http://mercure:3000/.well-known/mercure"."
In HandleMessageMiddleware.php line 80:&lt;/p&gt;
&lt;p&gt;Couldn't connect to server for "http://mercure:3000/.well-known/mercure".)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So here's the adapted &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;-file:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nt"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="nt"&gt;JWT_KEY&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;YourSecretKey&lt;/span&gt;
  &lt;span class="nt"&gt;DEMO&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;1&lt;/span&gt;
  &lt;span class="nt"&gt;ALLOW_ANONYMOUS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;1&lt;/span&gt;
  &lt;span class="nt"&gt;HEARTBEAT_INTERVAL&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;30s&lt;/span&gt;
  &lt;span class="nt"&gt;ADDR&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;':3000'&lt;/span&gt;
  &lt;span class="nt"&gt;CORS_ALLOWED_ORIGINS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;
  &lt;span class="nt"&gt;PUBLISH_ALLOWED_ORIGINS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;'*'&lt;/span&gt;

&lt;span class="c1"&gt;# ...&lt;/span&gt;

&lt;span class="nt"&gt;acceptance tests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
  &lt;span class="c1"&gt;# I would prefer to use a public php-7.3 image with mysqli, but&lt;/span&gt;
  &lt;span class="c1"&gt;# I don't think such a thing exists.&lt;/span&gt;
  &lt;span class="c1"&gt;# So let's reuse the image I created for the dikdikdik web tests.&lt;/span&gt;
  &lt;span class="nt"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;registry.gitlab.com/rva-vzw/dikdikdik.php&lt;/span&gt;
  &lt;span class="nt"&gt;services&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;mariadb:10.4&lt;/span&gt;
      &lt;span class="nt"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;db&lt;/span&gt;
    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;selenium/standalone-chrome&lt;/span&gt;
      &lt;span class="nt"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;chrome&lt;/span&gt;
    &lt;span class="p p-Indicator"&gt;-&lt;/span&gt; &lt;span class="nt"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;dunglas/mercure&lt;/span&gt;
      &lt;span class="nt"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="l l-Scalar l-Scalar-Plain"&gt;mercure:v0.10&lt;/span&gt;
  &lt;span class="c1"&gt;# (the rest of the job follows here)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The &lt;code&gt;JWT_KEY&lt;/code&gt; should work with the &lt;code&gt;JWT&lt;/code&gt; your backend uses
to publish events. The port number in &lt;code&gt;ADDR&lt;/code&gt; as well. If you
use Symfony, as I do, the corresponding configuration of your
backend should be in the &lt;code&gt;.env&lt;/code&gt; file, e.g.&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;MERCURE_PUBLISH_URL=http://mercure:3000/.well-known/mercure
MERCURE_JWT_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZXJjdXJlIjp7InB1Ymxpc2giOltdfX0.FFSjymJCGRDWrmAmPJDoVGuYwnx5FRTjRFkkYfvLkUg
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;(Needless to say: don't use the production JWT and token in the
source code that is used by gitlab! If you're unsure how to
create a JWT, see the section ‘Creating your JWT’
of 
&lt;a href="https://thedevopsguide.com/real-time-notifications-with-mercure/"&gt;this excellent blog post&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2020-12-03:&lt;/strong&gt; That blog post doesn't exist anymore, but 
&lt;a href="https://medium.com/@stefan.poeltl/instant-realtime-notifications-with-symfony-and-mercure-e45270f7c8a5"&gt;I found another page&lt;/a&gt;
that covers mercure and the JWT token.&lt;/p&gt;
&lt;p&gt;Now the problem I ran into, is similar to the
&lt;a href="https://blog.johanv.org/posts/gitlab-ci-codeception-and-selenium-web-tests"&gt;general problem I had with web tests&lt;/a&gt;:
the chrome container doesn't know where the mercure hub is;
the host name ‘mercure’ is not resolved to an ip address.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2022-06-20:&lt;/strong&gt; &lt;em&gt;The solution described below will still work, but
I found a better one. You should just set the
&lt;code&gt;FF_NETWORK_PER_BUILD&lt;/code&gt; variable to 1 in your &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; file,
as described &lt;a href="https://blog.johanv.org/posts/php-ci-demo"&gt;in this post&lt;/a&gt;. If you want to see how
this works for a real life project, you can check out the
&lt;a href="https://gitlab.com/rva-vzw/dikdikdik/-/blob/develop/.gitlab-ci.yml"&gt;.gitlab-ci.yml&lt;/a&gt;
file of &lt;a href="https://gitlab.com/rva-vzw/dikdikdik/"&gt;dikdikdik&lt;/a&gt;, an app to
keep track of the scores when playing &lt;a href="https://www.rijkvanafdronk.be/wiezen"&gt;solo whist&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;To fix this, I figure out the IP address of the Mercure hub when I
start the job, and I replace the host name of the &lt;code&gt;MERCURE_PUBLISH_URL&lt;/code&gt;
in the &lt;code&gt;.env&lt;/code&gt; file by this IP-address. This works, since my frontend
retrieves the publish url from the backend by a rest-call.&lt;/p&gt;
&lt;p&gt;This is how that looks like:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;  script:
    - MERCURE_IP=$(getent hosts mercure | awk '{ print $1 }')
    - echo Mercure IP $MERCURE_IP
    - sed -i "s/mercure:3000/$MERCURE_IP:3000/" .env
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You can review the complete job definition in the &lt;code&gt;.gitlab-ci.yml&lt;/code&gt;
&lt;a href="https://gitlab.com/rva-vzw/wdebelek/-/blob/develop/.gitlab-ci.yml#L129-161"&gt;file in the wdebelek repository&lt;/a&gt;.
The file &lt;code&gt;acceptance/TrickCest.php&lt;/code&gt; contains an
&lt;a href="https://gitlab.com/rva-vzw/wdebelek/-/blob/develop/tests/acceptance/TrickCest.php#L42"&gt;example test involving server sent events&lt;/a&gt;.
And hopefully you can see in the
&lt;a href="https://gitlab.com/rva-vzw/wdebelek/pipelines"&gt;pipelines&lt;/a&gt; that all
tests passed without problems 🤓.&lt;/p&gt;&lt;/div&gt;</description><category>ci</category><category>codeception</category><category>frontend</category><category>mercure</category><category>php</category><category>symfony</category><category>tests</category><guid>https://blog.johanv.org/posts/gitlab-ci-selenium-and-mercure/</guid><pubDate>Fri, 08 May 2020 20:15:00 GMT</pubDate></item><item><title>gitlab-ci and yarn</title><link>https://blog.johanv.org/posts/gitlab-ci-and-yarn/</link><dc:creator>Johan Vervloet</dc:creator><description>&lt;div&gt;&lt;p&gt;For my previous post, on &lt;a href="https://blog.johanv.org/posts/gitlab-ci-codeception-and-selenium-web-tests"&gt;gitlab-ci and codeception&lt;/a&gt;, I created a small project on gitlab that &lt;a href="https://gitlab.com/johanv/codeception-ci-demo"&gt;runs selenium webtests during gitlab-ci&lt;/a&gt;.  The project being tested is just a small vue.js-application.&lt;/p&gt;
&lt;p&gt;Recently I rewrote that small application; now it uses &lt;a href="https://vuejs.org/v2/guide/single-file-components.html"&gt;a single file vue component&lt;/a&gt;. I'm not completely sure what I've done, but it seems to work, and it involves &lt;a href="https://github.com/symfony/webpack-encore"&gt;webpack encore&lt;/a&gt; and &lt;a href="https://yarnpkg.com/en/"&gt;yarn&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Running yarn from gitlab-ci" src="https://blog.johanv.org/galleries/misc/gitlab-codeception-yarn.png"&gt;&lt;/p&gt;
&lt;p&gt;Now the challenge was to run yarn from gitlab-ci. I was looking for a docker container with yarn (even tried to build one myself), but it took me some time before I discovered that yarn is included in the &lt;a href="https://hub.docker.com/_/node"&gt;node&lt;/a&gt;-container.&lt;/p&gt;
&lt;p&gt;So I now use this node container in an extra task of the build stage in my &lt;a href="https://gitlab.com/johanv/codeception-ci-demo/blob/master/.gitlab-ci.yml#L25"&gt;.gitlab-ci.yaml&lt;/a&gt;. I create an artifact with the generated javascript, which is used in the test stage. &lt;a href="https://gitlab.com/johanv/codeception-ci-demo/pipelines/68644877"&gt;That seems to work&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As I said before, I am new to vue, and it's the first time I use yarn and webpack. So maybe I am making some obvious mistakes. Please let me know if there are things that can be done in a better way.&lt;/p&gt;&lt;/div&gt;</description><category>ci</category><category>docker</category><category>frontend</category><category>tests</category><category>yarn</category><guid>https://blog.johanv.org/posts/gitlab-ci-and-yarn/</guid><pubDate>Sat, 29 Jun 2019 19:02:12 GMT</pubDate></item><item><title>gitlab-ci, codeception and selenium web tests</title><link>https://blog.johanv.org/posts/gitlab-ci-codeception-and-selenium-web-tests/</link><dc:creator>Johan Vervloet</dc:creator><description>&lt;div&gt;&lt;p&gt;All the php projects I work on, have tests. For some projects, we use &lt;a href="https://phpunit.de"&gt;PHPUnit&lt;/a&gt; as testing framework, but for more recent projects, I prefer to use &lt;a href="https://codeception.com"&gt;Codeception&lt;/a&gt;, because it has an elegant way to write acceptance tests. We also use gitlab for our projects, and by adding a nifty &lt;code&gt;.gitlab-ci.yml&lt;/code&gt; file to our source code, we made &lt;a href="https://about.gitlab.com/product/continuous-integration/"&gt;gitlab run our test suite&lt;/a&gt; every time new commits are pushed to the repository.&lt;/p&gt;
&lt;p&gt;Recently, we started using &lt;a href="https://codeception.com/docs/modules/WebDriver"&gt;Selenium WebDriver&lt;/a&gt; with codeception, so that we could run browser tests, to make sure that the javascripts we use keep working. Of course we wanted to run these browser tests with gitlab-ci as well, but that was not as easy as we thought it would be. The idea was to run selenium with a browser &lt;a href="https://codeception.com/docs/modules/WebDriver#Headless-Selenium-in-Docker"&gt;via a docker container&lt;/a&gt;, but the challenging part was setting up a webserver the browser could connect to.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2022-06-17:&lt;/strong&gt; &lt;em&gt;In the mean time, I found out
&lt;a href="https://blog.johanv.org/posts/php-ci-demo/"&gt;how to run an apache server as a gitlab job service&lt;/a&gt;, so the rest
of this post has become kind of obsolete. I updated
&lt;a href="https://gitlab.com/johanv/codeception-ci-demo"&gt;the demo project&lt;/a&gt;, you should check
the &lt;a href="https://gitlab.com/johanv/codeception-ci-demo/-/blob/master/.gitlab-ci.yml"&gt;.gitlab-ci.yml&lt;/a&gt;
file, 
the &lt;a href="https://gitlab.com/johanv/codeception-ci-demo/-/tree/master/docker/apache"&gt;Docker configuration for the apache container&lt;/a&gt;,
and (of course 😉) the &lt;a href="https://gitlab.com/johanv/codeception-ci-demo/-/blob/master/README.md"&gt;README&lt;/a&gt;
to find out how it all works.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;In a first attempt, I tried to start all the containers needed for our application, running &lt;code&gt;docker-compose up&lt;/code&gt; from the ci like we do it for local development. This worked sometimes, but after a couple of builds the docker networks used by our gitlab runners got completely messed up, which was hard to fix.&lt;/p&gt;
&lt;p&gt;In a second attempt, I tried to use &lt;a href="https://docs.gitlab.com/ee/ci/services/"&gt;Gitlab CI Services&lt;/a&gt; for all the containers in our &lt;code&gt;docker-compose.yml&lt;/code&gt; file. I gave up before I completely configured that, because I noticed the networking problems wouldn't go away.&lt;/p&gt;
&lt;p&gt;After days of swearing, I finally got it running. I think the networking problems were caused by the nginx-container I tried to use for the web tests. But actually I didn't need a container for nginx. It turned out I could just juse the php built-in development server to run the tests.&lt;/p&gt;
&lt;p&gt;So I ended up by adding  a service for selenium with chrome and  a service for mysql (the project I was trying this on, didn't really need other services), and I just added a &lt;code&gt;php -S&lt;/code&gt; statement to the script that ran the tests, I had a running server.&lt;/p&gt;
&lt;p&gt;I still needed a small hack, to make the browser in the selenium container actually find the webserver. I ended up using a &lt;code&gt;sed&lt;/code&gt;-command on the configuration file of my test suite in codeception.&lt;/p&gt;
&lt;p&gt;For reference, here is a part of my &lt;code&gt;gitlab-ci.yml&lt;/code&gt; file:&lt;/p&gt;
&lt;pre class="code literal-block"&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;    - LOCAL_IP=$(ip route get 8.8.8.8 | awk -F"src " 'NR==1{split($2,a," ");print a[1]}')
    - echo Local IP $LOCAL_IP
    # Run the php built in server. Don't try to run nginx as a service, that only causes troubles. ;-)
    - php -S 0.0.0.0:8080 -t public/ 2&amp;gt; /dev/null &amp;amp;
    - sed -i "s/localhost:8080/$LOCAL_IP:8080/" tests/acceptance.suite.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that for this to work, I had to fiddle with the php container to have iproute2 installed.&lt;/p&gt;
&lt;p&gt;If you want to see how it actutally works; I created a &lt;a href="https://gitlab.com/johanv/codeception-ci-demo/pipelines"&gt;small demo project on gitlab&lt;/a&gt; that uses codeception in gitlab-ci to run a couple of browser tests. You can find the source code on gitlab: &lt;a href="https://gitlab.com/johanv/codeception-ci-demo"&gt;https://gitlab.com/johanv/codeception-ci-demo&lt;/a&gt;.&lt;/p&gt;&lt;/div&gt;</description><category>ci</category><category>frontend</category><category>tests</category><guid>https://blog.johanv.org/posts/gitlab-ci-codeception-and-selenium-web-tests/</guid><pubDate>Thu, 16 May 2019 05:27:33 GMT</pubDate></item><item><title>Van github naar gitlab</title><link>https://blog.johanv.org/posts/van-github-naar-gitlab/</link><dc:creator>Johan Vervloet</dc:creator><description>&lt;div&gt;&lt;p&gt;Mijn website is een statische website. Dat wil zeggen dat de hele site automatisch wordt gegenereerd op basis van een aantal tekstbestanden. En die tekstbestanden beheer ik met git.&lt;/p&gt;
&lt;p&gt;Gisteren verhuisde ik de git-repository met die teksten van &lt;a href="https://github.com/johanv/blog.johanv.org"&gt;github&lt;/a&gt; naar &lt;a href="https://gitlab.com/johanv/blog"&gt;gitlab&lt;/a&gt;. Niet omdat ik problemen heb met het &lt;a href="https://blogs.microsoft.com/blog/2018/06/04/microsoft-github-empowering-developers/"&gt;bedrijf achter github&lt;/a&gt; (want Microsoft is tegenwoordig érg goed bezig), maar wel omdat ik &lt;a href="https://about.gitlab.com/product/continuous-integration/"&gt;gitlab-ci&lt;/a&gt; wou gebruiken om mijn site te bouwen. Concreet komt het erop neer dat, telkens ik een nieuwe versie van de source push, gitlab voor mij mijn site &lt;a href="https://gitlab.com/johanv/blog/pipelines"&gt;automatisch bouwt en deployt&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Misschien heeft github ook wel zo'n service. Maar die van gitlab heb ik nu al vaak gebruikt, en ik ben er erg tevreden over. Dus vanaf nu wordt mijn blog gepowerd door &lt;a href="https://getnikola.com"&gt;nikola&lt;/a&gt; en gitlab. Waarvoor dank.&lt;/p&gt;&lt;/div&gt;</description><category>ci</category><category>git</category><category>johanv.org</category><category>nikola</category><guid>https://blog.johanv.org/posts/van-github-naar-gitlab/</guid><pubDate>Sat, 11 May 2019 08:16:15 GMT</pubDate></item></channel></rss>