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.

Budget Pro development begins again

The budget overview screen in Budget. Shows the this month and the two following months and the expenses for each

There was an initial flurry of development on Budget Pro in October/November and then it stalled. The stall was primarily down to lack of time as I started a freelance project in the November and needed to obviously dedicate time to that. However, whenever a free evening popped up, I chose not to work on Budget Pro and instead work on Budget or the freelance project to try and finish it sooner.

No sinister reason behind this and we still fully expect to release Budget Pro within the first half of 2023. The issue was simply that there were still things to learn from Budget, our free budgeting App.

Budget Open Beta

During the open beta, we learnt far more than we expected. We had to improve the demo, we needed to rework the Budget overview and there were several small features which we deemed necessary and didn’t finish adding until the end of the year.

In late November, I decided to delay any further development on Budget Pro until the official release of Budget; that way we would get to see and resolve all our problems in one codebase and not worry about having to rework anything in Budget Pro.

We always planned on there being two offerings of our budgeting tool – Budget, the free version and Budget Pro, our subscription option. In building Budget first, it has enabled us to identify and iron out potential issues before developing the much more complex version.

Our two Apps, Budget and Budget Pro solve the same problem, but they tackle it slightly differently. Budget is aimed at everyone; Budget Pro is aimed at users who need to collaborate or have much more complex budgets requirements.

Budget Pro is due out within the first half of 2023 and as soon as we are able, we will open it up for beta, the plan being we don’t make any of the same mistakes we did with the launch of Budget.