My most read articles on this blog are about Gitlab CI/CD with PHP. They cover a basic linting, testing and crude deploying process.

Today I want to look at my current CI/CD process for my Laravel projects in more depth. Currently the pipelines of my projects might vary slightly but is very similar to this:

Gitlab Pipeline

So there are 5 main stages in the process:

  • Preparation - The pulling down of dependencies and storing them in an artifact
  • Syntax - Check code syntax
  • Testing - Run unit tests
  • Building - Build assets
  • Deployment - Deploying to an appropriate server

The stages are processed in order with each stage containing one or many tasks. Should one task fails in a stage then the whole pipeline stops and is marked as failed.

To run the pipelines I make use of gitlabs free tier which gives you access to 2000 shared minutes per month as well as a runner on a server I have. More about setting that up can be found here.

Continue reading

I recently watched the following great talk on hacking laravel apps.

Towards the end of the talk Antti shows how it is possible to potentially gain root access to a server if your scheduler is running as root too.

As soon as I saw it I know I had a couple of apps where this vulnerability could have been exploited and so went to patch them straight away.

Whilst I knew what needed to be done I wasn’t 100% on how exactly I’d add an entry into another user’s crontab that wasn’t my own or root.

Turns out it was quite simple, acting as root use the -u argument to specify the target user.

sudo crontab -e -u www-data

In the above example the crontab for the user www-data would be opened. Since my php-fpm instance is run by www-data and therefore has access to all the application code already this made sense to me.

Hopefully I’ll never make this mistake again. If you haven’t already seen Antti’s talk above I’d highly recommend doing so asap!

Continue reading

For one of my recent projects I wanted to make use of the free allowance that AWS gives for SES.

One of the conditions of the SES allowance was that your calling app needs to be hosted on EC2.

I’ve not used EC2 before so I figured this would be a good way to dive into it.

Whilst I would never usually install software like composer on a production server, this was purely to test things out.

So after signing up for AWS and creating a local ubuntu server on an EC2 t2micro instance then cloning down the project I ran composer install to come across the following message:

composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)

mmap() failed: [12] Cannot allocate memory

mmap() failed: [12] Cannot allocate memory
PHP Fatal error: Out of memory (allocated 822091776) (tried to allocate 4096 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

Fatal error: Out of memory (allocated 822091776) (tried to allocate 4096 bytes) in phar:///usr/local/bin/composer/src/Composer/DependencyResolver/Solver.php on line 223

822091776bytes is over 800mb of memory being consumed by composer.

Continue reading


I recently build my first site with Jigsaw and deployed it on Netlify.

As part of that project I had to get some data from the Instagram API and present a feed of the latest 5 images on the site.

Rather than dealing with CORS errors in javascript I wondered what I could get away with in PHP during the build phase on a statically generated site.

Would I be able to:

  • Query some form of public json endpoint
  • Find the urls for the latest 5 images
  • Download them locally resize them for efficiency
  • Display them using Jigsaw
Continue reading


Laravel apps read sensitive information from their .env file.

Recently I found out that Laravel Mix can pass values from the same .env file to the js portion of your app as long as they are prefixed with MIX_

I use Gitlab ci pipelines to build production assets so that I dont need that additional tooling on the production servers the main one being:

  • yarn run production

This is preceded with cp .env.example .env meaning when the build commands are being run, they are going to use values from the .example.env file.

If your project doesn’t make use of anything from the .env file then this is totally fine, however in scenarios where you do, since production applications will almost certainly have different .env values to those in the .example.env file (Never commit credentials to source control!) the resulting file will have been built with the wrong credentials.

In this article I’m going to show how you can use gitlab CI to build those assets with updated environmental variables so that they function as expected when deployed to your production servers.

Continue reading


Laravel’s Form Requests are a great way of removing validation logic from your controllers.

There are times were it can be useful to update or change the request data before it is passed to the validator for example formatting postcodes, removing invalid characters or providing default values to data.

The official documentation shows how we can perform additional logic after the rule sets have been run but not before hand.

Digging through the Form Request api there is mention of a method called prepareForValidation which is an empty method that is called before the actual validation rules are run as can be seen in implementation:

the prepare for validation method

So given that the method is empty how do we use it and go about updating the form request data?

Continue reading

Introduction and Prerequisites

I’ve been remote working full time for over 3 years now.

In that time I’ve had to work with a number of clients who restrict access to their internal systems via IP Address whitelisting.

As a developer who often works from different locations and countries this can quickly become problematic.

A paid for solution is to purchase a Dedicated Static IP VPN from a reputable provider like NordVPN. and ask the clients IT team to whitelist your new Dedicated Static IP.

This is something I’ve been doing for a while and whilst the initial set up is a little fiddly, (You have to set up 2 accounts and get their team to link them together) its worked flawlessly for me.

However if you have the following:

  • SSH access to a device in a location with a Static IP (Perhaps you get one from your ISP or your office has one)
  • You use Linux or OSX (Sorry windows guys I don’t think even with WSL this will work).

Then you can use the super handy command line tool SSHUTTLE to route all (or some) of your traffic through that device.

Lets take a look at getting it working…

Continue reading

One of the projects I’ve been working recently has involved writing a system to communicate with a Clients pre-existing Legacy system. The system doesn’t have the ability to “talk out” but can be queried using a SOAP service.

The legacy system is:

  • Slow to interact with
  • Prone to crashing regularly

Here’s how we dealt with those 2 issues:

Since we don’t want to impact our end users experience the project has been set up to make use of Laravel queuing system with Redis and those queues are configured with Laravel Horizon.

When these jobs failed for whatever reason - including the clients system going down we wanted to be notified so that someone could look into what was happening.

The team at created a great package to do that handle notifying us when a failed job occurred.

However there are multiple jobs being run concurrently that run as frequently as every minute to check for things on their server. Which mean’t that once the legacy system went down we would receive multiple notifications until the system came back up, (In some cases this has been hours - not ideal).

After a while being flooded with these sorts of notifications makes them become an annoyance rather than useful and you begin to start ignoring them.

So I set out to write something that gave me everything the Spatie package did but also allowed me to throttle how frequently notification of a given type would be sent to us.

Laravel throttled failed jobs!

Continue reading

Today at work we switched away from Telegram to using MS Teams for our company messenger.

Since we we’re already paying for it it made sense to plus it offers a lot more than just a messenger such as custom wiki functionality.

One of the things we were making use of was telegram bots for our applications to sent us updates on key events of interest.

I’ve only recently started to make use of Laravels notifications in the projects I’ve been working on and to send messages via telegram I’d been using this package.

However whilst I’d found documentation that said that sending messages to MS Teams was possible there didn’t seem to be a notification channel for laravel.

So I went about building a basic one today:

Laravel Notifications for Microsoft Teams

Continue reading

Last year I began working at a new startup - NX Technology.

As a start up with limited funding we’re constantly looking for efficiencies and ways to get the most out of what we already have whether that be in hardware or software.

Whilst previously I’ve set up and self hosted a gitlab instance at NX we needed to get things up and running asap so we decided to use the gitlabs free tier.

At the time of writing the bronze tier comes with unlimited private repositories and 2000 gitlab ci minutes using gitlab’s shared runners.

One of the things I love about this is that once those minutes are up you can either pay for more or use your own runners to process jobs for your projects.

We have an old -nothing special- server which we’ve set up a gitlab runner on that will handle jobs for us along with gitlab’s shared runners and when our free minutes run out all jobs will run through that server.

Since most of the time when you’re pushing code to gitlab your laptop will be on, you can use your development laptop to help out too!

Continue reading
Author's picture

Talv Bansal

Full Stack Developer, Part Time Photographer

Head of Software Engineering