This is a SOC 2 compliant production infrastructure image. All changes go through a structured review process to maintain security controls and audit evidence.
All work happens on feature branches off main. Never commit directly to main.
git checkout main
git pull origin main
git checkout -b your-branch-nameUse descriptive branch names:
| Prefix | Purpose | Example |
|---|---|---|
feat/ |
New feature | feat/add-redis-extension |
fix/ |
Bug fix | fix/php-fpm-timeout |
security/ |
Security patch or hardening | security/update-owasp-crs |
docs/ |
Documentation only | docs/update-architecture |
Before writing code, understand what you're changing:
- Read docs/ARCHITECTURE.md for container architecture
- Read docs/SOC2-COMPLIANCE.md for security control mapping
- Check which SOC 2 controls your change may affect
Every change must pass the full test suite before opening a PR.
# Full lifecycle: build, start, test, clean up
just test-allIf you're iterating on a running container:
just build
just stop
just run
just testThe test suite validates:
| Test | What It Checks |
|---|---|
test-health |
Health check endpoint responds |
test-https-redirect |
HTTP redirects to HTTPS |
test-security-headers |
All security headers present |
test-ssl |
TLS 1.2+ enforced |
test-waf |
WAF blocks SQL injection |
test-blocked-paths |
Sensitive files return 403 |
test-php |
PHP 8.2 running, no dev tools |
test-services |
All services running |
test-permissions |
UID/GID mapping correct |
Push your branch and open a PR against main:
git push -u origin your-branch-nameYour PR must:
- Pass the CI pipeline (build, security tests, Trivy vulnerability scan)
- Receive at least one approval from a code owner
- Fill out the PR template, including the SOC 2 impact section
- Have no secrets, credentials, or debug code in the diff
PRs are squash-merged into main. The CI pipeline runs automatically on every push and PR.
- Pin specific versions for any new packages or dependencies
- Add tests for any new security controls
- Update documentation when changing architecture, configs, or security controls
- Keep the image minimal — every added package increases the attack surface
- Add development tools (
xdebug,php-dev,pcov, etc.) - Add privilege escalation tools (
sudo,gosu,su) - Disable or weaken WAF rules without a documented justification
- Lower TLS requirements below 1.2
- Remove security headers
- Commit
.envfiles, credentials, or secrets - Use
latesttags for pinned dependencies — always specify a version
Changes that affect security controls require extra scrutiny:
| File / Directory | SOC 2 Controls | Review Required |
|---|---|---|
Dockerfile |
CC6.1, CC8.1 | Always |
nginx/ |
CC6.1, CC6.6, CC6.7 | Always |
nginx/sites-enabled/ |
CC6.6, CC6.7 | Always |
wazuh/ |
CC7.1, CC7.2 | Always |
supervisord.conf |
CC7.1 | Always |
.github/workflows/ |
CC8.1 | Always |
php/ |
CC6.1 | When adding extensions |
docs/ |
CC8.1 | When controls change |
If your change modifies a SOC 2 control, update docs/SOC2-COMPLIANCE.md to reflect the change.
- Add the package to the
apt-get installblock in theDockerfile - Verify it is not a development-only package
- Run
just test-allto confirm the image builds and passes all tests - Update the PHP Extensions list in
README.md
Versions are pinned via ARG directives in the Dockerfile:
ARG OWASP_CRS_VERSION=4.4.0
ARG WAZUH_VERSION=4.9.0
ARG NODE_VERSION=20When updating a pinned version:
- Update the
ARGin theDockerfile - Run
just test-all - Update the version table in docs/SOC2-COMPLIANCE.md
- Note the version change in your PR description
Open a Feature Request or Bug Report if you're unsure about something.