/dockerized-php

A lightweight PHP development environment supporting self signed local domains with Caddy

Primary LanguageMakefileMIT LicenseMIT

Integration Tests

Dockerized PHP

A dockerized lightweight PHP development environment supporting self signed local domains powered by Caddy

[TOC]

Summary

This repository allows you to create containerized PHP applications and/or microservices using Docker and Caddy.

The Docker image is based on php:8.2.12-fpm-alpine3.18 in order to keep bade image as much lightweight as possible.

Highlights

  • Lightweight: main service Docker image only requires 89.8MB.
  • Self-signed local domains thanks to Caddy.
  • Unified environment to build CLI and/or web applications with PHP8.
  • Code Coverage, PHPUnit, Paratest, PHPInsights, PHPStan and Linters by default.

Requirements

To use this repository you need:

  • Docker - An open source containerization platform.
  • Git - The free and open source distributed version control system.

Built with

Type Component Description
Infrastructure Docker Containerization platform
Service Caddy Server Open source web server with automatic HTTPS written in Go
Service PHP-FPM PHP with FastCGI Process Manager
Miscelaneous Bash Allows to create an interactive shell within main service
Miscelaneous Make Allows to execute commands defined on a Makefile
Quality Assurance PCOV Allows to generate a CodeCoverage report for PHP apps
Quality Assurance PHP-Insights Allows to analyze the code quality of your PHP projects
Quality Assurance PHP-Parallel-Lint Allows to check the syntax of PHP files in parallel
Quality Assurance PHPStan Allows to perform static analysis of your application looking for issues
Testing Infection PHP Mutation Testing Framework
Testing PHPUnit PHP Testing Framework
Testing Paratest Allows to run your PHPUnit test suite in parallel
Testing UOPZ Allows to mock internal date/time functions on your tests
Testing BypassFinals Hook Allows to mock PHP final classes

Getting Started

Just clone the repository into your preferred path:

$ mkdir -p ~/path/to/my-new-project && cd ~/path/to/my-new-project
$ git clone git@github.com:fonil/dockerized-php.git .

Conventions

Build Arguments

To avoid conflicts with ownership and/or file permission from those files internally created by the container service, a non-root user is created into the service with the same ID and group name than the current host user, and forcing the service to be executed with this user and group when creating files.

Those details are in the docker-compose.yml file and contains the following arguments.

Argument How to fill the value Description
CURRENT_UNAME $ id --user --name Current host user name
CURRENT_GNAME $ id --group --name Current host group name
CURRENT_UID $ id --user Current host user ID
CURRENT_GID $ id --group Current host user group ID

Defining those values here allows you to execute docker compose and/or the Makefile commands (make build, make up...) with 100% compatibility.

I recommend you to use your current user name/group to avoid conflicts when executing commands that creates files inside the container (for example make composer install, etc.)

Application

Your application must be placed into src folder.

Default website domain

The default website domain is https://website.demo

Customizing the default domain

If you want to customize the default website domain please:

  • Update build/etc/caddy/Caddyfile accordingly
  • Update the Makefile in where a constant is defined with current domain name.

Directory structure

Folder Description
build The build directory contains config files required by PHP-FPM, Caddy...
build/etc/caddy The build/etc/caddy directory contains required Caddy's config file (Caddyfile).
build/usr/local/etc/php-fpm.d The build/usr/local/etc/php-fpm.d directory contains required PHP-FPM config file (www.conf).
build/shared/healthchecks The build/shared/healthchecks directory contains the PHP-FPM healthcheck file (php-fpm.sh).
src The src directory contains the source code of your application.
src/app The app directory contains your business logic.1
src/public The public directory contains the index.php file which bootstraps the application.
src/tests The tests directory contains your automated tests.
src/vendor The vendor directory contains your Composer dependencies.
output The output directory contains any file internally generated from the container service.

If you take a look to docker-compose.yml#L13 this folder is mounted as a volume into the application container.

With this setup you are able to modify the source code of your application, within your preferred IDE, on your host and automatically have those changes in the container ๐Ÿ˜ƒ

Logging

The application logs to STDOUT by default.

Mocking Date/Time functions

To allow testing with date and/or time variations, slope-it/clock-mock is added as dependency into src/composer.json.

This library provides a way for mocking the current timestamp used by PHP for \DateTime(Immutable) objects and date/time related functions.

It requires the uopz extension, that is why Dockerfile references to it.

Default Application

Default application just print outs Class [ App\Providers\Foo ] from Foo final class placed at src/app/Providers.

Default unit test just verifies the instance returns.

This default application has being created as a skeleton and it should be replaced by your business logic.

Available commands

A Makefile is provided with some predefined commands:

~/path/to/my-new-project$ make

โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•—
โ•‘                                                                              โ•‘
โ•‘                           .: AVAILABLE COMMANDS :.                           โ•‘
โ•‘                                                                              โ•‘
โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•

ยท show-context                   Setup: show context
ยท update-hosts-file              Setup: adds the website domain to /etc/hosts file
ยท build                          Docker: builds the service
ยท down                           Docker: stops the service
ยท up                             Docker: starts the service
ยท up-caddy                       Docker: starts the service + Caddy webserver
ยท logs                           Docker: exposes the service logs
ยท restart                        Docker: restarts the service
ยท bash                           Docker: stablish a bash session into main container
ยท composer-dump                  Composer: runs <composer dump-auto>
ยท composer-install               Composer: runs <composer install>
ยท composer-remove                Composer: runs <composer remove>
ยท composer-require-dev           Composer: runs <composer require --dev>
ยท composer-require               Composer: runs <composer require>
ยท composer-update                Composer: runs <composer update>
ยท linter                         Application: runs the PHP Linter in parallel mode
ยท phpcs                          Application: runs the PHPCodeSniffer to fix possible issues
ยท phpcbf                         Application: runs the PHPCodeBeautifier to fix possible issues
ยท phpinsights                    Application: runs the PHPInsights to fix possible issues
ยท infection                      Application: runs the Infection test suite
ยท paratest                       Application: runs the PHPUnit test suite in parallel mode
ยท phpunit                        Application: runs the PHPUnit test suite
ยท phpstan                        Application: runs PHPStan
ยท tests                          Application: runs ParaTest + Infection
ยท version                        Application: displays the PHP Version
ยท info                           Application: displays the php.init details
ยท run                            Application: Application: starts the services & installs dependencies & check host file
ยท install-caddy-certificate      Caddy: installs Caddy Local Authority certificate

Build the service

~/path/to/my-new-project$ make build

Run the service

~/path/to/my-new-project$ make run
Certificate Authority (CA) & SSL Certificate

Caddy uses HTTPS by default. In order to avoid SSL certificates issues you must install the Caddy Authority Certificate on your browser. This is a one-time action due the certificate does not change after rebuilding/restarting the service.

A Makefile command called make install-caddy-certificate is provided and copies the Caddy root certificate from the Caddy container service into current application path, and displays the steps you need to follow to install this certificate in your browser.

Stop the service

~/path/to/my-new-project$ make down

Dealing with Code Quality

~/path/to/my-new-project$ make linter
~/path/to/my-new-project$ make phpinsights
~/path/to/my-new-project$ make phpstan

Dealing with Tests

~/path/to/my-new-project$ make phpunit

This command executes PHPUnit

~/path/to/my-new-project$ make paratest

This command executes PHPUnit in parallel mode

~/path/to/my-new-project$ make infection

This command executes the mutation testing tool

Reports

PHPUnit/Paratest/Infection are configured to store the PHP Code Coverage report into output/coverage

Logs

Infection is configured to store the logs into output/logs/infection

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities:

PLEASE DON'T DISCLOSE SECURITY-RELATED ISSUES PUBLICLY

Supported Versions

Only the latest major version receives security fixes.

Reporting a Vulnerability

If you discover a security vulnerability within this project, please open an issue here. All security vulnerabilities will be promptly addressed.

License

The MIT License (MIT). Please see LICENSE file for more information.

Footnotes

  1. Any class of file located under app directory will be loaded with App namespace by Composer using the PSR-4 autoloading standard โ†ฉ