Budget – Official Release

Budget - The Official Release

Late last year, I released Budget, a free open-source App powered by the Costs to Expect API, with a beta tag. After bringing the Wife on board to help, we started to respond to feedback and polish the App. We wanted as much feedback as possible before the official release which is now ready.

Beta Release

We spent quite a while testing the App before releasing it with the beta label. However it is always amazing just how many issues appear when the public at large start using your stuff.

We ended up pushing seven small updates, each improving the UX and UI of the App that extra little bit. All these improvements will make it into Budget Pro (the subscription version of Budget) and eventually all my other Apps. After 25 years of web development, I still admit I have a lot to learn and am always happy when I do learn something new.

I’ve released several Apps over the last two years. However none have been as polished as Budget and I have to say I am proud of what I’ve created and keen to start focusing on Budget Pro, the commercial offering of Budget.

I have a blog post coming soon explaining why there are going to be two versions of Budget and why they are going to be created in the way they are. The short story is, I’ve always intended for the Apps to be separate, and I think the approach I’m taking will ensure that they can each shine in their own way.

The Next Chapter

This is the start of a new chapter and I’m keen to see where it goes, only time will tell.

We learned so much during the last two months, hopefully we can benefit from the new knowledge as we approach the beta release of Budget Pro. Budget Pro is much more complicated than Budget so I’m sure we will discover an entire new set of issues which hopefully our beta users will be able to help us resolve.

My typical project setup for Laravel

My Laravel project setup for Windows, Docker, WSL2 & PHPStorm

This is one of those posts that is more of a reference for me rather than general information. If you use PHP, Docker, MySQL, Windows, WSL2 and PHPStorm this post about my typical Laravel project setup may be of interest to you.

Docker and WSL2

I use Docker, specifically docker compose. Typically, I define two services in the docker-compose.yml file, [project_name].app and [project_name].mysql. If the project is part of a service I will define a network, this is to make it easier for containers to communicate. All the Costs to Expect Apps rely on the Costs to Expect API so they all share the same network.

Below is an example of a docker-compose.yml file for Budget, our free budgeting tool.

version: '3'
services:
    costs.budget.app:
        build:
            context: .
            dockerfile: .docker/app/Dockerfile
        image: costs.budget.app
        container_name: costs.budget.app
        ports:
            - "80:80"
        volumes:
            - .:/var/www/html
        env_file: .env
        environment:
            TZ: UTC
            DB_HOST: ${DB_HOST}
            DB_DATABASE: ${DB_DATABASE}
            DB_USERNAME: ${DB_USERNAME}
            DB_PASSWORD: ${DB_PASSWORD}
    costs.budget.mysql:
        build:
            context: .
            dockerfile: .docker/mysql/Dockerfile
        image: costs.budget.mysql
        container_name: costs.budget.mysql
        ports:
            - "3306:3306"
        env_file: .env
        environment:
            TZ: UTC
            MYSQL_DATABASE: ${DB_DATABASE}
            MYSQL_USER: ${DB_USERNAME}
            MYSQL_PASSWORD: ${DB_PASSWORD}
            MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
        volumes:
            - ./.docker/mysql/data:/var/lib/mysql
networks:
    default:
        name: costs.network
        external: true

I leave the ports at their default values. The exception is when I know I will need to run more than Docker container at a which need to communicate. I always need to run the Costs to Expect API at the same time as another Costs to Expect App so will typically map the ports on the API to 8080 and 3308.

The dockerfiles for each of the services exist in a .docker folder. I typically end up with .docker/app/Dockerfile and .docker/mysql/Dockerfile. The .docker/mysql folder will also contain a data folder, this is the volume for the MySQL data.

The MySQL Dockerfile doesn’t include any configuration, just FROM mysql:8, the example below shows a Dockerfile for a typically Laravel application.

I used to include Composer and PHPUnit but have moved away from the additional complexity as it didn’t really offer any benefits and just made configuration in PPHStorm more complicated.

FROM php:8.1-apache

COPY . /var/www/html
COPY .docker/app/vhost.conf /etc/apache2/sites-available/000-default.conf

RUN apt-get update && apt-get install -y \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install -j$(nproc) gd

RUN apt-get update && apt-get install -y \
    zip libzip-dev \
    && docker-php-ext-configure zip \
    && docker-php-ext-install zip

RUN docker-php-ext-install pdo_mysql bcmath

RUN chown -R www-data:www-data /var/www/html \
    && a2enmod rewrite

WORKDIR /var/www/html

PHPStorm, Composer and PHPUnit

PHPStorm works relatively flawlessly with WSL2, well it did and will again without a tweak after the 16th of January.

I store all my project files in WSL2, specifically Ubuntu, the project root for PHPStorm will normally be something like \\wsl$\Ubuntu\home\[user]\Projects\[project_name]. I have a Projects folder inside my home directory and a folder for each project. The Projects folder includes any phar files I might need so as not to duplicate them across projects.

The CLI Interpreter is set to my distro of choice, so in my case Ubuntu.

Composer settings are as defined as below.

  • Path to composer.json //wsl$/Ubuntu/home/[user]/Projects/[project_name]/composer.json
  • Execution, composer.phar
  • Composer.phar location \wsl$\Ubuntu\home\[user]\Projects\composer.phar

PHPUnit settings are defined as below

  • Remote Interpreter
  • Use composer autoloader
  • Path to script /home/[user]/Projects/[project_name]/vendor/autoload.php
  • Test runner default configuration file /home/[user]/Projects/[project_name]/phpunit.xml.dist

This Laravel project setup works well for all my projects as if I ever need to use a different version of PHP or MySQL I can update the dockerfiles for each service and rebuild. I recently needed to upgrade an App form PHP5.6 to 8.0, this setup made it easy to upgrade to each version of PHP and MySQL along the way and test at each step.

If I need to use Tailwind, SASS or other tools, I try to use them via WSL2 before going the Windows route.

After reading this you may wonder why I use Windows for development, there are three main reasons, one, I’m comfortable with Windows, two, I play games, three, I build my own PCs. The setup above will work regardless of your operating system of choice.

This post is part of a series on my development process. Please check out some of my other posts in this series, my git workflow and action class usage in my Laravel apps.