Standard setup for PHP projects 2021
Table of Contents
The focus of this blog is to help set up PHP Projects in PhpStorm, in particular a Silverstripe project. I have also included snippets from my side-projects. I hope the information will be useful for other PHP projects.
This is a follow-up to my blog Standard Setup for PHP projects from
2020.
There have been several changes, to config files in particular, easy coding standard yml files to php files, which now allow code completion, amongst other benefits. Xdebug is now version 3, which has different configuration. I Have also being using Docker since July 2020, so have some useful docker containers, which include many of the standards I’m looking for.
Developer environments #
Windows #
On my works windows laptop I primarily use Laragon. I find it has a good set of development tools, including: PHP, MySQL, Apache, Node, Git, Composer, automatic host file updating, pretty urls, and many other good reasons.
Linux #
On my personal laptop I have a duel boot configuration. Windows has Laragon, Linux Pop_OS! Has Docker. When I upgraded my laptop, last year, I fitted additional RAM and an additional SSD, which I installed Pop_OS!. I never installed PHP, MySQL or Apache. I installed Docker instead. I mostly use the Laptop with Linux Pop_OS! I find its quicker, easy to use, and it uses less RAM.
Integrated Developer Environment (IDE) #
My go to Integrated Developer Environment (IDE), for the last two years is PhpStorm. The learning curve to get the best out of it, is well worth the effort. After all it is not only a code editor, but has Git, Database, terminal and debugging built in. The stand out tools are the code completion and refactoring.
I have many plugins, to many to name. Here are some I find particularly useful:
- Php Inspections (EA Extended), open-source Static Code Analyzer.
- Tabnine AI Autocomplete: JavaScript .. PHP , the free version offers two autocompletion options.
I make all my notes using Markdown and store them in Scratches, this is one of the most underrated features of PhpStorm, these notes are available across all my projects.
I still have VS Code as a backup, on Windows I also have Notepad++, if for some unusual reason I don’t have PhpStorm open and want to take a quick peek at a file then the lightweight and speed of Notepad++ is useful.
Composer #
Composer is the dependency manager for PHP. It also provides PSR-4 PHP autoloader.
Switching versions #
Composer is now in version 2, however some code bases will require version 1. To swap between the versions use the following commands:
- Switch to version 1:
composer self-update --1
- Switch to version 2:
composer self-update --2
Composer Docker image #
Composer has several images available on docker hub.
docker pull composer/composer
docker run --rm -it -v "$(pwd):/app" composer/composer -V
Composer version 2.0.14 2021-05-21 17:03:37
To add Composer to an existing Dockerfile:
COPY --from=composer/composer /usr/bin/composer /usr/bin/composer
Read the docker description for further information.
Example snippet fo a composer.json:
{
"name": "emilybache/yatzy-refactoring-kata",
"description": "Kata to practice refactoring",
"license": "MIT",
"require": {
"php": "^7.4|^8.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5",
"phpstan/phpstan": "^0.12.74",
"phpstan/phpstan-phpunit": "^0.12.17",
"symplify/easy-coding-standard": "^9.0",
"symplify/phpstan-extensions": "^9.0"
},
"autoload": {
"psr-4": {
"Yatzy\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Yatzy\\Tests\\": "tests/"
}
},
"scripts": {
"checkcode": "phpcs src tests --standard=PSR12",
"fixcode": "phpcbf src tests --standard=PSR12",
"test": "phpunit",
"tests": "phpunit",
"test-coverage": "phpunit --coverage-html build/coverage",
"check-cs": "ecs check --ansi",
"fix-cs": "ecs check --fix --ansi",
"phpstan": "phpstan analyse --ansi"
}
}
.editorconfig #
Example .editorconfig file. Normally found in the root of a project.
# For more information about the properties used in
# this file, please see the EditorConfig documentation:
# http://editorconfig.org/
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,json,ss}]
indent_size = 2
# The indent size used in the `package.json` file cannot be changed
# https://github.com/npm/npm/pull/3180#issuecomment-16336516
[composer.json]
indent_size = 4
[*.ss]
max_line_length = 999
The above is a good example of how file can have a global config, then more granular configs can be applied. PhpStorm will read the config and automatically apply the settings.
Xdebug #
Xdebug has been changed from version 2 to 3. It can be used to step-debug PHP scripts, report code coverage and now provides development aids. However, due to how it analyses the script it can make PHP slow! Xdebug’s set-debugging and code coverage should only be enabled when they are required.
Follow the installation instructions and add the following to your php.ini:
[Xdebug]
; zend_extension=/wherever/you/put/it/xdebug
; e.g.
; Windows using Laragon:
zend_extension = C:\laragon\bin\php\php-7.4.4-Win32-vc15-x64\ext\php_xdebug-3.0.4-7.4-vc15-x86_64.dll
; Linux with PHP 8:
; zend_extension = /usr/lib/php8/modules/xdebug.so
xdebug.mode = coverage,debug,develop
; Linux: change 'pop-os' to your host name
xdebug.client_host = pop-os
; windows and mac:
; xdebug.client_host=localhost
xdebug.client_port = 9003
xdebug.start_with_request = yes
Xdebug with Docker #
PHP docker containers can have Xdebug installed as follows:
# Buster (FROM brettt89/silverstripe-web:7.4-apache):
RUN install-php-extensions xdebug
# Alpine (FROM php:8.0-cli-alpine3.13):
RUN apk add --no-cache php8-pecl-xdebug \
&& docker-php-ext-enable /usr/lib/php8/modules/xdebug.so
The extension can be enabled using environment variables:
ENV XDEBUG_CONFIG="client_host=pop-os" \
# windows & mac:
# XDEBUG_CONFIG= "client_host=host.docker.internal"
XDEBUG_MODE="develop"
# XDEBUG_MODE="coverage,debug,develop"
Alternatively, the extension can be enabled using environment variables:
docker-compose.yml
version: "3.3"
services:
silverstripe:
image: brettt89/silverstripe-web:7.4-apache
ports:
- "80:80"
volumes:
- .:/var/www/html
depends_on:
- database
environment:
- DOCUMENT_ROOT=/var/www/html/public
- SS_TRUSTED_PROXY_IPS=*
- SS_ENVIRONMENT_TYPE=dev
- SS_DATABASE_SERVER=database
- SS_DATABASE_NAME=SS_mysite
- SS_DATABASE_USERNAME=root
- SS_DATABASE_PASSWORD=
- SS_DEFAULT_ADMIN_USERNAME=admin
- SS_DEFAULT_ADMIN_PASSWORD=password
- XDEBUG_CONFIG="client_host=pop-os"
- XDEBUG_MODE="develop"
# database...
Setup PhpStorm #
PhpStorm is my IDE of choice for PHP development. Here are some tips for configuring it per project.
Configuring Xdebug #
TL;DR (parts copied from PhpStorm Tutorials, link to the full version below)
In the Settings/Preferences dialog Ctrl+Alt+S, select Languages & Frameworks | PHP.
Check the Xdebug installation associated with the selected PHP interpreter:
a. On the PHP page, choose the relevant PHP installation from the CLI Interpreter list and click the Browse button next to the field.
b. The CLI Interpreters dialog that opens shows the following:
i. The version of the selected PHP installation. (e.g. C:\laragon\bin\php\php-7.4.4-Win32-vc15-x64\php.exe)
ii. The name and version of the debugging engine associated with the selected PHP installation (Xdebug). (e.g. C: \laragon\bin\php\php-7.4.4-Win32-vc15-x64\ext\php_xdebug.dll)
iii Once set click OK.
Define the Xdebug behaviour. Click Debug under the PHP node (Languages & Frameworks | PHP | Debug.). On the Debug page that opens, specify the following settings in the Xdebug area:
- Check the Pre-configuration has been complete (Xdebug ins installed, Install browser toolbar, Enable listening for PHP Debug connections and Start debug session)
- Under the XDebug heading, Choose the Debug Port field (default is 9000,9003). This must be exactly the same port number specified in the php.ini file: xdebug.remote_port =9003
- To accept any incoming connections, select the Can accept external connections checkbox. (Default)
- Select the Force break at the first line when no path mapping is specified checkbox to have the debugger stop as soon as it reaches and opens a file that is not mapped to any file in the project on the Servers page. (Default)
- Click OK
Using debug mode #
Set a breakpoint in the file to be inspected.
Open your php file, e.g. public/index.php, wait for the file to open, then in to top right there will be a floating bar with a list of browsers. Click Chrome (Alt+F2 + Choose Chrome)
Chrome browser will launch and open the projects webpage. If the Debug icon isn’t already green, click the Debug icon for Xdebug helper extension. From the drop down list click Debug option, the icon will then display green.
Navigate the project’s website, to the page which uses the file that has the breakpoint set. As soon as the page is hit PhpStorm will open (it may be behind the browser).
In PhpStorm, accept the connection (this warning normally only displays the first hit and accepted once).
Debug information will display in the console, including the option to inspect variables and evaluate.
Further details: How to Debug #
For the full version of the above see:
- Configuring Xdebug in PhpStorm
- Browser Debugging Extensions, click the link for Xdebug for Chrome and install Xdebug Helper.
- Youtube: Step Into Debugging with PhpStorm by Gary Hockin, 58 min video on Debugging with Xdebug 2.
Strict mode #
PHPStorm has an inspection to set strict mode.
TL&DR;
Strict types declaration setting can be found under Type compatibility in the Inspections pane of the ** Preferences** window.
Or double shift search for Missing Strict types declaration tick the inspection.
To run the inspection against whole project (code base): CTRL + ALT + SHIFT + I or double shift search for run inspection by name. Search for missing strict type declaration, Enter for whole project. The inspection will run, click on each file and click Add strict types declaration
Easy Coding Standard (ECS) #
The easiest way to start using PHP CS Fixer and PHP_CodeSniffer with 0-knowledge
Github: symplify/easy-coding-standard
ECS is my goto coding standard tool, it includes PHP CS Fixer and PHP_CodeSniffer, meaning I can use existing standards. I use it on every project!
Install ECS using Composer #
composer require --dev symplify/easy-coding-standard
Docker image with ECS #
My favourite Docker PHP tool, packed with useful tools, including ECS is Docker hub jakzal/phpqa
docker pull jakzal/phpqa:php7.4-alpine
docker run -it --rm -v "$(pwd):/project" -v "$(pwd)/tmp-phpqa:/tmp" \
-w /project jakzal/phpqa:php7.4-alpine ecs --version
Example ecs.php
file #
Note: ECS has changed from a yml file to a php file, which allows code completion, amongst other things.
ecs.php
<?php
declare(strict_types=1);
use PhpCsFixer\Fixer\ArrayNotation\ArraySyntaxFixer;
use PhpCsFixer\Fixer\Operator\BinaryOperatorSpacesFixer;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symplify\EasyCodingStandard\ValueObject\Option;
use Symplify\EasyCodingStandard\ValueObject\Set\SetList;
return static function (ContainerConfigurator $containerConfigurator): void {
$services = $containerConfigurator->services();
$services->set(ArraySyntaxFixer::class)
->call('configure', [[
'syntax' => 'short',
]]);
// align key value pairs (mostly)
$services->set(BinaryOperatorSpacesFixer::class)
->call('configure', [[
// Likely problems are pipe operators
// if this is a problem change 'default' => 'single'
// and uncomment this lines:
// 'operators' => [
// '|' => 'none',
// '=>' => 'align_single_space_minimal'
// ],
'default' =>'align_single_space_minimal',
]]);
// add declare(strict_types=1); to all php files:
$services->set(DeclareStrictTypesFixer::class);
$parameters = $containerConfigurator->parameters();
$parameters->set(Option::PATHS, [
__DIR__ . '/src',
__DIR__ . '/tests',
]);
$parameters->set(Option::SETS, [
// run and fix, one by one
SetList::SPACES,
// SetList::ARRAY,
// SetList::DOCBLOCK,
// SetList::NAMESPACES,
// SetList::CONTROL_STRUCTURES,
// SetList::CLEAN_CODE,
// SetList::STRICT,
// SetList::PSR_12,
// SetList::PHPUNIT,
]);
$parameters->set(Option::INDENTATION, "spaces");
$parameters->set(Option::LINE_ENDING, "\n");
};
Example projects with ECS included #
I always find it useful to look at existing projects with working code, see some examples from GitHub:
- Personal project:
- Kata:
- LMC:
- lmc eu/php coding standard - heavily commented!
Run ECS #
vendor/bin/ecs check
vendor/bin/ecs check --fix
If composer.json has been configured with scripts, as above:
composer check-cs
composer fix-cs
Alias:
alias cc="composer check-cs"
alias fc="composer fix-cs"
- Mac and Linux: add the alias to ~/.bash_aliases.
- Windows: create files cc.bat and fc.bat and add the composer calls.
Then run with cc and fc!
PHPStan #
PHPStan focuses on finding errors in your code without actually running it. It catches whole classes of bugs even before you write tests for the code. It moves PHP closer to compiled languages in the sense that the correctness of each line of the code can be checked before you run the actual line.
- Github: phpstan/phpstan
Install PHPStan using Composer #
composer require phpstan/phpstan --dev
# phpunit analysis:
composer require phpstan/phpstan-phpunit --dev
# additional extensions:
composer require symplify/phpstan-extensions --dev
Docker image with PHPStan #
My favourite Docker PHP tool, packed with useful tools, including PHPStan is Docker hub jakzal/phpqa
docker pull jakzal/phpqa:php7.4-alpine
docker run -it --rm -v "$(pwd):/project" -v "$(pwd)/tmp-phpqa:/tmp" \
-w /project jakzal/phpqa:php7.4-alpine phpstan --version
One of the benefits of using the docker image is PHPStan doesn’t need to be installed as a dev dependency. Less to install and no dependency clashes!
Example phpstan.neon
file #
PHPStan expects a phpstan.neon file in the root of the project.
phpstan.neon
includes:
- vendor/symplify/phpstan-extensions/config/config.neon
- vendor/phpstan/phpstan-phpunit/extension.neon
parameters:
paths:
- src
- tests
# The level 8 is the highest level
level: 8
# Larstan recommendation:
checkMissingIterableValueType: false
# Ignore generic class Ds\Map
checkGenericClassInNonGenericObjectType: false
ignoreErrors:
# Magic method is used is simulate enum
- '#Call to an undefined static method#'
- message: '#PHPDoc tag @method has invalid value#'
paths:
- src\Model\SpecialOfferType.php
- src\Model\ProductUnit.php
# buggy
# mixed
# cache buggy
# tests
# iterable
The above includes placeholders (buggy/mixed etc) for ignored files or rules. See the documentation for how to add.
Example projects with PHPStan included #
I always find it useful to look at existing projects with working code, see some examples from GitHub:
- Personal project:
- Kata:
- Others:
Run PHPStan #
vendor/bin/phpstan analyse --error-format symplify
If composer.json has been configured with scripts, as above:
composer phpstan
Alias:
alias ps="composer phpstan"
- Mac and Linux: add the alias to ~/.bash_aliases.
- Windows: create files ps.bat and add the composer calls.
Then run with ps
!
PHPUnit #
PHPUnit is a programmer-oriented testing framework for PHP. It is an instance of the xUnit architecture for unit testing frameworks.
Installation of PHPUnit using Composer #
composer require --dev phpunit/phpunit ^9.5
Docker image with PHPUnit #
My favourite Docker PHP tool, packed with useful tools, including several versions of PHPUnit is Docker hub jakzal/phpqa
docker pull jakzal/phpqa:php7.4-alpine
docker run -it --rm -v "$(pwd):/project" -v "$(pwd)/tmp-phpqa:/tmp" \
-w /project jakzal/phpqa:php7.4-alpine phpunit --version
One of the benefits of using the docker image is less dev dependencies.
Example phpunit.xml
or phpunit.xml.dist
file #
Example phpunit.xml from emilybache/Theatrical-Players-Refactoring-Kata .
phpunit.xml
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
bootstrap="vendor/autoload.php"
colors="true">
<coverage processUncoveredFiles="true">
<include>
<directory suffix=".php">./src</directory>
</include>
</coverage>
<testsuites>
<testsuite name="AllTests">
<directory>./tests</directory>
</testsuite>
</testsuites>
</phpunit>
- Add
/build/
to .gitignore
echo /build/ >> .gitignore
Example projects with PHPUnit included #
I always find it useful to look at existing projects with working code, see some examples from GitHub:
- Personal project:
- Kata:
- Others:
- lmc eu/php coding standard
- laravel/cashier-mollie - includes how to run with SQLite in memory database
Run PHPUnit #
vendor/bin/phpunit
If composer.json has been configured with scripts, as above:
composer phpunit
Alias:
alias pu="composer phpunit"
- Mac and Linux: add the alias to ~/.bash_aliases.
- Windows: create files pu.bat and add the composer calls.
Then run with pu
!
Docker #
I wrote at the start, Docker is my only development environment on my Linux Pop_OS! Laptop. This layer of complexity is sometimes frustrating. Especially when Laragon makes my Windows development environment so easy. I have persisted, primarily to challenge myself to learn Docker.
Dockerfile #
There are many flavours of Dockerfiles, the smallest, most lightweight are generally Alpine images. Here are some ** Dockerfiles** I have curated.
PHP 8 Alpine CLI with xdebug and intl #
Dockerfile for PHP 8 Alpine with xdebug and intl, useful for Kata. See Yatzy Refactoring Kata php
Dockerfile
FROM php:8.0-cli-alpine3.13
# user, uid and gid are the same as my Linix. This has no effect on windows
ARG USER=michael
ARG UID=1000
ARG GID=1000
# 'pop-os' is my Linux host name, on your Linux change to your host name! On Windows and Mac change to:
# xdebug.client_host=host.docker.internal
ENV xdebug.mode=coverage,debug,develop \
xdebug.client_host=pop-os \
xdebug.client_port=9003 \
xdebug.start_with_request=yes
# create a system user with home folder, uid:gid 1000:1000, no password called michael
RUN addgroup -g $GID $USER \
&& adduser \
--system \
--disabled-password \
--gecos "" \
--home "/home/$USER" \
--ingroup "$USER" \
--no-create-home \
--uid "$UID" \
"$USER"
RUN apk add --no-cache php8-pecl-xdebug php8-intl \
&& docker-php-ext-enable /usr/lib/php8/modules/xdebug.so /usr/lib/php8/modules/intl.so
# smoke test
RUN php -v \
&& php -m
WORKDIR /app
docker build -t php8-cli-alpine:local .
docker run -it --rm -v $(pwd):/app -u 1000:1000 -w /app php8-cli-alpine:local /bin/sh
- PhpStorm: Add php8-cli-alpine:local as the CLI Interpreter
- Configure tests to use this as the PHP Interpreter.
PHP 7.4 Alpine with Apache, PDO and intl #
Used on PHP AJAX CRUD using jQuery UI Demo, see the repo for the docker-compose, which includes MySQL 5.7.0. Note the start.sh file is also needed to run!
Dockerfile
FROM alpine:edge
MAINTAINER Paul Smith <pa.ulsmith.net>
# Original docker iamge source: https://github.com/ulsmith/alpine-apache-php7
# Add repos
RUN echo "http://dl-cdn.alpinelinux.org/alpine/edge/testing" >> /etc/apk/repositories
# Add basics first
RUN apk update && apk upgrade && apk add \
bash apache2 php7-apache2 curl ca-certificates openssl openssh git php7 php7-phar php7-json php7-iconv php7-openssl tzdata openntpd nano
# Add Composer
RUN curl -sS https://getcomposer.org/installer | php && mv composer.phar /usr/local/bin/composer
# Setup apache and php
RUN apk add \
php7-ftp \
php7-xdebug \
php7-mcrypt \
php7-mbstring \
php7-soap \
php7-gmp \
php7-pdo_odbc \
php7-dom \
php7-pdo \
php7-zip \
php7-mysqli \
php7-sqlite3 \
php7-pdo_pgsql \
php7-bcmath \
php7-gd \
php7-odbc \
php7-pdo_mysql \
php7-pdo_sqlite \
php7-gettext \
php7-xml \
php7-xmlreader \
php7-xmlwriter \
php7-tokenizer \
php7-xmlrpc \
php7-bz2 \
php7-pdo_dblib \
php7-curl \
php7-ctype \
php7-session \
php7-redis \
php7-exif \
php7-intl \
php7-fileinfo \
php7-ldap \
php7-apcu
# Problems installing in above stack
RUN apk add php7-simplexml
RUN cp /usr/bin/php7 /usr/bin/php \
&& rm -f /var/cache/apk/*
# Add apache to run and configure
RUN sed -i "s/#LoadModule\ rewrite_module/LoadModule\ rewrite_module/" /etc/apache2/httpd.conf \
&& sed -i "s/#LoadModule\ session_module/LoadModule\ session_module/" /etc/apache2/httpd.conf \
&& sed -i "s/#LoadModule\ session_cookie_module/LoadModule\ session_cookie_module/" /etc/apache2/httpd.conf \
&& sed -i "s/#LoadModule\ session_crypto_module/LoadModule\ session_crypto_module/" /etc/apache2/httpd.conf \
&& sed -i "s/#LoadModule\ deflate_module/LoadModule\ deflate_module/" /etc/apache2/httpd.conf \
&& sed -i "s#^DocumentRoot \".*#DocumentRoot \"/app/public\"#g" /etc/apache2/httpd.conf \
&& sed -i "s#/var/www/localhost/htdocs#/app/public#" /etc/apache2/httpd.conf \
&& printf "\n<Directory \"/app/public\">\n\tAllowOverride All\n</Directory>\n" >> /etc/apache2/httpd.conf
RUN mkdir /app && mkdir /app/public && chown -R apache:apache /app && chmod -R 755 /app && mkdir bootstrap
ADD start.sh /bootstrap/
RUN chmod +x /bootstrap/start.sh
ADD /public /app/public
RUN chown -R apache:apache /app
WORKDIR /app
EXPOSE 80
ENTRYPOINT ["/bootstrap/start.sh"]
docker-compose.yml #
To get the most out of a development environment. It should be easy to “spin up”, docker-compose files take the lengthy Docker run commands, The lay them out into easy to read files, which are easy to edit.
Example from Pen-y-Fan / php-ajax-crud-using-jquery-ui-demo
You can see two Apache servers, sharing the same database. One has XDebug enabled, which makes it slow, but easy to run step debugging. I only need to switch from localhost:8080 to localhost:8081 to start debugging.
docker-compose.yml
version: "3"
services:
ajaxcrud:
image: apachephp:local
# build: ./
labels:
- "traefik.backend=ajaxcrud"
# - "traefik.frontend.rule=Host:ajaxcrud.docker.localhost"
environment:
- MYSQL_HOST=database
- APACHE_SERVER_NAME=ajaxcrud.docker.localhost
- PHP_SHORT_OPEN_TAG=On
- PHP_ERROR_REPORTING=E_ALL
- PHP_DISPLAY_ERRORS=On
- PHP_HTML_ERRORS=On
# Xdebug is disabled use ajaxcrudx for debugging
networks:
- default
ports:
- "8080:80"
volumes:
- ./:/app
- ./tmp-phpqa:/tmp
working_dir: /app
depends_on:
- database
# ADD in permission for setting system time to host system time
cap_add:
- SYS_TIME
- SYS_NICE
# Enable Xdebug and use port 8081
ajaxcrudx:
image: apachephp:local
labels:
- "traefik.backend=ajaxcrudx"
# - "traefik.frontend.rule=Host:ajaxcrud.docker.localhost"
environment:
- MYSQL_HOST=database
- APACHE_SERVER_NAME=ajaxcrudx.docker.localhost
- PHP_SHORT_OPEN_TAG=On
- PHP_ERROR_REPORTING=E_ALL
- PHP_DISPLAY_ERRORS=On
- PHP_HTML_ERRORS=On
- PHP_XDEBUG_ENABLED=On
networks:
- default
ports:
- "8081:80"
volumes:
- ./:/app
- ./tmp-phpqa:/tmp
working_dir: /app
depends_on:
- database
# ADD in permission for setting system time to host system time
cap_add:
- SYS_TIME
- SYS_NICE
database:
image: mysql:5.7
ports:
- "33060:3306"
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
volumes:
- db-data:/var/lib/mysql
volumes:
db-data:
#networks:
# default:
# external:
# name: docker_docker-localhost
Makefile #
Makefile allow a consistent and easy way for me to “spin up” the different environments. It doesn’t matter if it is
a LAMP stack or Node, I can run make up
to start things off.
Example used on PHP AJAX CRUD using jQuery UI Demo
Usage:
- build-image - build the local image ready for docker-compose
- make up - starts the docker-compose in the same directory in demon (background)
- make down - stops the docker-compose
- make seed - Create the table and seed the database with three records
- make shell - opens a sh terminal in the running ajaxcrud container as a standard user
- make shell-root - opens a sh in ajaxcrud container as root user
- make shell-web - opens a sh in ajaxcrud container as www user
- make up-f - start the docker-compose in foreground (useful for error messages)
- make tests - run phpunit tests
- make test-coverage - phpunit coverage html report will be created in build/coverage
- make phpstan - static analysis using phpstan
- make checkcode - check code using php_code sniffer (phpcbf)
- make fixcode - fix code using php_code sniffer (phpcbf)
- make check-cs - check code using easy coding standards (ecs)
- make fix-cs - fix code using easy coding standards (ecs)
- grumphp - manually run grumphp (runs: phpunit, ecs and phpstan)
- toolbox - shell access to the toolbox
- cypress-register - register Cypress with xhost to allow Docker to display GUI app on the host’s monitor
- cypress - run Cypress end to end testing
Makefile
# Duster: www-data:www-data is 33:33
# Alpine: apache:apache is 100:101
APACHE_UID = 100
APACHE_GID = 101
build-image:
docker build -t apachephp:local .
up:
docker-compose up --remove-orphans -d
up-f:
docker-compose up --remove-orphans
down:
docker-compose down --remove-orphans
seed:
docker-compose exec -u ${APACHE_UID}:${APACHE_GID} ajaxcrud php /app/build_db.php
shell:
docker-compose exec -u ${shell id -u}:${shell id -g} ajaxcrud sh
shell-root:
docker-compose exec -u 0:0 ajaxcrud sh
shell-web:
docker-compose exec -u ${APACHE_UID}:${APACHE_GID} ajaxcrud sh
chown:
docker-compose exec -u 0:0 ajaxcrud chown -R ${shell id -u}:${shell id -g} ./
.PHONY : tests
tests:
docker-compose exec -u ${shell id -u}:${shell id -g} ajaxcrud ./vendor/bin/phpunit
test-coverage:
docker-compose exec -u ${shell id -u}:${shell id -g} \
ajaxcrudx ./vendor/bin/phpunit --coverage-html build/coverage
phpstan:
docker run --init -it --rm -w /project \
-v $(shell pwd):/project \
-v $(shell pwd)/tmp-phpqa:/tmp \
jakzal/phpqa:1.52-php7.4-alpine phpstan analyse
checkcode:
docker run --init -it --rm -w /project \
-v $(shell pwd):/project \
-v $(shell pwd)/tmp-phpqa:/tmp \
jakzal/phpqa:1.52-php7.4-alpine phpcs public tests src --standard=phpcs.xml
fixcode:
docker run --init -it --rm -w /project \
-v $(shell pwd):/project \
-v $(shell pwd)/tmp-phpqa:/tmp \
jakzal/phpqa:1.52-php7.4-alpine phpcbf public tests src --standard=phpcs.xml
check-cs:
docker run --init -it --rm -w /project \
-v $(shell pwd):/project \
-v $(shell pwd)/tmp-phpqa:/tmp \
jakzal/phpqa:1.52-php7.4-alpine ecs check
fix-cs:
docker run --init -it --rm -w /project \
-v $(shell pwd):/project \
-v $(shell pwd)/tmp-phpqa:/tmp \
jakzal/phpqa:1.52-php7.4-alpine ecs check --fix
grumphp:
docker run --init -it --rm -w /project \
-v $(shell pwd):/project \
-v $(shell pwd)/tmp-phpqa:/tmp \
jakzal/phpqa:1.52-php7.4-alpine ./vendor/bin/grumphp run
toolbox:
docker run --init -it --rm -w /project \
-v $(shell pwd):/project \
-v $(shell pwd)/tmp-phpqa:/tmp \
jakzal/phpqa:1.52-php7.4-alpine sh
cypress-register:
xhost +local:`docker inspect --format='{{ .ContainerConfig.Hostname }}' cypress/included:6.6.0`
.PHONY : cypress
cypress:
docker run -it --rm -d -e DISPLAY \
-v $(shell pwd):/e2e \
-v /tmp/.X11-unix:/tmp/.X11-unix --net=host -w /e2e \
--entrypoint cypress cypress/included:6.6.0 open --project .
cypress-run:
docker run -it --rm -w /e2e \
-v $(shell pwd):/e2e \
cypress/included:6.6.0
Conclusion #
I hope you find this curated list useful, I hope to continue my development and update a new list next year!