A professional, reusable, Docker-powered security and code quality platform designed for PHP and WordPress development workflows. This centralized security pipeline automatically performs static analysis, OWASP validation, vulnerability scanning, coding standard enforcement, taint analysis, and dependency auditing across multiple projects from a single shared environment.

Built for enterprise-grade development, the pipeline integrates powerful tools such as:

  • PHPStan
  • Psalm
  • PHPCS
  • WordPress Coding Standards
  • Composer Audit
  • SonarQube
  • OWASP ZAP
  • Git Hooks
  • Realtime File Watchers

The system enables developers and teams to automatically detect:

  • OWASP Top 10 vulnerabilities
  • SQL injection risks
  • XSS vulnerabilities
  • insecure input handling
  • coding standard violations
  • vulnerable dependencies
  • security hotspots
  • authentication and permission issues

Objective

Create a reusable Docker-based local security/security-scanning platform that can be used across:

  • WordPress plugins
  • WooCommerce extensions
  • PHP applications
  • React + PHP projects
  • REST APIs
  • Payment gateway integrations

This setup provides:

  • PHPCS
  • WordPress Coding Standards
  • PHPStan
  • Psalm + Taint Analysis
  • Composer Audit
  • SonarQube
  • OWASP ZAP
  • Git Hooks
  • Realtime File Watching
  • Dockerized architecture

This solution helps development teams implement secure coding practices early in the development lifecycle while maintaining high code quality, performance, and compliance standards across all local projects.

Final Architecture

security-pipeline/
│
├── docker-compose.yml
├── .env
├── README.md
│
├── php/
│   └── Dockerfile
│
├── scripts/
│   ├── install-project.sh
│   ├── security-check.sh
│   ├── watch-security.sh
│   ├── sonar-scan.sh
│   ├── zap-scan.sh
│   └── git-hook.sh
│
├── config/
│   ├── phpstan.neon
│   ├── phpcs.xml
│   ├── psalm.xml
│   └── sonar-project.properties
│
├── hooks/
│   └── pre-commit
│
└── projects/
    ├── project-1/
    ├── project-2/
    └── project-3/

STEP 1 — Create Base Folder

mkdir security-pipeline
cd security-pipeline

STEP 2 — Create Docker Compose

File

docker-compose.yml

Code

services:

  php-security:
    build:
      context: .
      dockerfile: php/Dockerfile

    container_name: php-security

    volumes:
      - ./projects:/var/www/projects
      - ./config:/security/config
      - ./scripts:/security/scripts
      - ./hooks:/security/hooks

    working_dir: /var/www/projects

    tty: true

  sonarqube:
    image: sonarqube:lts-community

    container_name: sonarqube

    ports:
      - "9000:9000"

    environment:
      SONAR_ES_BOOTSTRAP_CHECKS_DISABLE: "true"

    volumes:
      - sonarqube_data:/opt/sonarqube/data
      - sonarqube_logs:/opt/sonarqube/logs
      - sonarqube_extensions:/opt/sonarqube/extensions

volumes:
  sonarqube_data:
  sonarqube_logs:
  sonarqube_extensions:

STEP 3 — Create PHP Security Dockerfile

File

php/Dockerfile

Code

FROM php:8.3-cli

RUN apt-get update && apt-get install -y \
    git \
    unzip \
    curl \
    zip \
    wget \
    default-mysql-client \
    npm \
    nodejs

COPY --from=composer:latest /usr/bin/composer /usr/bin/composer

RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash -

RUN apt-get install -y nodejs

RUN npm install -g @wordpress/env

WORKDIR /var/www/projects

CMD ["bash"]

STEP 4 — Start Docker Containers

docker compose up -d

Check:

docker ps

STEP 5 — Enter Security Container

docker exec -it php-security bash

STEP 6 — Install Global Security Tools

Inside container:

composer global require \
squizlabs/php_codesniffer \
wp-coding-standards/wpcs \
phpstan/phpstan \
vimeo/psalm

STEP 7 — Configure PHPCS

/root/.config/composer/vendor/bin/phpcs --config-set installed_paths /root/.config/composer/vendor/wp-coding-standards/wpcs

echo 'export PATH="$PATH:/root/.config/composer/vendor/bin"' >> ~/.bashrc

source ~/.bashrc

Verify:

phpcs -i

Should show:

The installed coding standards are 
MySource
PEAR 
PSR1 
PSR2 
PSR12 
Squiz 
Zend 
WordPress
WordPress-Core 
WordPress-Docs
WordPress-Extra

STEP 8 — Create Shared PHPCS Config

File

config/phpcs.xml

Code

<?xml version="1.0"?>
<ruleset name="Project Rules">

    <description>Enterprise WordPress Security Rules</description>

    <rule ref="WordPress" />

    <exclude-pattern>vendor/*</exclude-pattern>
    <exclude-pattern>node_modules/*</exclude-pattern>

</ruleset>

STEP 9 — Create Shared PHPStan Config

File

config/phpstan.neon

Code

parameters:

    level: 7

    paths:
        - .

    excludePaths:
        - vendor
        - node_modules

STEP 10 — Create Shared Psalm Config

File

config/psalm.xml

Code

<?xml version="1.0"?>
<psalm
    errorLevel="3"
    resolveFromConfigFile="true"
>

    <projectFiles>
        <directory name="." />

        <ignoreFiles>
            <directory name="vendor" />
            <directory name="node_modules" />
        </ignoreFiles>
    </projectFiles>

    <plugins>
        <pluginClass class="Psalm\PhpUnitPlugin\Plugin" />
    </plugins>

</psalm>

STEP 11 — Create Shared Sonar Config

File

config/sonar-project.properties

Code

sonar.projectKey=php-security
sonar.projectName=PHP Security Pipeline
sonar.sources=.
sonar.host.url=http://sonarqube:9000

STEP 12 — Create Security Runner Script

File

scripts/security-check.sh

Code

#!/bin/bash

PROJECT_PATH=$1

if [ -z "$PROJECT_PATH" ]; then
  echo "Please provide project path"
  exit 1
fi

cd $PROJECT_PATH

echo "==================================="
echo "Running PHPCS"
echo "==================================="

~/.composer/vendor/bin/phpcs \
--standard=/security/config/phpcs.xml .

echo "==================================="
echo "Running PHPStan"
echo "==================================="

~/.composer/vendor/bin/phpstan analyse \
--configuration=/security/config/phpstan.neon

echo "==================================="
echo "Running Psalm"
echo "==================================="

~/.composer/vendor/bin/psalm \
--config=/security/config/psalm.xml

echo "==================================="
echo "Running Composer Audit"
echo "==================================="

composer audit

echo "==================================="
echo "Security Check Completed"
echo "==================================="

STEP 13 — Make Script Executable

chmod +x scripts/security-check.sh

STEP 14 — Create Sonar Scanner Script

File

scripts/sonar-scan.sh

Code

#!/bin/bash

PROJECT_PATH=$1

cd $PROJECT_PATH

sonar-scanner \
-Dsonar.projectBaseDir=$PROJECT_PATH \
-Dproject.settings=/security/config/sonar-project.properties

STEP 15 — Create OWASP ZAP Scan Script

File

scripts/zap-scan.sh

Code

#!/bin/bash

TARGET=$1

if [ -z "$TARGET" ]; then
  echo "Provide target URL"
  exit 1
fi

mkdir -p /tmp/zap-reports

docker run --rm \
  -v /tmp/zap-reports:/zap/wrk/:rw \
  ghcr.io/zaproxy/zaproxy:stable \
  zap-baseline.py \
  -t $TARGET \
  -r zap-report.html

STEP 16 — Create Realtime Watch Script

Install entr:

sudo apt install entr

File

scripts/watch-security.sh

Code

#!/bin/bash

PROJECT_PATH=$1

cd $PROJECT_PATH

find . -name "*.php" | entr /security/scripts/security-check.sh $PROJECT_PATH

STEP 17 — Git Pre-Commit Hook

File

hooks/pre-commit

Code

#!/bin/bash

/security/scripts/security-check.sh $(pwd)

if [ $? -ne 0 ]; then

  echo "==================================="
  echo "Security checks failed"
  echo "Commit blocked"
  echo "==================================="

  exit 1
fi

STEP 18 — Enable Git Hooks

Inside project:

docker cp php-security:/security/hooks/pre-commit .git/hooks/pre-commit

chmod +x .git/hooks/pre-commit

STEP 19 — Add a New Project

Example:

mkdir projects/my-plugin

Copy WordPress plugin code inside:

projects/my-plugin/

STEP 20 — Run Security Scan

docker exec -it php-security bash

Run:

/security/scripts/security-check.sh /var/www/projects/my-plugin

STEP 21 — Run Realtime Security Watcher

/security/scripts/watch-security.sh /var/www/projects/my-plugin

Now every file save automatically triggers:

  • PHPCS
  • PHPStan
  • Psalm
  • Composer Audit

STEP 22 — Run SonarQube Scan

Open:

http://localhost:9000

Default:

Username: admin
Password: admin

Run:

/security/scripts/sonar-scan.sh /var/www/projects/my-plugin

STEP 23 — Run OWASP ZAP Scan

Example:

/security/scripts/zap-scan.sh http://host.docker.internal:8080

Replace URL with:

  • WordPress local URL
  • Plugin demo URL
  • API URL

STEP 24 — Common Commands

Start containers

docker compose up -d

Stop containers

Stop containers

Enter container

Enter container

Run security scan

/security/scripts/security-check.sh /var/www/projects/my-plugin

Run watcher

/security/scripts/watch-security.sh /var/www/projects/my-plugin

Run SonarQube scan

/security/scripts/sonar-scan.sh /var/www/projects/my-plugin

Run ZAP scan

/security/scripts/zap-scan.sh http://host.docker.internal:8080

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *