Hello world! 👋 Making something awesome?

Hi! I'm Marc, an experienced SaaS CTO and software/product engineer.

Over the last 15+ years, I was the sole developer behind the hugely successful ThriveCart, as well as many other platforms.

I'm an expert at getting the maximum result from the leanest resources, saving you time and increasing your revenue.

I'm always interested in how I can help cool people make cool things.
Read my CV, send me an email and let's talk!

Generating JWTs for GitHub Apps with PHP

As I’m working on my new AI startup Rivets, I’ve been setting up a GitHub App. That’s not an OAuth app, but the second type they provide, where the app can operate as itself as opposed to operating as you on your behalf. There’s an excellent PHP library lcobucci/jwt available to handle the meaty parts of generating JWTs, but I had some trouble getting it working with GitHub Apps specifically, as there are some quirks, and not a huge range of examples.
Read more →

Using Coolify as an alternative to Laravel Forge

The more I use Coolify, the more I’m impressed by it. It’s a great alternative to platforms like Laravel Forge, Vercel, Heroku and others. Following on from my previous post about setting this up, I’ve also published a Github repository to make it easy to get started. Coolify handles everything I’ve thrown at it, and I’m using it in production with PHP, Node, Python, Postgres, and MySQL. If you work across different technologies or like to experiment, it’s never been easier to take back control from the cloud and run things on your own servers.
Read more →

Using Cloudflare Workers to serve custom error pages

I’ve recently had to shut down some old platforms. This presented an interesting challenge, as I had some requirements: No ongoing server costs/maintenance Custom error messages depending on the domain, so the solution can be applied to multiple legacy platforms Work across wildcard subdomains, which are used to identify the tenant I already manage DNS through Cloudflare, and after investigating their Workers a little bit, I found that they provide the perfect solution.
Read more →

Syncing multiple GBs from EFS to a remote S3 account

Whilst shutting down some old projects, I’m archiving all of their folders and storing them in S3 in case of an emergency. I don’t have AWS credentials stored and set up on the EC2 instance, so I’m passing them through as variables to the script below. As with the script to export tens of thousands of individual MySQL databases, you’ll want to edit the values at the top. EFS_MOUNT_POINT is the full path to where the EFS drive is mounted S3_BUCKET is your target S3 bucket AWS_… self explanatory!
Read more →

Exporting 10,000+ MySQL databases

I’m a big fan of single-tenant databases, one for each customer. With MySQL and InnoDB, a single server can scale to tens of thousands of individual databases. As long as you’re deliberate with your schema design up front - here, I’m a big fan of explicit key/value tables that let you assign arbitrary metadata to objects that are more normalised - you buy yourself incredibly simple isolation by simply selecting the appropriate database once you’ve identified your tenant (using PHP’s select_db()).
Read more →