shinsenter/php

Sponsored OSS

By SHIN Company

Updated about 1 hour ago

📦 Simplified PHP Docker images for effortless customization and extension setup.

Image
Languages & frameworks
Developer tools
Web servers
34

1M+

shinsenter/php repository overview

PHP Docker Images

📦 Lightweight PHP Docker images designed for easy customization and simple extension management.

Our images support PHP versions from 5.6 up to 8.6 (RC), with variants for CLI, ZTS, FPM, FPM/Apache, FPM/Nginx, RoadRunner, and FrankenPHP. Images are available for both Debian and Alpine.

Daily build

Table of Contents

Introduction

shinsenter/php

These images are based on the official PHP Docker images and make it easy to change PHP and PHP-FPM settings using environment variables. No image rebuild required.

They include Composer (the latest version) and common web servers such as Apache2, Nginx, RoadRunner, and FrankenPHP. This helps you start projects faster without extra installs.

🪶 Note: While based on the official images and including useful extensions, we have significantly reduced the image sizes to improve download times and resource usage, using the docker-squash project.

Docker Image Variants

Tags cover PHP versions from 5.6 to 8.6-rc and come in cli, zts, fpm, fpm-nginx, fpm-apache, roadrunner(1), and frankenphp(2) variants. Both Debian and Alpine builds are available.

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) RoadRunner variant — requires PHP >= 8.0.
(2) FrankenPHP variant is BETA — requires PHP >= 8.2.

See all tags on our Docker Hub.

Examples

Run a container using one of these commands:

CLI
# 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
docker run -v ./myproject:/var/www/html -p 9000:9000 shinsenter/php:8.5-fpm
PHP-FPM + Nginx (or Apache, RoadRunner, FrankenPHP)
# 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

You can configure PHP and PHP-FPM using environment variables instead of rebuilding images.

Naming rules:

By following this convention you can quickly identify the environment variable that maps to each configuration directive.

👉🏻 Note: By default, $PHP_* variables are applied only if set before the container starts. To allow changing PHP settings from an interactive shell inside a running container, start the container with ALLOW_RUNTIME_PHP_ENVVARS=1.

💡 Tip: Run php-envvars inside the container to list the default $PHP_* variables.

Examples
Command Line
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
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 VariableWhat it doesEquivalent php.ini / fpm setting
PHP_DISPLAY_ERRORS=1Show errors during developmentdisplay_errors = 1
PHP_POST_MAX_SIZE=100MSet max POST size (default 8M)post_max_size = 100M
PHP_UPLOAD_MAX_FILESIZE=100MSet max upload file size (default 2M)upload_max_filesize = 100M
PHP_SESSION_COOKIE_HTTPONLY=1Enable HttpOnly on session cookiessession.cookie_httponly = 1

💡 Tip: Run php-envvars in the container to get a full list of default $PHP_* environment variables.

Pre-installed PHP Extensions

Common PHP extensions are pre-installed so projects can start quickly.

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

👉🏻 Note: Extensions that are already included in the official PHP images are not listed here.

💡 Tip: Run docker run --rm shinsenter/php:8.5-cli php -m (replace 8.5 as needed) to see installed extensions.

Adding PHP Extensions

Use the phpaddmod helper to install extensions easily.

You do not need to use docker-php-ext-install or manually edit php.ini — phpaddmod installs and configures extensions for you.

Example 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/

👉🏻 Note: phpaddmod is a wrapper around the mlocati/docker-php-extension-installer, which handles compiling and enabling extensions.

Application Directory

Default application directory: /var/www/html. Change it with $APP_PATH:

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

To change the document root (a path inside $APP_PATH that contains index.php), set $DOCUMENT_ROOT:

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 example sets the document root to /app/public.

Customizing Container User and Group in Docker

Override the default user and group with environment variables:

Environment VariableDescriptionDefault
APP_USERUsername inside the containerwww-data
APP_GROUPGroup name inside the containerwww-data
APP_UIDNumeric UID for the userUID in container
APP_GIDNumeric GID for the groupGID in container

Example (run as user myapp with UID 5000):

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

docker-compose example:

services:
  web:
    image: shinsenter/php:8.5-fpm-nginx
    environment:
      APP_USER: "myapp"
      APP_UID: "5000"

Hooks

Hooks let you customize runtime behavior. Create a hooks folder inside $APP_PATH and place executable files named after each hook (or use subfolders).

Supported hooks:

Hook nameWhen it runsExample use
onbootAt container start or restartSend startup notification
first-runOnly the first time the container startsInitialize database
rebootedEvery container restartCheck crash logs
migrationRun database migrationsApply DB migrations
onreadyAfter migration, when the app is almost readyWarm up caches
onliveAfter the web server starts (if included)Trigger a webhook

Example: To install PHP modules on first run, add hooks/first-run or hooks/first-run/install-modules.

Enable DEBUG=1 to see which hooks run.

Autorun Scripts

Place shell scripts in /startup/ to run automatically when the container starts. Scripts run in alphabetical order by filename.

Example Dockerfile to add an autorun script:

Ensure the script is executable.

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/

👉🏻 Note: The startup directory includes 99-greeting, which prints a welcome message at startup.

Disable Autorun Scripts

To disable autorun scripts, set DISABLE_AUTORUN_SCRIPTS=1:

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

Or in docker-compose:

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

Using Cron Jobs

This project supports simple cron jobs. For advanced cron features, consider building a custom image.

Enable cron with ENABLE_CRONTAB=1. The service loads jobs from $CRONTAB_DIR (default: /etc/crontab.d) and runs them as $APP_USER:$APP_GROUP (default www-data:www-data), with $CRONTAB_HOME (default: /var/www/html) as the home directory.

Example Dockerfile to add a crontab:

FROM shinsenter/php:latest

ENV ENABLE_CRONTAB=1

# create crontab entry via RUN instruction
RUN 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/

Crontab entry format:

# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,...
# |  |  |  |  .---- day of week (0 - 6) OR sun,mon,...
# |  |  |  |  |
# *  *  *  *  *  command to be executed

You can set cron jobs directly via the CRONTAB_SETTINGS environment variable in docker-compose:

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 cron-related environment variables, see Other System Settings.

Customize Supervisor Command

Set SUPERVISOR_PHP_COMMAND to override the default command used by the supervisor process. This lets you run a different command to serve your app.

Command line example:

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

docker-compose example:

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

Sending Emails

We use msmtp as a lightweight sendmail replacement. You can send mail with libraries like PHPMailer.

To use PHP's mail() function, configure SMTP via these environment variables:

Environment VariableDescriptionExample Value
SMTP_HOSTSMTP server hostname or IPsmtp.gmail.com
SMTP_PORTSMTP port587
SMTP_LOGPath to SMTP log file/path/to/email.log
SMTP_FROMSender email address[email protected]
SMTP_USERSMTP usernameYour smtp username
SMTP_PASSWORDSMTP passwordYour smtp password
SMTP_AUTHEnable SMTP authentication (on/off)on
SMTP_TLSUse TLS for the connection (on/off)on

💡 Tip: If you don't have an SMTP server, try using a local SMTP container like Mailpit. With Mailpit, set SMTP_HOST=mailpit and SMTP_PORT=1025 in your container.

Debug Mode

Enable verbose logging by setting DEBUG=1 when starting the container.

Command line:

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

docker-compose:

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

Other System Settings

Additional environment variables for fine-tuning container behavior:

Setting NameDefault ValueDescriptionExample
DEFAULT_LOG_PATH/proc/1/fd/2Where logs are written. By default, logs are sent to the container's stdout./var/log/container.txt
DEBUG or DEBUG_MODENot setEnable verbose logging when set to 1.1
TZUTCSet the container's timezone. See the list of timezones.Asia/Tokyo
ALLOW_RUNTIME_PHP_ENVVARSNot setAllow $PHP_* variables to override PHP configuration at runtime.1
INITIAL_PROJECTNot setComposer project to create if the app directory is empty. If this is a URL ending in .zip, .tar.gz, or similar, the archive will be downloaded and extracted.https://example.com/project.zip
INITIAL_PROJECT_GIT_OPTIONSNot setOptions passed to git clone when INITIAL_PROJECT is a .git URL.-b develop
DISABLE_AUTORUN_SCRIPTSNot setSet to 1 to disable autorun scripts.1
DISABLE_AUTORUN_CREATING_PROJECTNot setPrevent automatic project creation when set to 1.1
DISABLE_AUTORUN_COMPOSER_INSTALLNot setSkip running composer install during startup when set to 1.1
DISABLE_AUTORUN_GENERATING_INDEXNot setDo not generate index.php when set to 1.1
DISABLE_AUTORUN_FIX_OWNER_GROUPNot setDo not automatically fix ownership of the application directory when 1.1
DISABLE_GREETINGNot setSuppress the startup greeting with 1.1
COMPOSER_OPTIMIZE_AUTOLOADERNot setWhen 1, run Composer with --optimize-autoloader for production installs.1
ENABLE_SSHDNot setEnable SSH server inside the container when 1.1
SSHD_AUTHORIZED_KEYSNot setPublic SSH keys to add to ~/.ssh/authorized_keys (one per line).ssh-rsa AAAA...
ENABLE_CRONTABNot setEnable Crontab service when 1. Jobs are loaded from $CRONTAB_DIR.1
ENABLE_CRONTAB_DEBUGNot setAdds a debug cron job that runs every minute when 1.1
CRONTAB_DIR/etc/crontab.dDirectory for crontab definitions. Jobs run as $APP_USER./path/for/crontab/schedules
CRONTAB_HOME$APP_PATHHome directory for cron jobs./path/for/crontab
CRONTAB_MAILTONot setEmail address to receive cron output.[email protected]
CRONTAB_PATH$PATHExecutable search path used by cron jobs./path/for/crontab/bin
CRONTAB_SETTINGSNot setDefine cron jobs directly via environment variable.0 0 * * * echo "..."
CRONTAB_SHELL/bin/shDefault shell for cron jobs./bin/bash
CRONTAB_TZ$TZTimezone used for cron jobs.Asia/Tokyo
SUPERVISOR_PHP_COMMANDNot setOverride the PHP command used by supervisor.php -S localhost:80 index.php
ENABLE_TUNING_FPMNot enabledEnable automatic tuning of PHP-FPM settings when set to 1.1
ENABLE_TUNING_MPMNot enabledEnable automatic tuning of Apache MPM settings when set to 1.1

Supported Platforms

See our Docker Hub for available platforms. Images are built for both Debian and Alpine variants.

Stable Image Tags

For stable, production-ready images we maintain dated tags in a separate repository.

Contributing

If you find these images useful, consider donating via PayPal or open an issue on GitHub.

Your support helps maintain and improve these images for everyone.

License

This project is licensed under the GNU General Public License v3.0.

Please respect the work that went into these images. If you reuse ideas from this project, credit is appreciated.


From Vietnam 🇻🇳 with love.

Tag summary

Content type

Image

Digest

sha256:607406e22

Size

89.7 MB

Last updated

about 1 hour ago

docker pull shinsenter/php:dev-8.1

This week's pulls

Pulls:

24,177

Jul 27 to Aug 2