Hi OpenEMR Dev Community,
I’ve been experimenting right here in openemr-frankenphp-docker, and I’d love to walk you through what’s inside the repo, why FrankenPHP+Caddy is worth a closer look, and how you can help test the approach.
What’s in this repository
-
openemr-source-code/: a vanilla OpenEMR tree plus one new entry point,frankenphp-worker.php(link here), used to preload key classes. -
openemr-devops-source-code/: the upstream devops stack copied verbatim so we can compare this FrankenPHP path against the “first” (Apache/PHP-FPM) Docker/Kubernetes assets without context switching. -
frankenphp_experiment/: the heart of the project, containing a purpose-built Dockerfile (docker/frankenphp/), Compose file (compose/docker-compose.yml), and the benchmarking toolkit (benchmarking/) with k6 scripts, run_benchmarks.sh, and captured results. -
README.md: documents how the experiment is wired together, the single-file code addition, and—most importantly—the initial performance deltas plus a step-by-step recipe to rebuild them.
Early results from this repo
The current measurements in README.md show some performance improvements versus the standard 7.0.4 Apache image although it should be noted that the benchmarking used to compare the two (basically just sending a bunch of requests at the login page) needs to be improved to truly give a proper comparison of the two.
| Metric | FrankenPHP | Apache 7.0.4 | Delta (%) |
|---|---|---|---|
| Avg latency (ms) | 84.99 | 110.74 | -23.3% |
| p95 latency (ms) | 211.90 | 347.11 | -39.0% |
| Requests/sec | 172.74 | 165.26 | +4.5% |
| Web tier CPU % | 0.00 | 4.15 | -100.0% |
| Web tier RSS (MiB) | 467.30 | 807.20 | -42.1% |
| MySQL CPU % | 0.01 | 0.26 | -96.2% |
| MySQL RSS (MiB) | 309.80 | 380.70 | -18.6% |
Static binaries and deployment impact
Because FrankenPHP supports static builds, the repo shows how we could ultimately ship OpenEMR in containers that look like:
FROM scratch
COPY openemr-frankenphp /
CMD ["/openemr-frankenphp"]
That unlocks:
- a much smaller CVE surface area
- faster pulls for autoscaling
- the ability to run OpenEMR on bare-metal or edge systems without Docker or really any other dependencies required—any environment that can execute a Linux binary becomes viable
Ways to get involved
-
Clone the repo, follow the six-step “How can I replicate these results?” section in README.md, and post your findings (including session handling, uploads, and portal workflows or anything else you find interesting).
-
Contribute better load-test scripts under frankenphp_experiment/benchmarking/ so we can stress more real-world paths.
-
Explore static builds: experiment with creating and running binaries from FrankenPHP and share what you learn.
-
Open issues/PRs for security hardening, preload tuning in frankenphp-worker.php, or Caddy best practices (TLS, audit logging, etc.).
Thanks for reading and for any feedback you can share. With community testing and collaboration, we can decide whether FrankenPHP becomes a first-class OpenEMR runtime alongside our traditional Apache/Nginx stacks—or even powers a future static-binary distribution.