Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
149 commits
Select commit Hold shift + click to select a range
40fb22a
Removed comma trimming from package install
jaydrogers Feb 7, 2024
fde0dff
Moved Matrix job generation to a dedicated script
jaydrogers Feb 8, 2024
6e9f0d6
Added first draft of FrankenPHP
jaydrogers Feb 8, 2024
137daa9
Add BUILDKIT_PROGRESS environment variable
jaydrogers Feb 8, 2024
cf876a3
Fix typo in script name
jaydrogers Feb 8, 2024
4c5bd04
Changed name to development images
jaydrogers Feb 8, 2024
ac18d72
Working local PHP
jaydrogers Feb 9, 2024
9a64385
Working entrypoint
jaydrogers Feb 9, 2024
c86f1d1
Merge branch 'main' into 280-create-a-frankenphp-variation
jaydrogers Apr 3, 2024
5e55811
Added OPcache settings
jaydrogers Apr 3, 2024
799b6a6
Merge branch 'main' into 280-create-a-frankenphp-variation
jaydrogers Apr 4, 2024
1cc15aa
Merge branch 'main' into 280-create-a-frankenphp-variation
jaydrogers Apr 4, 2024
8f7b15b
Merge branch 'main' into 280-create-a-frankenphp-variation
jaydrogers May 13, 2024
1efb583
chore: Add SHOW_WELCOME_MESSAGE flag to Dockerfile
jaydrogers May 13, 2024
09ba2c3
chore: Add opcache to DEPENDENCY_PHP_EXTENSIONS in Dockerfile
jaydrogers May 13, 2024
5e2dcf2
chore: Update FRANKEN_PHP_VERSION to 1.1.4 in Dockerfile
jaydrogers May 13, 2024
d1bcbc6
Moved matrix to dedicated script
jaydrogers May 13, 2024
df97ef1
Add sorting
jaydrogers May 13, 2024
8a51c14
Merge branch 'main' into 280-create-a-frankenphp-variation
jaydrogers Jul 31, 2024
2bb76ce
chore: Update FRANKEN_PHP_VERSION to 1.2.2 in Dockerfile
jaydrogers Jul 31, 2024
0ab9bd3
Update `APP_BASE_DIR` default value to "/var/www/html" and add a new …
jaydrogers Jul 31, 2024
73b4031
Merge branch 'main' into 280-create-a-frankenphp-variation
jaydrogers Nov 22, 2024
cd72317
Merge branch 'main' into 280-create-a-frankenphp-variation
jaydrogers Mar 5, 2025
775f319
Bump PHP Extension Installer to version 2.7.27
jaydrogers Mar 5, 2025
39ee9b8
Add PHP_FPM_PM_MAX_REQUESTS as environment variable (#513)
Mar 5, 2025
dd8698d
Alphabatized variables
jaydrogers Mar 5, 2025
4612d3d
Add environment variable: PHP_MAX_INPUT_VARS (#500)
RadeJR Mar 5, 2025
003d88a
Merge branch 'release/v3.6' of github.com:serversideup/docker-php int…
jaydrogers Mar 5, 2025
7625ec6
Refactored "set-file-permissions" and "set-id" scripts. Fixes #502
jaydrogers Mar 5, 2025
792f1cb
Added cursor rules
jaydrogers Mar 6, 2025
6ff7b0c
Updated rules
jaydrogers Mar 6, 2025
4763451
Add NGINX Unit and PHP-FPM to system administrator skills
jaydrogers Mar 6, 2025
09e5a2f
Enhance S6 Overlay initialization script with robust error handling a…
jaydrogers Mar 6, 2025
883501f
Add additional OPCache environment variables (#510)
aSeriousDeveloper Mar 6, 2025
8f22dbf
Refactor Laravel Autorun Script, adjust entrypoint behavior, contiane…
aSeriousDeveloper Mar 11, 2025
c73193f
Add Cache-Control header to assets and media files (#487)
guillaumebriday Mar 11, 2025
44d5e8e
Update Laravel Automations documentation with detailed environment va…
jaydrogers Mar 11, 2025
8abfd75
Update Laravel Automations documentation for isolated migrations
jaydrogers Mar 11, 2025
2ffee5f
Add opt-int database seeding support (#404)
DarkGhostHunter Mar 11, 2025
d123d4a
Bump PHP Extension Installer version to 2.7.28
jaydrogers Mar 11, 2025
f74e487
Bump NGINX Unit version to 1.34.2
jaydrogers Mar 11, 2025
19ca9c8
Bump PHP Extension Installer version to 2.7.29
jaydrogers Apr 18, 2025
f784f8d
Bump PHP Extension Installer version to 2.7.31
jaydrogers Apr 18, 2025
4af92bd
Bump PHP Extension Installer version to 2.8.0
jaydrogers Jun 18, 2025
80c794f
Bump S6 version to 3.2.1.0
jaydrogers Jun 18, 2025
3a03547
Add support for skipping database connection checks during Laravel mi…
jaydrogers Jun 20, 2025
2029bfa
Update php-fpm-healthcheck version to 0.6.0 in installation script
jaydrogers Aug 4, 2025
947ac7e
Merge branch 'main' into release/v3.6
jaydrogers Aug 4, 2025
6eca498
Enhance get-php-versions.sh with DockerHub validation and fallback me…
jaydrogers Aug 4, 2025
08bb810
Refine PHP version validation in get-php-versions.sh to preserve warn…
jaydrogers Aug 4, 2025
205b069
Refactor PHP version fallback warnings in get-php-versions.sh
jaydrogers Aug 4, 2025
b46699c
Revert change to get-php-versions.sh
jaydrogers Aug 4, 2025
7e8beaa
Add GitHub Actions annotation function to get-php-versions.sh
jaydrogers Aug 4, 2025
4cbf04c
Fix output of GitHub Actions annotation function in get-php-versions.sh
jaydrogers Aug 4, 2025
8a0b41c
Cleaner method for GitHub annotation warnings
jaydrogers Aug 4, 2025
55c03c5
Disable warning about secrets because they don't have any secrets to …
jaydrogers Aug 19, 2025
d344d53
Add "Professionally Supported" section to README with service options…
jaydrogers Aug 20, 2025
e4ff084
Add script to fetch latest NGINX versions for different operating sys…
jaydrogers Aug 21, 2025
a20fc49
Update view-nginx-versions.sh script comments for clarity on OS filte…
jaydrogers Aug 21, 2025
831e272
Update view-nginx-versions.sh help menu to clarify source of NGINX ve…
jaydrogers Aug 21, 2025
1781743
Add functionality to determine and add family alias tags for Docker i…
jaydrogers Aug 21, 2025
7a7fc6b
Add auto-resolution for NGINX version in dev.sh for fpm-nginx builds.…
jaydrogers Aug 21, 2025
99d7bd4
Update NGINX version for Alpine 3.17 to 1.26.2-r1 and ensure proper f…
jaydrogers Aug 21, 2025
e9d3bb8
Renamed NGINX script and added --write mode
jaydrogers Aug 21, 2025
a390206
Add documentation for NGINX version management, including commands to…
jaydrogers Aug 21, 2025
5666893
Refactor to support installing NGINX from a specific version from the…
jaydrogers Aug 21, 2025
83761e2
Add NGINX repository key verification details for Debian and Alpine, …
jaydrogers Aug 21, 2025
85b4543
Update NGINX directory paths in docker-php-serversideup-set-file-perm…
jaydrogers Aug 21, 2025
238e208
Add dockerhub validation
jaydrogers Aug 21, 2025
0f41cca
Implement NGINX version computation for fpm-nginx builds in Docker wo…
jaydrogers Aug 21, 2025
6e1703a
Added Depot CI runners
jaydrogers Aug 21, 2025
a711abb
Adjust filtering logic to supported "latest OS" within the "supported…
jaydrogers Aug 21, 2025
304c527
Move matrix generation to a script
jaydrogers Aug 21, 2025
b015a35
Remove Trixie support for Unit
jaydrogers Aug 21, 2025
4f7d9fa
Remove support for Alpine 3.20 in PHP 8.4
jaydrogers Aug 21, 2025
c0e0f82
Removed Alpine 3.20
jaydrogers Aug 21, 2025
306bf0c
Added trixie support to Unit
jaydrogers Aug 21, 2025
9fefa9b
Add validation for OS and variation in Docker tag assembly script; in…
jaydrogers Aug 21, 2025
9467a3c
Enhance version weighting logic in matrix generation script to suppor…
jaydrogers Aug 21, 2025
ae3a912
Changed matrix to depot runner
jaydrogers Aug 21, 2025
141deb0
Update PHP extension installer version to 2.9.4
jaydrogers Aug 21, 2025
6642364
Update php-fpm-healthcheck to version 0.6.0 in installation script
jaydrogers Aug 21, 2025
e52ae67
Update S6 version to 3.2.1.0 in installation script
jaydrogers Aug 21, 2025
57340cc
Update NGINX Unit version to 1.34.2 in Dockerfile
jaydrogers Aug 21, 2025
6aade3e
Update php-fpm-healthcheck to version 0.6.0 in Dockerfile
jaydrogers Aug 21, 2025
74670a8
Comment out PHP 8.5-rc configuration due to a blocking bug in a depen…
jaydrogers Aug 21, 2025
6e6da58
Merge branch 'improvement/ci-and-nginx' into release/v3.6
jaydrogers Aug 21, 2025
26c1f6f
Organized script for better readability
jaydrogers Aug 21, 2025
fec586d
Merge branch 'improvement/ci-and-nginx' into release/v3.6
jaydrogers Aug 21, 2025
a3a11f8
Enhance script to require root privileges and improve error handling …
jaydrogers Aug 21, 2025
a0481b2
Merge branch 'improvement/ci-and-nginx' into release/v3.6
jaydrogers Aug 21, 2025
2f822e9
Merge branch 'release/v3.6' into 280-create-a-frankenphp-variation
jaydrogers Aug 22, 2025
59e3121
Revert changes to alpine and debian installer
jaydrogers Aug 22, 2025
9e9ad9b
Add shellcheck label
jaydrogers Aug 22, 2025
0e550f4
Enhance generate-matrix.sh to include excluded_minor_versions in PHP …
jaydrogers Aug 22, 2025
64ed90d
Compile FrankenPHP from source
jaydrogers Aug 23, 2025
ef48b01
Exclude 8.2 on FrankenPHP
jaydrogers Aug 23, 2025
62e8405
Merge branch 'main' into release/v3.6
jaydrogers Aug 26, 2025
ae7eb4b
Merge branch 'release/v3.6' into 280-create-a-frankenphp-variation
jaydrogers Aug 26, 2025
a3d592c
Add default Caddyfile for FrankenPHP that mimics the FPM-NGINX experi…
hookenz Aug 28, 2025
78f2b40
Enhance get-php-versions.sh script to include an optional --output pa…
jaydrogers Sep 3, 2025
0c769d4
Update get-php-versions.sh to add --input parameter for specifying th…
jaydrogers Sep 3, 2025
5019265
Refactor to get the truth of the default variation from the php-versi…
jaydrogers Sep 3, 2025
02fa1f7
Set the repository build version
jaydrogers Sep 3, 2025
f281c6a
Update docker-php-serversideup-set-file-permissions script to support…
jaydrogers Sep 3, 2025
186fe8f
Update GitHub Actions workflows to use actions/checkout@v5 for improv…
jaydrogers Sep 4, 2025
ec59633
Update GitHub Actions workflow to use actions/download-artifact@v5 fo…
jaydrogers Sep 4, 2025
b85a7cb
Update PHP extension installer version to 2.9.7 for improved function…
jaydrogers Sep 4, 2025
f58e227
Refactor dev.sh to replace CUSTOM_REGISTRY with PUSH_TO_REGISTRY flag…
jaydrogers Sep 4, 2025
25a5fce
Enhance docker-php-serversideup-set-file-permissions script to suppor…
jaydrogers Sep 4, 2025
e4c1718
Updated FrankenPHP version to 1.9.1
jaydrogers Sep 30, 2025
ecc4764
Changed source compile method to use xcaddy
jaydrogers Sep 30, 2025
1ff2789
Update PHP extension installer version to 2.9.9
jaydrogers Sep 30, 2025
35db83f
Refactor docker-php-serversideup-set-file-permissions script to auto-…
jaydrogers Sep 30, 2025
1017afa
Update Apache configuration to use dynamic HEALTHCHECK_PATH variable …
jaydrogers Sep 30, 2025
f868e0a
Update NGINX access logging to conditionally disable logs for healthc…
jaydrogers Oct 1, 2025
5b4f04c
Add `NGINX_ERROR_LOG` and `NGINX_ACCESS_LOG`. (#534)
robsontenorio Oct 1, 2025
a3431d9
Add`PHP_FPM_PM_STATUS_PATH`, `PHP_OPCACHE_ENABLE_FILE_OVERRIDE`, `PHP…
jaydrogers Oct 1, 2025
f4d237f
FEAT: add `NGINX_IP_LISTENING_PROTOCOL` (#539)
yuuzukatsu Oct 1, 2025
4bb3173
feat: allow nginx `client_max_body_size` to be configurable (#558)
dlundgren Oct 1, 2025
7837fd1
Fix deprecation notices for `session.sid_length` and `session.sid_bit…
jaydrogers Oct 1, 2025
85f9f79
Merge branch '280-create-a-frankenphp-variation' of github.com:server…
jaydrogers Oct 1, 2025
87286af
Update PHP extension installer version to 2.9.11
jaydrogers Oct 2, 2025
2b5cd7b
Update performance.conf (#530)
ricardomm85 Oct 2, 2025
c63c75c
Merge branch 'main' into 280-create-a-frankenphp-variation
jaydrogers Oct 2, 2025
ad5fe47
introduce start-period and start-interval parameters to HEALTHCHECK (…
aSeriousDeveloper Oct 2, 2025
077fd62
Add absolute_redirect off to Nginx configuration files
jaydrogers Oct 2, 2025
46b232e
Update log format in Apache vhost templates to include Referer and Us…
jaydrogers Oct 2, 2025
15b3091
Update environment variable documentation for Laravel optimizations a…
jaydrogers Oct 2, 2025
99ecb51
Update Laravel documentation links to reflect version 12.x changes fo…
jaydrogers Oct 2, 2025
4838355
Refactor Laravel migration script to build migration flags dynamicall…
jaydrogers Oct 2, 2025
3f1f527
Fixed notice of `/package/admin/s6-overlay/libexec/preinit: info: /ru…
jaydrogers Oct 2, 2025
bfb00cd
Enhance Laravel automation scripts with new migration options and imp…
jaydrogers Oct 7, 2025
c465d9b
Add Caddy logging configuration to Dockerfile for frankenphp variation
jaydrogers Oct 8, 2025
ded236f
Add healthcheck configuration to Dockerfile and Caddyfile for franken…
jaydrogers Oct 8, 2025
c92e7c7
Merge branch 'main' into 280-create-a-frankenphp-variation
jaydrogers Oct 8, 2025
14aacd1
Fix missing procps on FrankenPHP Variation (#571)
arnaud-ritti Oct 10, 2025
20dd93c
Add instructions for computing the Alpine key hash and building with …
jaydrogers Oct 14, 2025
582b16f
Update documentation to replace 'NGINX Unit variation' with 'FrankenP…
jaydrogers Oct 14, 2025
6ccd468
Add Docker introduction and benefits to installation documentation
jaydrogers Oct 14, 2025
814f395
Renamed getting started folder
jaydrogers Oct 14, 2025
9bf823f
Renamed folders
jaydrogers Oct 14, 2025
5c6928c
Moved folders
jaydrogers Oct 14, 2025
7d818f5
Remove version declaration from Docker Compose example in PHP setting…
jaydrogers Oct 14, 2025
bbbefc3
Added "acme" certificate mode for FrankenPHP
jaydrogers Oct 14, 2025
b8fe41a
Set proper XDG_* paths
jaydrogers Oct 15, 2025
e029eaf
Added FrankenPHP version during build (Fixes #577)
jaydrogers Oct 15, 2025
3c1196a
Refactored Caddyfile structure for better SSL experience
jaydrogers Oct 15, 2025
5a3699c
Updated installation documentation to enhance clarity on PHP variatio…
jaydrogers Oct 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .cursor/rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
You are a highly skilled PHP system administrator tasked with maintaining open source PHP Docker images for Laravel applications. Your goal is to assist in creating production-ready Docker images that follow best practices for security, performance, and developer experience using the guidelines below.

1. Skills you posses deep knowledge and best practices of:
- Docker
- PHP
- Laravel
- GitHub Actions
- Shell scripting
- S6 Overlay
- Nginx
- Apache
- NGINX Unit
- PHP-FPM

2. Development Guidelines:

- Follow the best practices for security, performance, and developer experience.
- Write clean, maintainable and technically accurate code.
- All entrypoint scripts for the Docker images must be POSIX compliant and able to be executed with /bin/sh.
- Any /bin/sh scripts must be compatible with Debian and Alpine Linux.
- For any /bin/bash scripts, these should work with MacOS, Linux, and WSL2.
- Never use an approach you're not confident about. If you're unsure about something, ask for clarity.

This project is open source and the code is available on GitHub, so be sure to follow best practices to make it easy for others to understand, modify, and contribute to the project.
2 changes: 1 addition & 1 deletion .github/workflows/action_update-dockerhub-readme.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
name: Push README to Docker Hub
steps:
- name: git checkout
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: main

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/scheduled-task_update-sponsors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout πŸ›ŽοΈ
uses: actions/checkout@v4
uses: actions/checkout@v5

- name: Generate Sponsors πŸ’–
uses: JamesIves/github-sponsors-readme-action@v1
Expand Down
11 changes: 3 additions & 8 deletions .github/workflows/service_docker-build-and-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,6 @@ on:
type: string
default: 'scripts/conf/php-versions.yml'
description: 'The path to the PHP versions file.'
default-image-variation:
type: string
default: 'cli'
description: 'The default PHP variation to use for the Docker image.'
registry-repositories:
type: string
required: true
Expand All @@ -43,7 +39,7 @@ jobs:
php-version-map-json: ${{ steps.get-php-versions.outputs.php-version-map-json }}
steps:
- name: Check out code
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: ${{ inputs.ref }}

Expand Down Expand Up @@ -84,12 +80,12 @@ jobs:

steps:
- name: Check out code.
uses: actions/checkout@v4
uses: actions/checkout@v5
with:
ref: ${{ inputs.ref }}

- name: Download PHP Versions file
uses: actions/download-artifact@v4
uses: actions/download-artifact@v5
with:
name: php-versions.yml
path: ./artifacts
Expand Down Expand Up @@ -127,7 +123,6 @@ jobs:
./scripts/assemble-docker-tags.sh
env:
PHP_VERSIONS_FILE: "${{ inputs.php-versions-file }}"
DEFAULT_IMAGE_VARIATION: ${{ inputs.default-image-variation }}
PHP_BUILD_VERSION: ${{ matrix.patch_version }}
PHP_BUILD_VARIATION: ${{ matrix.php_variation }}
PHP_BUILD_BASE_OS: ${{ matrix.base_os }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ layout: docs
| Built-in security optimizations | ❌ | βœ… |
| Optimized for Laravel & WordPress| ❌ | βœ… |
| NGINX + FPM variation| ❌ | βœ… |
| NGINX Unit variation| ❌ | βœ… |
| FrankenPHP variation| ❌ | βœ… |
| Native health checks | ❌ | βœ… |

## Unprivileged by Default
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,42 @@ layout: docs
All images are hosted on [DockerHub](https://hub.docker.com/r/serversideup/php) and [GitHub Packages](https://github.com/serversideup/docker-php/pkgs/container/php) for free. Containers default to running Debian, but Alpine images are also available.
::

## What's Docker?
[Docker](https://www.docker.com/) is an open source utility for building, shipping, and running applications in containers. Containers are isolated environments that can run on any host.

![Docker Layers with Laravel Application](/images/docs/docker-layers.png)

### Why containerize with Docker?
Going through the efforts of containerizing your application gives you one extremely powerful capability:

πŸ‘‰ **You can run your application anywhere**

Once you're at this level, you unlock a ton of new possibilities:

- **Your application runs the same, everywhere** - no more "it works on my machine". Run 100% of your application on any operating system. All they need is Docker installed.
- **Ship with more confidence** - all infrastructure configurations are *centrally managed* in Git, so you can change, test and rollback with ease
- **No more vendor lock-in** - if a host raises their prices on you, you can migrate with very little effort
- **Scaling is a breeze** - once you get your application in one container, it's so easy to scale up to any number of containers
- **Improved security** - containerized apps are more secure than traditional apps because they are isolated from the host
- **Better uptime** - if something fails during deployment, you can roll back your application to a previous version with ease

The even crazier part is you don't need a Platform as a Service (PaaS) to get all these benefits. Everything can be done with 100% free and open source tools.

## How to get started with Docker
At first, Docker may seem a little intimidating, but don't let that stop you. Docker is one of the most powerful skill-sets that we've learned in our career.

Although teaching you how to use Docker is beyond the scope of serversideup/php, we've actually created another open source project called [Spin](https://serversideup.net/open-source/spin/) that dramatically reduces the learning curve for getting started with Docker.

Here's a quick demo of Spin of what an app looks like when we use Docker from development to production:

::video-embed
---
src: https://www.youtube.com/watch?v=5z2JoEt5XIk
---
::

[Learn more about Spin β†’](https://serversideup.net/open-source/spin/)

## Our most popular images
All images are intelligently tagged with the PHP version and variation. This allows you to easily select the right image for your use case.

Expand All @@ -28,28 +64,53 @@ Our most popular tags include:
| unit | <span class="font-bold text-white">Debian Based</span><span class="not-prose mb-1 block">[![serversideup/php:8.4-unit](https://img.shields.io/docker/image-size/serversideup/php/8.4-unit?label=serversideup%2Fphp%3A8.4-unit)](https://hub.docker.com/r/serversideup/php/tags?name=8.4-unit&page=1&ordering=-name)</span><span class="not-prose mb-1 block">[![serversideup/php:8.3-unit](https://img.shields.io/docker/image-size/serversideup/php/8.3-unit?label=serversideup%2Fphp%3A8.3-unit)](https://hub.docker.com/r/serversideup/php/tags?name=8.3-unit&page=1&ordering=-name)</span><span class="not-prose mb-1 block">[![serversideup/php:8.2-unit](https://img.shields.io/docker/image-size/serversideup/php/8.2-unit?label=serversideup%2Fphp%3A8.2-unit)](https://hub.docker.com/r/serversideup/php/tags?name=8.2-unit&page=1&ordering=-name)</span><span class="not-prose mb-1 block">[![serversideup/php:8.1-unit](https://img.shields.io/docker/image-size/serversideup/php/8.1-unit?label=serversideup%2Fphp%3A8.1-unit)](https://hub.docker.com/r/serversideup/php/tags?name=8.1-unit&page=1&ordering=-name)</span><span class="not-prose mb-1 block">[![serversideup/php:8.0-unit](https://img.shields.io/docker/image-size/serversideup/php/8.0-unit?label=serversideup%2Fphp%3A8.0-unit)](https://hub.docker.com/r/serversideup/php/tags?name=8.0-unit&page=1&ordering=-name)</span><span class="not-prose mb-1 block">[![serversideup/php:7.4-unit](https://img.shields.io/docker/image-size/serversideup/php/7.4-unit?label=serversideup%2Fphp%3A7.4-unit)](https://hub.docker.com/r/serversideup/php/tags?name=7.4-unit&page=1&ordering=-name)</span> |

## Selecting the right variation
There are 4 main variations.
We offer a number of different variations to suit your needs. Each variation is optimized for specific use cases.

### CLI
If you need to run a quick command with something like `composer` or use PHP to run a CLI program only, this might be a great option for you.
The CLI variation is a minimal image designed for running PHP from the command line only. It does not include a web server.

Use this variation for running commands like Composer, running scheduled tasks, or executing PHP scripts that don't require a web server.

[Learn more about CLI β†’](/docs/image-variations/cli)

### FPM
The `fpm` variation is great for people who need to run a PHP "backend" if they already have a proxy serving static content. If you're using FPM only, that means you're probably at a larger scale.
The FPM (Fast Process Manager) variation runs PHP-FPM without a web server. This variation is ideal for microservices architectures where you need a dedicated PHP backend.

Use this variation when you already have a separate proxy or load balancer handling static content and routing PHP requests to your FPM container. This is commonly used in larger-scale deployments.

[Learn more about FPM β†’](/docs/image-variations/fpm)

### FPM-Apache
The `fpm-apache` variation is meant for users who want to run something like WordPress with Docker. Apache is configured to be a "reverse proxy", which will serve any static content with Apache and serve any PHP requests with PHP-FPM. Since there are two processes required to run this variation, we use [S6 Overlay](/docs/guide/using-s6-overlay) to ensure the container health is accurate.
The FPM-Apache variation combines PHP-FPM with Apache as a reverse proxy. Apache serves static content directly and forwards PHP requests to PHP-FPM for processing.

Use this variation for applications like WordPress that benefit from Apache's .htaccess support and mod_rewrite functionality. This is a production-ready setup using S6 Overlay to manage both processes reliably.

[Learn more about using Docker with WordPress β†’](/docs/guide/using-wordpress-with-docker)
[Learn more about FPM-Apache β†’](/docs/image-variations/fpm-apache) | [Using Docker with WordPress β†’](/docs/guide/using-wordpress-with-docker)

### FPM-NGINX
The `fpm-nginx` variation is great for people who want to run Laravel applications or similar. This allows you to serve static content quickly with NGINX but also pass PHP requests to PHP-FPM. Similar to PHP-Apache, there are two processes required to run this variation. We use S6 Overlay to ensure the container health is accurate.
The FPM-NGINX variation combines PHP-FPM with NGINX as a reverse proxy. This is the traditional setup that has been widely adopted for modern PHP applications, including many Laravel deployments.

Use this variation for production Laravel applications and other PHP frameworks that require a stable, battle-tested web server configuration. We use S6 Overlay to ensure both processes run reliably in a single container.

[Learn more about FPM-NGINX β†’](/docs/image-variations/fpm-nginx)

### Unit (deprecated)
::note
In October 2025, NGINX stopped supporting NGINX Unit and archived the project. NGINX Unit will eventually be removed from our project. [See the official announcement β†’](https://github.com/nginx/unit?tab=readme-ov-file#nginx-unit)
::

The Unit variation uses NGINX Unit as a modern application server that runs everything in a single process.

While this variation is being deprecated, it can still be used for existing applications. Consider migrating to FrankenPHP for a modern single-process alternative.

[Learn more about Unit β†’](/docs/image-variations/unit)

[Learn more about S6 Overlay β†’](/docs/guide/using-s6-overlay)
### FrankenPHP
The FrankenPHP variation is a modern application server built on top of the Caddy web server. It runs everything in a single process, eliminating the complexity of managing PHP-FPM and a separate web server.

### Unit
The `unit` variation is for NGINX Unit, which is a modern approach to delivering containerized web applications. Instead of relying on the complexities of two processes running NGINX + PHP-FPM, Unit replaces both the NGINX Web Server and PHP-FPM to run everything under one process. Unit is open source and maintained by the NGINX Unit team.
Use this variation for Laravel or Symfony applications that can benefit from worker mode, automatic HTTPS, and modern protocols like HTTP/2 and HTTP/3. This is the recommended variation for new projects seeking cutting-edge performance.

[Learn more about Unit β†’](https://unit.nginx.org/)
[Learn more about FrankenPHP β†’](/docs/image-variations/frankenphp)

## Selecting the version of PHP
Selecting the best version of PHP is highly dependent on your use case. In a perfect world, running the latest version of PHP will give you the latest and greatest, but it all depends on the libraries that your application uses.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Since these images are not privileged, that means they are not running on ports
| fpm-nginx | HTTP: 8080, HTTPS: 8443 |
| fpm-apache | HTTP: 8080, HTTPS: 8443 |
| unit | HTTP: 8080, HTTPS: 8443 |
| frankenphp | HTTP: 8080, HTTPS: 8443 |

### How do I run these services on ports 80 and/or 443?
Almost everyone will want to run these services on ports 80 and 443. If you have an advanced setup, you can use a reverse proxy like Caddy or Traefik to handle the SSL termination and forward the traffic to the container on the non-privileged port.
Expand Down Expand Up @@ -85,9 +86,11 @@ The following packages are installed by default:
|-------------|-----------------|----------------------|------------------------|
| `libfcgi-bin`<br/>(Debian)<br/>`fcgi`<br/>(Alpine) | FastCGI is a protocol for interfacing interactive programs with a web server. | *-fpm <br/> *-fpm-nginx <br/> *-fpm-apache | This is required for the webserver to interface with PHP-FPM and the [`php-fpm-healthcheck`](https://github.com/renatomefi/php-fpm-healthcheck) project. |
| `gettext-base` (Debian) <br/> `gettext` (Alpine) | GNU gettext is a framework for translating user interfaces. | *-fpm-nginx <br/> *-fpm-apache | This is required for the `envsubst` command. We use this command to process templates on container initialization. |
| `procps` (Debian) | The procps package contains programs for monitoring your system and its processes. | * (Debian images) | This is required for `pgrep` so we can use that for our native health checks. |
| `libstdc++6`<br/>(Debian)<br/>`libstdc++` (Alpine) | The GNU Standard C++ Library is a C++ standard library. | *-frankenphp | This is [required for the watcher to run](https://github.com/php/frankenphp/blob/e917ab79742c9e4703023861fdc7a86cdb59da1e/Dockerfile#L135-L138) with FrankenPHP. |
| `procps` | The procps package contains programs for monitoring your system and its processes. | * (only Debian images) | This is required for `pgrep` so we can use that for our native health checks. |
| `shadow` | Shadow is required for the `usermod` command. | *-alpine | This is required to change the UID and GID of the `www-data` user in `docker-php-serversideup-set-id`. |


## Health Checks
By default, all health checks for web servers (Apache, Unit, NGINX, etc.) are located at `/healthcheck`. You should receive an `OK` response if the container is healthy.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,16 +117,25 @@ label: "Update NGINX versions"

Compute the Alpine key hash when updating:

::code-panel
---
label: "Compute the Alpine key hash"
---
```bash
curl -sS https://nginx.org/keys/nginx_signing.rsa.pub -o /tmp/nginx_signing.rsa.pub
# macOS
openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -outform DER 2>/dev/null | shasum -a 256 | awk '{print $1}'
# Linux
openssl rsa -pubin -in /tmp/nginx_signing.rsa.pub -outform DER 2>/dev/null | sha256sum | awk '{print $1}'
```
::

Then build with the new hash (optionally include the old hash during rotation):

::code-panel
---
label: "Build with the new hash"
---
```bash
docker build \
--build-arg SIGNING_ALPINE_RSA_PUB_SHA256="<new-hash>,<old-hash>" \
Expand Down
Loading
Loading