An open API service indexing awesome lists of open source software.

https://github.com/shinsenter/php

๐Ÿ“ฆ Simplified PHP Docker images for easy customization and extension setup. Supports PHP 5.6 to 8.5 in CLI, ZTS, FPM, FPM/Apache2, FPM/Nginx, RoadRunner and FrankenPHP variants, available in both Debian and Alpine. Built daily.
https://github.com/shinsenter/php

docker-frankenphp docker-laravel docker-php docker-php-alpine docker-php-apache docker-php-apps docker-php-cli docker-php-debian docker-php-fpm docker-php-frankenphp docker-php-mini docker-php-nginx docker-php-nginx-unit docker-php-roadrunner docker-php-servers docker-roadrunner docker-s6-overlay docker-symfony docker-wordpress php

Last synced: about 1 month ago
JSON representation

๐Ÿ“ฆ Simplified PHP Docker images for easy customization and extension setup. Supports PHP 5.6 to 8.5 in CLI, ZTS, FPM, FPM/Apache2, FPM/Nginx, RoadRunner and FrankenPHP variants, available in both Debian and Alpine. Built daily.

Awesome Lists containing this project

README

          

# PHP Docker Images
๐Ÿ“ฆ Simplified PHP Docker images for effortless customization and extension setup.

Our Docker images cover PHP versions from 5.6 to 8.5 (beta), available in CLI, ZTS, FPM, FPM/Apache2, FPM/Nginx, RoadRunner and FrankenPHP variants. The Docker images are available for both Debian and Alpine versions.

- Docker Hub: https://hub.docker.com/r/shinsenter/php
- GitHub Packages: https://code.shin.company/php/pkgs/container/php
- You can also find and use [other pre-built Docker images for some popular PHP applications and frameworks here](https://hub.docker.com/u/shinsenter).

[![Daily build](https://code.shin.company/php/actions/workflows/build-all.yml/badge.svg)](https://code.shin.company/php/actions/workflows/build-all.yml)

## Table of Contents
- [Introduction](#introduction)
- [Docker Image Variants](#docker-image-variants)
- [Customizing Settings via Environment Variables](#customizing-settings-via-environment-variables)
- [Pre-installed PHP Extensions](#pre-installed-php-extensions)
- [Adding PHP Extensions](#adding-php-extensions)
- [Application Directory](#application-directory)
- [Customizing Container User and Group in Docker](#customizing-container-user-and-group-in-docker)
- [Hooks](#hooks)
- [Autorun Scripts](#autorun-scripts)
- [Using Cron Jobs](#using-cron-jobs)
- [Customize Supervisor Command](#customize-supervisor-command)
- [Sending Emails](#sending-emails)
- [Debug Mode](#debug-mode)
- [Other System Settings](#other-system-settings)
- [Supported Platforms](#supported-platforms)
- [Stable Image Tags](#stable-image-tags)
- [Contributing](#contributing)
- [License](#license)

## Introduction

[![shinsenter/php](https://repository-images.githubusercontent.com/458053748/5a05c8e4-1c00-440c-98f1-2cd4548bbaa2)](https://docker.shin.company/php)

Our PHP Docker images are based on the [official PHP Docker images](https://hub.docker.com/_/php).
These images facilitate the easy adjustment of PHP and PHP-FPM settings using environment variables,
eliminating the need to rebuild images when making configuration changes.

These images also come with the latest version of [Composer](https://getcomposer.org)
and popular web servers like [Apache2](https://httpd.apache.org), [Nginx](https://nginx.org), [RoadRunner](https://roadrunner.dev) or [FrankenPHP](https://frankenphp.dev).
This setup allows for faster project initiation without additional installations.

> ๐Ÿชถ Info: While built on the official PHP images and including more useful extensions,
> we have **significantly reduced the image sizes** compared to the base images.
> This optimization improves download times and resource usage without sacrificing functionality,
> thanks to the [docker-squash](https://code.shin.company/docker-squash) project.

## Docker Image Variants

Our image tags cover PHP versions from 5.6 to 8.5,
available in `cli`, `zts`, `fpm`, `fpm-nginx`, `fpm-apache`, `roadrunner`(1), and `frankenphp`(2) variants. The Docker images are available for both Debian and Alpine versions.

Examples:
- `shinsenter/php:8.3-cli`
- `shinsenter/php:8.4-zts`
- `shinsenter/php:8.5-fpm`
- `shinsenter/php:8.1-fpm-apache`
- `shinsenter/php:8.2-fpm-nginx`
- `shinsenter/php:8.3-roadrunner` (1)
- `shinsenter/php:8.4-frankenphp` (2)

> (1): PHP with RoadRunner server. The `roadrunner` variant supports PHP >= 8.0.

> (2): FrankenPHP is still in BETA. The `frankenphp` variant supports PHP >= 8.2.

Explore all available tags on our [Docker Hub](https://hub.docker.com/r/shinsenter/php/tags).

### Examples

You can easily run a container by copying and pasting one of these `docker run` commands:

#### CLI

```shell
# non-interactive
docker run --rm shinsenter/php:8.5-cli php -m

# interactive
docker run -it -v ./myproject:/var/www/html shinsenter/php:8.5-cli
```

#### PHP-FPM

```shell
docker run -v ./myproject:/var/www/html -p 9000:9000 shinsenter/php:8.5-fpm
```

#### PHP-FPM + Nginx (or Apache, RoadRunner, FrankenPHP)

```shell
# with Nginx
docker run -v ./myproject:/var/www/html -p 80:80 -p 443:443 shinsenter/php:8.5-fpm-nginx

# with Apache
docker run -v ./myproject:/var/www/html -p 80:80 -p 443:443 shinsenter/php:8.5-fpm-apache

# with RoadRunner
docker run -v ./myproject:/var/www/html -p 80:80 -p 443:443 shinsenter/php:8.4-roadrunner

# with FrankenPHP
docker run -v ./myproject:/var/www/html -p 80:80 -p 443:443 shinsenter/php:8.4-frankenphp
```

## Customizing Settings via Environment Variables

These images allow customizing PHP and PHP-FPM settings through environment variables instead of rebuilding images.

The environment variable names follow these conventions:
- Variables are prefixed with `PHP_` to avoid conflicts with other application variables.
- The rest of the variable name matches the configuration directive name from `php.ini` or `php-fpm.conf`:
- PHP ini directives: https://www.php.net/manual/en/ini.list.php
- PHP-FPM directives: https://www.php.net/manual/en/install.fpm.configuration.php
- Directive names are converted to `CONSTANT_CASE` - uppercase with underscores instead of dots or dashes.

This naming convention helps you easily identify which environment variable applies to which PHP/PHP-FPM configuration directive.

> ๐Ÿ‘‰๐Ÿป Info: By default, the `$PHP_*` environment variables only take effect when set before starting the container.
> To dynamically change PHP configurations using `$PHP_*` environment variables while running commands within the container,
> you need to start your container with the `ALLOW_RUNTIME_PHP_ENVVARS=1` environment variable.

> ๐Ÿ’ก Hint: Run `php-envvars` in the container to get a full list of default `$PHP_*` environment variables.

### Examples

#### Command Line

```shell
docker run \
-v ./myproject:/var/www/html \
-e PHP_DISPLAY_ERRORS='1' \
-e PHP_POST_MAX_SIZE='100M' \
-e PHP_UPLOAD_MAX_FILESIZE='100M' \
-e PHP_SESSION_COOKIE_HTTPONLY='1' \
shinsenter/php:8.5 php -i
```

#### With docker-compose.yml

```yaml
services:
web:
image: shinsenter/php:8.5-fpm-nginx
environment:
PHP_DISPLAY_ERRORS: "1"
PHP_POST_MAX_SIZE: "100M"
PHP_UPLOAD_MAX_FILESIZE: "100M"
PHP_SESSION_COOKIE_HTTPONLY: "1"
```

#### Explanation

| Environment Variable | Explanation | Equivalent Configuration |
|-------------------------------|----------------------------------------------------|-----------------------------|
| PHP_DISPLAY_ERRORS=1 | Enables displaying errors during development. | `display_errors 1` |
| PHP_POST_MAX_SIZE=100M | Increases the maximum post size from the default 8MB. | `post_max_size 100M` |
| PHP_UPLOAD_MAX_FILESIZE=100M | Increases the maximum upload file size from the default 2MB. | `upload_max_filesize 100M` |
| PHP_SESSION_COOKIE_HTTPONLY=1 | Enables the HttpOnly flag for session cookie security. | `session.cookie_httponly 1` |

> ๐Ÿ’ก Hint: Run `php-envvars` in the container to get a full list of default `$PHP_*` environment variables.

## Pre-installed PHP Extensions

Popular PHP extensions are pre-installed by default, allowing projects to get started faster without additional installation.

```list
apcu
bcmath
calendar
exif
gd
gettext
igbinary
intl
msgpack
mysqli
opcache
pcntl
pdo_mysql
pdo_pgsql
pgsql
redis
sodium
tidy
uuid
yaml
zip
```

> ๐Ÿ‘‰๐Ÿป Info: The pre-installed PHP extensions from the official Docker images are excluded from this list.

> ๐Ÿ’ก Hint: Run `docker run --rm shinsenter/php:8.5-cli php -m` in the container
to get a list of extensions (you can replace `8.5` with a specific PHP version).

## Adding PHP Extensions

These images use a simple command called `phpaddmod` to install PHP extensions.

You don't need to run the more complex `docker-php-ext-install` command
or manually edit the `php.ini` file; `phpaddmod` handles the installation and configuration for you.

For example, in your `Dockerfile`:

```Dockerfile
FROM shinsenter/php:8.5-fpm-nginx

# Install imagick, swoole and xdebug
RUN phpaddmod imagick swoole xdebug

# Add your instructions here
# For example:
# ADD --chown=$APP_USER:$APP_GROUP ./myproject/ /var/www/html/
```

> ๐Ÿ‘‰๐Ÿป Info: The `phpaddmod` command is a wrapper around the [`mlocati/docker-php-extension-installer`](https://github.com/mlocati/docker-php-extension-installer) utility,
which takes care of all required steps to compile and activate the extensions.

> ๐Ÿ’ก Hint: If you're having trouble figuring out which extensions can be installed,
have a look at [their documentation](https://github.com/mlocati/docker-php-extension-installer/blob/master/README.md#supported-php-extensions).

## Application Directory

The default application directory is `/var/www/html` and can be customized via the `$APP_PATH` environment variable:

```shell
docker run -p 80:80 -p 443:443 -p 443:443/udp \
-v "$PWD":/app \
-e APP_PATH=/app \
shinsenter/php:8.5-fpm-nginx
```

This changes the web application directory to `/app`.

Moreover, the default document root
(a relative path inside the `$APP_PATH` (application directory) that contains your `index.php` file)
can be customized by setting the `$DOCUMENT_ROOT` environment variable:

```shell
docker run -p 80:80 -p 443:443 -p 443:443/udp \
-v "$PWD":/app \
-e APP_PATH=/app \
-e DOCUMENT_ROOT=public \
shinsenter/php:8.5-fpm-nginx
```

This would change the document root path to `/app/public`.

## Customizing Container User and Group in Docker

Override the default user and group settings by setting environment variables when running the container.

Available variables:

| Environment Variable | Description | Default |
|----------------------|-----------------------------------------|------------------|
| `APP_USER` | Username inside the container | `www-data` |
| `APP_GROUP` | Group name inside the container | `www-data` |
| `APP_UID` | Numeric UID of the user | UID in container |
| `APP_GID` | Numeric GID of the group | GID in container |

For example, to run a container as user `myapp` with UID `5000`:

```shell
docker run -p 80:80 -p 443:443 -p 443:443/udp \
-e APP_USER=myapp \
-e APP_UID=5000 \
shinsenter/php:8.5-fpm-nginx
```

Or in a `docker-compose.yml`:
```yaml
services:
web:
image: shinsenter/php:8.5-fpm-nginx
environment:
APP_USER: "myapp"
APP_UID: "5000"
```

## Hooks

Hooks are useful for customizing the behavior of a running container.

These images support the following hooks:

| Hook name | Description | Example usage |
|-------------|------------------------------------------------------|----------------------------|
| `onboot` | Runs when the container starts or restarts. | Send startup notification. |
| `first-run` | Runs only the first time the container starts. | Initialize database. |
| `rebooted` | Runs whenever the container restarts. | Check crash logs. |
| `migration` | Runs migration scripts. | Run DB migrations. |
| `onready` | Runs after `migration`, when the app is nearly ready.| Warm up caches. |
| `onlive` | Runs after the web server starts (if included). | Trigger webhook. |

To use hooks, create a `hooks` folder inside `$APP_PATH` and add executable files named after the hook, or in subfolders with the same name.
Example: to install PHP modules at `first-run`, add a script `hooks/first-run` or `hooks/first-run/install-modules`.

Set `DEBUG=1` to see which hooks are executed.

## Autorun Scripts

Shell scripts placed in the `/startup/` directory will automatically run when the container starts, in alphabetical order by filename.
This feature can initialize projects before the main program runs, saving time by executing initialization scripts automatically.

#### Usage Example

Copy a script called `00-migration` into `/startup/` via a Dockerfile:

> Note: Ensure the script has executable permissions.

```Dockerfile
FROM shinsenter/php:8.5-cli

ADD ./autorun/00-migration /startup/00-migration
RUN chmod +x /startup/00-migration

# Add your instructions here
# For example:
# ADD --chown=$APP_USER:$APP_GROUP ./myproject/ /var/www/html/
```

> ๐Ÿ‘‰๐Ÿป Info: The startup directory already includes a script called `99-greeting` that prints a welcome message when the container starts.

#### Disable Autorun Scripts

To disable autorun scripts, set `DISABLE_AUTORUN_SCRIPTS=1` as an environment variable.

For example, with `docker run`:

```shell
docker run -e DISABLE_AUTORUN_SCRIPTS=1 shinsenter/ubuntu-s6:latest bash
```

Or in `docker-compose.yml`:

```yaml
services:
web:
image: shinsenter/ubuntu-s6:latest
environment:
DISABLE_AUTORUN_SCRIPTS: "1"
```

## Using Cron Jobs

> **Note**: This is a supporting feature. If you require more advanced capabilities beyond basic `crontab` functionality, please consider building your own Docker image and installing an alternative scheduling tool (e.g., [supercronic](https://github.com/aptible/supercronic)) that better suits your needs.

To enable cron jobs in containers, you can start the container with `ENABLE_CRONTAB=1`.
This setting activates the Crontab service, which loads settings from the directory specified by `$CRONTAB_DIR` (default is `/etc/crontab.d`).

The cron jobs will run as the user defined by `$APP_USER:$APP_GROUP`, which by default is `www-data:www-data`,
and with the home directory set by `$CRONTAB_HOME` (default is `/var/www/html`).

Here is an example Dockerfile to add a crontab:

```Dockerfile
FROM shinsenter/php:latest

ENV ENABLE_CRONTAB=1

# create crontab entry via RUN instruction
RUN echo '* * * * * echo "echo This line will run every minute!" | tee /tmp/cron-every-minute.txt' >> /etc/crontab.d/sample1;

# or copy crontab entries via ADD instruction
ADD ./sample2 /etc/crontab.d/
```

The format of a crontab entry is as follows:

```
# Job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * command to be executed
```

You can also easily set up cron jobs through the `$CRONTAB_SETTINGS` environment variable in the `docker-compose.yml` file.
When the container starts, these settings are loaded into crontab, giving you more flexibility to change them later.

```yml
services:
web:
image: shinsenter/php:8.5-fpm-nginx
environment:
ENABLE_CRONTAB: "1"
CRONTAB_SETTINGS: "* * * * * echo 'This line will run every minute!' | tee /tmp/cron-every-minute.txt"
```

For more information on environment variables for cron jobs, refer to the [Other System Settings](#other-system-settings) section below.

## Customize Supervisor Command

We can set a `$SUPERVISOR_PHP_COMMAND` environment variable to the service definition in your application's `docker-compose.yml` file.
This environment variable will contain the command that the container will use to serve your application using another process instead of the default process.

#### Command Line

```shell
docker run \
-e SUPERVISOR_PHP_COMMAND='php -S localhost:80 index.php' \
shinsenter/php:8.5
```

#### With docker-compose.yml

```yml
services:
web:
image: shinsenter/php:8.5
environment:
SUPERVISOR_PHP_COMMAND: "php -S localhost:80 index.php"
```

## Sending Emails

In these Docker images, `sendmail` has been replaced by `msmtp` for sending emails.
You can send emails using common PHP libraries like [PHPMailer](https://github.com/PHPMailer/PHPMailer).

If you prefer to use PHP's `mail()` function,
you'll need to configure SMTP using the following environment variables in your container:

| Environment Variable | Description | Example Value |
|----------------------|-------------------------------------------------|----------------------|
| `SMTP_HOST` | The hostname or IP address of the SMTP server. | `smtp.gmail.com` |
| `SMTP_PORT` | Port number used to connect to the SMTP server. | `587` |
| `SMTP_LOG` | File path to store SMTP email logs. | `/path/to/email.log` |
| `SMTP_FROM` | The sender's email address. | `admin@example.com` |
| `SMTP_USER` | Username used for SMTP authentication. | `your_smtp_username` |
| `SMTP_PASSWORD` | Password used for SMTP authentication. | `your_smtp_password` |
| `SMTP_AUTH` | Whether SMTP authentication is required. | `on` |
| `SMTP_TLS` | Whether to use TLS for secure connection. | `on` |

> ๐Ÿ’ก Hint: If you don't have an SMTP server available (like Gmail) to send emails,
> you can try using another container such as [Mailpit](https://hub.docker.com/r/axllent/mailpit) to act as an SMTP server.
>
> If you're using Mailpit, you only need to set the following two environment variables
> in your container: `SMTP_HOST=mailpit` and `SMTP_PORT=1025`.

## Debug Mode

Enable "debug mode" for more verbose logging by setting `DEBUG=1` as an environment variable.
This can be used both with `docker run` and in `docker-compose.yml`.

#### Command Line

```shell
docker run -e DEBUG=1 shinsenter/php:8.5-fpm-nginx
```

#### With docker-compose.yml

```yml
services:
web:
image: shinsenter/php:8.5-fpm-nginx
environment:
DEBUG: "1"
```

## Other System Settings

These Docker images include additional environment variables for fine-tuning container behavior:

| Setting Name | Default Value | Description | Example |
|------------------------------------|------------------|-----------------------|---------|
| `DEFAULT_LOG_PATH` | `/proc/1/fd/2` | Specifies where logs are written. By default, logs are sent to the containerโ€™s standard output. | `/var/log/container.txt` |
| `DEBUG` or `DEBUG_MODE` | Not set | Enables verbose logging when set to `1`. | `1` |
| `TZ` | `UTC` | Sets the containerโ€™s default timezone. See the [full list of timezones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). | `Asia/Tokyo` |
| `ALLOW_RUNTIME_PHP_ENVVARS` | Not set | Allows `$PHP_*` environment variables to override PHP configurations at runtime. | `1` |
| `INITIAL_PROJECT` | Not set | Specifies the Composer project to create if the application directory is empty.
โ€ป If the value is a URL ending in `*.zip`, `*.tar.gz` or `*.git`, the container will download and extract the archive to the application directory. | `laravel/laravel` |
| `INITIAL_PROJECT_GIT_OPTIONS` | Not set | The parameter will be passed to the `git clone` command if `$INITIAL_PROJECT` is set and is a URL ending with `.git`. | `-b develop` |
| `DISABLE_AUTORUN_SCRIPTS` | Not set | Disables all autorun scripts when set to `1`. | `1` |
| `DISABLE_AUTORUN_CREATING_PROJECT` | Not set | Prevents automatic project creation when set to `1`. By default, Composer will create a project if `$INITIAL_PROJECT` is set and the application directory is empty. | `1` |
| `DISABLE_AUTORUN_COMPOSER_INSTALL` | Not set | Skips `composer install` during startup when set to `1`. By default, the command runs if `composer.json` exists but dependencies are missing. | `1` |
| `DISABLE_AUTORUN_GENERATING_INDEX` | Not set | Skips creation of `index.php` when set to `1`. By default, an `index.php` file is generated in `$DOCUMENT_ROOT` if it doesn't already exist. | `1` |
| `DISABLE_AUTORUN_FIX_OWNER_GROUP` | Not set | Disables automatic correction of ownership for the application directory when set to `1`. | `1` |
| `DISABLE_GREETING` | Not set | Suppresses the startup greeting message when set to `1`. | `1` |
| `COMPOSER_OPTIMIZE_AUTOLOADER` | Not set | When set to `1`, enables Composer's optimized autoloader (`--optimize-autoloader`) during install, improving performance in production. | `1` |
| `ENABLE_SSHD` | Not set | When set to `1`, enable the SSH server inside the container. | `1` |
| `SSHD_AUTHORIZED_KEYS` | Not set | Public SSH keys (one per line) that will be added to the container's `~/.ssh/authorized_keys` for authentication. | `ssh-rsa XXXX...` |
| `ENABLE_CRONTAB` | Not set | Enables the Crontab service when set to `1`, loading job definitions from `$CRONTAB_DIR` (default: `/etc/crontab.d`). | `1` |
| `ENABLE_CRONTAB_DEBUG` | Not set | When set to `1`, adds a debug cron job that runs every minute and prints environment variables visible to cron. | `1` |
| `CRONTAB_DIR` | `/etc/crontab.d` | Directory where cron job definitions are located. Jobs run as the user specified in `$APP_USER`. | `/path/for/crontab/schedules` |
| `CRONTAB_HOME` | `$APP_PATH` | Sets the `$HOME` directory used during cron job execution. | `/path/for/crontab` |
| `CRONTAB_MAILTO` | Not set | Email address to receive cron job output. | `admin@example.com` |
| `CRONTAB_PATH` | `$PATH` | Defines the executable search path used by cron jobs. | `/path/for/crontab/bin` |
| `CRONTAB_SETTINGS` | Not set | Allows defining cron jobs directly in `docker-compose.yml`, making it easy to manage scheduled tasks inside the container. | `0 0 * * * echo "Hello new day!"` |
| `CRONTAB_SHELL` | `/bin/sh` | Specifies the default shell used for cron job execution. | `/bin/bash` |
| `CRONTAB_TZ` | `$TZ` | Sets the timezone for cron jobs. See the [full list of timezones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones). | `Asia/Tokyo` |
| `SUPERVISOR_PHP_COMMAND` | Not set | Overrides the containerโ€™s default entrypoint with a custom PHP command to serve the application. | `php -S localhost:80 index.php` |
| `ENABLE_TUNING_FPM` | Not enabled | Enables automatic tuning of PHP-FPM settings when set to `1`. | `1` |
| `ENABLE_TUNING_MPM` | Not enabled | Enables automatic tuning of Apache MPM settings when set to `1`. | `1` |

## Supported Platforms

Check our [Docker Hub](https://hub.docker.com/r/shinsenter/php/tags) for all available platforms. The Docker images are available for both Debian and Alpine versions.

## Stable Image Tags

For stable versions (with date tagged) you can depend on in production,
we also apply version tags on another repository.

> ๐Ÿ‘‰๐Ÿป View Stable Tags: https://hub.docker.com/r/shinsenter/php-archives/tags

## Contributing

If you find these images useful, consider donating via [PayPal](https://www.paypal.me/shinsenter)
or opening an issue on [GitHub](https://code.shin.company/php/issues/new).

Your support helps maintain and improve these images for the community.

## License

This project is licensed under the terms of the [GNU General Public License v3.0](https://code.shin.company/php/blob/main/LICENSE).

Please respect the intellectual efforts involved in creating these images.
If you intend to copy or use ideas from this project, proper credit is appreciated.

---

From Vietnam ๐Ÿ‡ป๐Ÿ‡ณ with love.