Reduce your serverless bills using open source

Serverless is quite trendy nowadays. For those of us new to the Cloud game, Serverless is a way to deploy your apps without worrying about maintaining infrastructure. Imagine the LAMP stack (Linux, Apache, MySQL, and PHP). With serverless you only have to worry about the ‘P’ that is PHP. Linux (the operating system), Apache (the web server), and MySQL (the database) are all managed by the cloud service provider. Examples of modern serverless platforms include Heroku, Vercel, Fly.io, & AWS Elastic BeanStalk.

Great right? Yes great you and your developers can finally focus on just delivering your application. Correct, but it comes at a cost. How most of these platforms lure you in is with a free tier where you get a lot of features up front like automatic resource scaling but you need to pay-as-you-go and/or pay a tiny subscription. This seems innocent and even cost-effective to the fledgling development team who wants to get their product out there fast, but while infrastructure scales well with serverless your costs don’t. Cara.app is a cautionary tale, it might still be unprofitable from the huge serverless bill it accrued. Although you could use “spend management” like the one provided by Vercel.

There is another way to go “serverless” but with servers. Using projects like Coolify and Dokploy to manage your servers is a great alternative – let’s call them Open Source Serverless. There are other tools like Kamal and Dokku but I chose to look at Coolify and Dokploy because they have an easy-to-use Web Interface. Below I will be comparing traditional Serverless and Open Source Serverless (Coolify and Dokploy).

FeaturesTraditional Serverless
(Netlify, Vercel, Heroku etc.)
Open Source Serverless
(Coolify, Dokploy, Dokku etc.)
CostHigh cost from various types of chargesCheap, can even run on a Raspberry Pi
Vendor Lock-InYesVery portable
MaintenanceEasy to maintain, often custom-made for a particular development frameworkNeed some understanding of Nixpacks, Docker & the tool itself
User Interface (UI)Very good UIDokploy has a great interface but others could be better
Customization & OptimizationLimited Options to optimize your infrastructure which is important as you scaleUnlimited options in terms of optimizing your infrastructure
Open sourceLimitedYes, which makes your serverless infrastructure very customizable

I currently use Open source serverless for my needs and I will go into details on my experience highlighting each point in the table above.

  1. Cost: The cost of Open source serverless (Coolify) in my experience is very cheap. I am only paying for my VPS servers since I am self-hosting. Max $20 monthly for two servers. This setup on other cloud providers will cost me an arm and a leg.
  2. Vendor Lock-In: I was able to try different Open source platforms before settling on one. No lock-in it’s Docker & Traefik with a dashboard and you can move your app somewhere else.
  3. Maintenance: This is where I spent a lot of time. Bringing over my app and setting up my custom infrastructure took some time and planning. I also encountered some bugs in the software – which I had to patch or fix manually.
  4. User Interface: For this, I looked at Vercel, Coolify & Dokploy. Vercel wins hands down it was so sleek and easy to get around. I was tempted but I resisted considering the costs. Coolify’s UI is all over the place and takes getting used to but it has the best features and services. Dokploy’s UI was okay although it had fewer features than Coolify.
  5. Customization & Optimization: This is where Coolify wins. I specifically choose Coolify for it ease of customization and it huge community. Whenever I ran into a roadblock I could easily go into the code and make changes. Using Dockerfile, Docker Compose & NixPacks, I could easily create my own services and deploy them.
  6. Open Source: The open-source nature of Coolify has attracted a huge community that helps with support and testing. For others like Vercel, you might not easily access and contribute to the project and it’s community.

In conclusion, use what is best for you, I would use this rule of thumb:

  • Normal serverless like Vercel; if I have the funding, little time, and just want to focus on building apps.
  • Open Source Serverless like Coolify; if I have time, limited funding, and going to support multiple types of services and apps.

Best way to scale up your PHP apps

PHP has a new and modern official app server called FrankenPHP. This gives your PHP apps the super power it needs to serve various workloads beyond what the tradition methods have to offer. These superpowers includes the following:

  1. Speed & performance.
  2. Real time Capabilities.
  3. Support for modern, cutting edge web protocols like Early Hints, QUIC+HTTP/3, etc.
  4. Ease of distributing you PHP app as a single binary.

Below is a result of performance benchmark I made, comparing FrankenPHP, Nginx and PHP CLI Server out of the box.

I used wrk with 12 threads, 400 concurrent connections for 30 seconds for each server on a Ubuntu WSL machine with a 12GB RAM and 20 Cores available. The results are staggering and it shows the power of FrankenPHP out of box.

Note that it is possible to get other servers, like Nginx to this level of performance but it will require some fine-tuning and optimization on the developers side.

So what are you waiting for go ahead, use, tinker and contribute to this amazing project if you can.

Intro to DDEV for Laravel

Are you tired of spending time setting up your development on the local environment instead of creating solutions? If so, DDEV is the answer. DDEV is an open source tool for creating and running local web development environments in minutes. It supports PHP and Node.js.

It’s so simple you can follow the recipe below to get started:

  1. Install DDEV using the instruction at https://ddev.readthedocs.io/en/stable/users/install.
  2. Ensure Docker Desktop is running.
  3. In the laravel root directory run ddev config.
  4. Follow the instructions and ensure that the document root is set to Laravel’s public directory. Then run ddev start.
  5. Run migrations for the Laravel database ddev exec php artisan migrate .
  6. Now type and run ddev launch .

Easy as pie. Have fun!!

Don’t forget to support the project https://github.com/sponsors/ddev.

Simple Unit Testing for Types in C11

Sometimes I find myself doing coding tests to keep my problem-solving skills sharp. One of the platforms I use is CodeWars, a platform owned by Andela. My current stack is JavaScript (including NodeJS), PHP, and C/C++. I noticed the tests for the C and C++ exercises were written using a library called Criterion, which brings us to the topic of Unit testing in C and C++.  I did some intense C and C++ work a while back on embedded Linux systems and one of the tools I lacked was a simple library to do testing in. Looking at the criterion I realized I had just found an easy-to-use tool for testing my C/C++ work.

I decided to put this simplicity to test and in order to do so I decided to use a toy CLI app I wrote in C some years ago. This app has a function for random number generation.

In file app.c:

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<string.h>
#include "app.h"
........
int generateAccountNumber(){
    srand(time(NULL));
    return rand();
}
........

Testing this is as simple as the code below:

In file tests.c:

#include <stdio.h>
#include <criterion/criterion.h>
#include "app.h"
#include <string.h>

#define DETERMINE_TYPE(x) _Generic((x), \
    int: "int", \
    float: "float", \
    double: "double", \
    char: "char", \
    long: "long", \
    default: "unknown")

Test(bankapp, random_num) {
    cr_assert(!strcmp("int", DETERMINE_TYPE(generateAccountNumber())));
}

All you need to do now is compile the test using:

gcc tests.c app.c -o tests -lcriterion

One thing to note is that the main function of the application you are testing must be in a separate file to prevent clashing with the main file provided by the Criterion testing framework. And that is it! You have a test.


I added the C11 _Generic macro feature to highlight a new C language feature that allows you to “return” a select value or function based on the type provided. This can be used for implementing programming features such as function overloading, Generics, Type checking like I used here, and many more. We will be looking more into this C11 feature in future articles. Thanks for reading.

References

  1. Criterion Testing Framework Documentation.
  2. Blog on how to use Generic Macros in C.

How to save your software project from the costs of abstraction

All software tools mainly do one form of abstraction or the other to save you time or money, this abstraction comes at a cost. I have been working in software for years now and every time I am tasked with creating a new project from scratch, the question of which programming language, framework, libraries, platform, or tools to use always comes up. My answer is always “Use the best tools for the situation”. This is the engineer’s approach to software development, maybe it’s my strong engineering background rearing its head.

Unfortunately, nowadays the choice of the software we use is based on trends. The trends are set by corporations pouring millions of dollars into marketing their tools as the next solution to all software engineering problems. Examples of these marketing campaigns are AI replacing developers, companies touting the slogan “End of Software” or claims that the Cloud will replace all infrastructure needs. These ideas are not bad, if anything I agree that they are innovative ideas, but at the end of the day as a software professional, you must see them as another tool in your toolbox.

The cost you incur from using the wrong tools can cost you millions and a huge chunk of your revenue. This is a short checklist of questions I ask to ensure I am using the right tool:

  1. Usefulness:
    Is this tool going to add any value to my project? Is using these tools cost-effective will it save time & money? Beware of using a tool because everyone is using it, do not fall for the marketing gimmick.
  2. Maintainability:
    What will it cost to maintain this tool? Can it be maintained internally or is there support – free or paid?
  3. Extensibility
    If user requirements grow – which they will, is this tool flexible enough to be updated or upgraded at a reasonable cost?
  4. Maturity
    The more mature a software project is, the more stable and secure it is. Are there any benefits to bearing the risk of using an up-and-coming tool over a tested and mature tool?

At the end of the day, it is in your best interest and that of stakeholders to pick the right tools.

strlen vs mb_strlen in PHP

As a PHP developer, I am sure you use strlen often to check for the length of strings. strlen does not return the length of a string but the number of bytes in a string. In PHP, one character is one byte therefore for characters that fall within the 0 – 255 range in ASCII/UTF-8 all seem well; that is string length matches the number of bytes. There is nothing wrong with this approach of checking the length of a string using strlen if you are checking the length of string that you typed in Latin characters for your program because ASCII and some basic UTF-8 characters fall within the range of a single byte.


The problem with using strlen occurs when there is a character outside of the 1-byte range, then strlen returns values greater than the string length, which can lead to bugs and general confusion. The solution to this is to use mb_strlen, which returns the exact length of the character by checking the encoding set. Check out the snippet displaying this:

 // strlen okay: Result is 4
echo strlen('Rose');

// strlen not okay: Result is 7
echo strlen('Michał');

// mb_strlen okay: Result is 6
echo mb_strlen('Michał');

A rule of thumb I use when checking length of character input from user especially from a web browser I use mb_strlen but when I need to use the actual size of the string I use strlen for example when transferring string through or saving them in a database or if it is a string I typed out myself.

Next time you want to check the length of a string in PHP or any language it is best to know the appropriate function to use for the type of string characters.

Follow me on Twitter / Mastodon / LinkedIn or check out my code on Github or my other articles.

Software development process for the Solo developer

Completing and shipping personal projects as a solo developer can be tasking when you have other responsibilities. Over the years I have gathered a simple framework to ship good software quickly. The steps can be divided into:

  1. Scope and objective.
  2. Strict deadline.
  3. Testing.
  4. Deployment and maintenance.

You may ask, what about other methods agile, waterfall etc. I have found those techniques to be too cumbersome for the solo developer. A solo developer is a team of one with limited time and resources, a pragmatic approach is needed if you want results. 

Let’s breakdown each step and provide why they are necessary for your project success and how to implement them.

  1. Scope and objective

I try to ensure every software project solves at least a problem for its users even if the user is just you. A lot of big projects have started out by programmers scratching their own itch. E.g Linux and Dropbox

Software developed with a user in mind has various considerations like usability, security etc. that you rarely find in a toy project.

  1. Strict deadline

Be very strict and realistic about when you want your software to make it into the world. A realistic deadline will ensure you do not fall into a lot of traps that will waste the little time and resources you have at your disposal as a solo developer. Some of these mistakes are:

  • Adding unnecessary features.
  • Not getting user feedback quickly.
  • Slow decision making.
  1. Testing

The rule of thumb here is to see untested code as incomplete code. Testing is at the core of software, especially for solo projects where you have little to no marketing resources. The best marketing you have is good working software. Testing ensures you have a usable software that meets set out objectives and makes your users happy.

  1. Deployment and maintenance

Now you have finally shipped a good working software project following the guidelines above. Well, you can now expect feedback for users (including you) as the software is used for various purposes over its lifetime. Some of the feedback may be harsh or humbling, brace yourself, listen and use this as a way to better your software project while it is in use. If possible, seek out users’ opinions and pain points.

Well, those are the 4 simple steps I currently use for my solo projects. I am practical and pragmatic in my software development approach. I explore various technologies and programming languages but at the same time I do not follow trends. As a solo developer you do not have time to jump on trends. Your best tools are the ones currently at your disposal.  


If you liked this article or want to reach out to me, you can follow me on: mastodon or twitter. You can also keep up to date by signing up for my newsletter.

Separating WSL (Linux) path and Window path

I often find myself hacking the Linux kernel for fun and profit. This time I was trying out Buildroot Embedded Linux build system and the first stumbling block using WSL was the fact that Windows path containing spaces were appended to the WSL path which the Linux file system has issues with. Running make for the Buildroot gives the error below:

Your PATH contains spaces, TABs, and/or newline (\n) characters

Follow the steps below for the solution:

  1. Create a config file for WSL interop in the WSL distro you are using. sudo nano /etc/wsl.conf
  2. Copy and paste the config below in the file:
[interop]
appendWindowsPath=false
  1. Save then restart the WSL distro in the Windows shell (not the WSL distro).
wsl -d [distribution name] --shutdown
wsl -d [distribution name]
  1. Check the path to echo $PATH to ensure all is well, only the Linux path should remain.
  2. And we are done! Finally we can build our kernel without worries.

If you forget your Windows Subsystem for Linux (WSL) password, try this.

I have been using Windows Subsystem for Linux (WSL) for a while now and sometimes I create a distribution and forget the password. If you find your self in the same situation, just follow these steps:

  1. Open the Windows Shell.
  2. Type in wsl -l to get the list of WSL Distributions you have on your system.
  3. Login to the distribution using wsl -d [Distribution Name].
  4. Type in whoami to get your default user name. Note this down.
  5. Logout of the distribution, by typing exit.
  6. Log in as root: wsl -d [Distribution Name] -u root.
  7. Change the password for the user by running this passwd [User Name] and follow the instructions.
  8. If all goes well you should get a “passwd: password updated successfully” message.
  9. Logout again using exit .
  10. Now you can use the new password for your WSL Distribution default user.

Hope this was helpful to you. Thanks for reading.

System statistics reporting using Laravel

The Laravel web framework comes with a lot of powerful tools and one of them it the Task Scheduler. This allows you to create and manage all your automated – Cron Jobs – tasks within the framework. If you do not write Cron jobs often, going through documentation or memorizing the Crontab syntax and expression can be extra work (I usually use crontab.guru to simplify this ). Laravel uses functions such as everyTwoMinutes() which is simple to remember and implement. There is also per second scheduling which is not available by default on crontab.

First, you have to open the app/Console/Kernel.php file. Your scheduled task will be added in the schedule(Schedule $schedule) function, by calling the $schedule object. There four main types of calls you can make using the $schedule object:

  1. A closure function containing Laravel/PHP code you wish to run.
  2. A command which runs an Artisan command.
  3. A queued Job.
  4. Command line scripts which can run external scripts.

I will be running an external script (using exec ) to get my systems stats and then send them to myself every 5 minutes. To use an already setup docker environment you can clone this repo and follow the setup instructions (If you choose to use the docker environment. Run your commands in the ‘web’ container) . Copy the code block below in the schedule function:

 
$command = 'echo "------------------" >> out.txt &&';
        $command .= 'top -b -n 1 >> out.txt &&';
        $command .= 'echo "------------------" >> out.txt &&';
        $command .= 'cat /proc/meminfo >> out.txt &&';
        $command .= 'echo "------------------"';
        
        $schedule->exec($command)
        ->appendOutputTo('out.txt')
            ->name('System Stats')
            ->everyFiveMinutes()
            ->emailOutputTo('me@example.com');

Then first test using php artisan schedule:test select the number associated with this task and click enter. if there are no errors, run php artisan schedule:work to start the scheduler if you are on a development environment. For production, add this to your Crontab :

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

NOTE:

  1. Ensure email sender (mailer) of choice is configured on the .env file.
  2. If you choose to use the docker environment. Run your commands in the ‘web’ container.

That’s it, you can include other server stats you want to send through email in the exec function of the scheduler.

References:

  1. Laravel Documentation: https://laravel.com/docs/10.x/scheduling#task-output