Modernize images and move PHP 8.1 to legacy
Tests / integration (8.2, alpine) (push) Canceled after 0s
Tests / integration (8.2, debian) (push) Canceled after 0s
Tests / integration (8.3, alpine) (push) Canceled after 0s
Tests / integration (8.3, debian) (push) Canceled after 0s
Tests / integration (8.4, alpine) (push) Canceled after 0s
Tests / integration (8.4, debian) (push) Canceled after 0s
Tests / integration (8.5, alpine) (push) Canceled after 0s
Tests / integration (8.5, debian) (push) Canceled after 0s

PHP 8.1 is end-of-life. It is dropped from the default build and test
matrices. 8.1 and 8.1-alpine are still built, multi-arch, by the
manual legacy job (workflow_dispatch with legacy=true), together with
7.2, 7.3, 7.4 and 8.0. This replaces manual-build.yml.
This commit is contained in:
jkaninda committed 2026-10-22 05:30:34 +02:00
1 parent c602e1a0ad
commit 5abd5bc076
24 files changed
+857 -595

No files matched your search

+153 -74
View File
@@ -10,13 +10,15 @@ A **ready-to-use container** designed for running PHP-based applications, includ
#### **Features**
- **PHP Application Support**: Optimized to run Laravel or any PHP-based applications.
- **Nginx and PHP-FPM in one container**, managed by Supervisord.
- **Integrated Extensions**:
- **Database**: MySQL and PostgreSQL.
- **Caching**: Redis and Memcached.
- **Messaging**: Kafka for event-driven architecture.
- **Task Scheduling**: Laravel Scheduler and Cron jobs support.
- **Custom Configuration**: Pre-configured with sensible defaults, allowing seamless customization.
- **Event Handling**: Support for advanced event-driven processes.
- **Task Scheduling**: Laravel Scheduler and Queue Worker started automatically.
- **Custom Configuration**: Pre-configured with sensible defaults, tunable through environment variables.
- **Debian and Alpine variants**, multi-arch (`linux/amd64`, `linux/arm64`).
- **Production-ready**: healthcheck, graceful shutdown, OPcache, logs on stdout, `supervisorctl` support.
- **Optimized for Microservices**: Built with modern PHP microservices in mind.
This image is ideal for developers looking for a streamlined, high-performance solution to deploy PHP applications with essential tools already integrated.
@@ -26,35 +28,47 @@ This image is ideal for developers looking for a streamlined, high-performance s
- [Docker Hub](https://hub.docker.com/r/jkaninda/nginx-php-fpm)
- [GitHub Repository](https://github.com/jkaninda/nginx-php-fpm)
## **Supported PHP Versions**
- 8.4
- 8.3
- 8.2
- 8.1
- 8.0
- 7.4
- 7.2
## **Supported PHP Versions & Tags**
## **Specifications**
This Docker image comes pre-installed with the following:
- **PHP Extensions**:
- Composer
- OpenSSL
- XML
- PDO
- Rdkafka
- Redis
- Mbstring
- PCNTL
- ZIP
- GD
- BCMath
- Memcached
| PHP | Debian tag | Alpine tag |
|-----|------------|------------|
| 8.5 | `8.5`, `latest` | `8.5-alpine`, `alpine` |
| 8.4 | `8.4` | `8.4-alpine` |
| 8.3 | `8.3` | `8.3-alpine` |
| 8.2 | `8.2` | `8.2-alpine` |
- **Additional Features**:
- Laravel Cron Jobs & Scheduler
- Supervisord
- Node.js & NPM
Legacy images (PHP is end-of-life, no longer rebuilt automatically or tested): `8.1`, `8.1-alpine`, `8.0`, `7.4`, `7.3`, `7.2`.
---
## **Specifications**
### **PHP Extensions**
- Composer 2
- OpenSSL
- XML
- PDO (MySQL, PostgreSQL and SQLite)
- Rdkafka
- Redis
- Mbstring
- Intl
- Exif
- PCNTL
- ZIP
- GD (FreeType, JPEG, PNG, WebP)
- BCMath
- Memcached
- Opcache
### **Additional Features**
- Nginx
- Laravel Scheduler
- Laravel Queue Worker
- Supervisord
- Node.js 24 LTS and NPM
- Git, Zip/Unzip, SQLite CLI
---
## **Basic Usage with Docker Compose**
@@ -62,17 +76,14 @@ This Docker image comes pre-installed with the following:
```yaml
services:
app:
image: jkaninda/nginx-php-fpm:8.3
image: jkaninda/nginx-php-fpm:8.5
container_name: app
restart: unless-stopped
user: www-data # Optional for production
volumes:
# Project root
- ./src:/var/www/html
ports:
- "80:80"
networks:
- default
```
### **Commands**
@@ -84,27 +95,27 @@ docker compose up -d
#### Create a new Laravel project:
```sh
docker compose exec app composer create-project --prefer-dist laravel/laravel .
docker compose exec -u www-data app composer create-project --prefer-dist laravel/laravel .
```
#### Generate application key:
```sh
docker compose exec app php artisan key:generate
docker compose exec -u www-data app php artisan key:generate
```
#### Create a storage symlink:
```sh
docker compose exec app php artisan storage:link
docker compose exec -u www-data app php artisan storage:link
```
#### Fix storage and cache permissions:
```sh
docker compose exec app chmod -R 777 storage bootstrap/cache
docker compose exec app chown -R www-data:www-data storage bootstrap/cache
```
#### Run Laravel migrations:
```sh
docker compose exec app php artisan migrate
docker compose exec -u www-data app php artisan migrate
```
#### Access the container shell:
@@ -112,37 +123,91 @@ docker compose exec app php artisan migrate
docker exec -it app bash
```
#### Run a one-off command (Nginx and PHP-FPM are not started):
```sh
docker run --rm -v "$PWD:/var/www/html" jkaninda/nginx-php-fpm composer install
```
#### Restart the queue workers after a deployment:
```sh
docker compose exec app supervisorctl restart Laravel-worker:*
```
---
## **Advanced Nginx PHP-FPM Setup**
## **Environment Variables**
### Nginx
| Variable | Default | Description |
|----------|---------|-------------|
| `DOCUMENT_ROOT` | `$APP_DIR/public` if it exists, otherwise `$APP_DIR` | Nginx web root |
| `DOMAIN` | `_` | Nginx `server_name` |
| `CLIENT_MAX_BODY_SIZE` | `15M` | Nginx `client_max_body_size` |
### Laravel
| Variable | Default | Description |
|----------|---------|-------------|
| `LARAVEL_SCHEDULER_ENABLED` | `true` | Run `php artisan schedule:run` every minute |
| `LARAVEL_QUEUE_WORKER_ENABLED` | `true` | Run `php artisan queue:work` |
| `LARAVEL_QUEUE_OPTIONS` | `--sleep=3 --tries=3` | Options passed to `queue:work` (e.g. `redis --queue=high,default`) |
| `LARAVEL_PROCS_NUMBER` | `1` | Number of queue worker processes |
| `APP_DIR` | `/var/www/html` | Application directory (where `artisan` is looked up) |
The scheduler and queue worker are only started when an `artisan` file is found in `APP_DIR`.
### PHP
| Variable | Default |
|----------|---------|
| `PHP_MEMORY_LIMIT` | `256M` |
| `PHP_UPLOAD_MAX_FILESIZE` | `80M` |
| `PHP_POST_MAX_SIZE` | `80M` |
| `PHP_MAX_EXECUTION_TIME` | `30` |
| `PHP_DATE_TIMEZONE` | `UTC` |
| `PHP_DISPLAY_ERRORS` | `Off` |
### OPcache
| Variable | Default | Description |
|----------|---------|-------------|
| `PHP_OPCACHE_ENABLE` | `1` | |
| `PHP_OPCACHE_ENABLE_CLI` | `0` | |
| `PHP_OPCACHE_MEMORY_CONSUMPTION` | `512` | MB |
| `PHP_OPCACHE_MAX_ACCELERATED_FILES` | `50000` | |
| `PHP_OPCACHE_VALIDATE_TIMESTAMPS` | `0` | Set to `1` in development so code changes are picked up |
| `PHP_OPCACHE_REVALIDATE_FREQ` | `0` | |
### PHP-FPM
| Variable | Default |
|----------|---------|
| `PHP_FPM_PM` | `dynamic` |
| `PHP_FPM_PM_MAX_CHILDREN` | `20` |
| `PHP_FPM_PM_START_SERVERS` | `2` |
| `PHP_FPM_PM_MIN_SPARE_SERVERS` | `1` |
| `PHP_FPM_PM_MAX_SPARE_SERVERS` | `3` |
| `PHP_FPM_PM_MAX_REQUESTS` | `500` |
Container environment variables (e.g. `DB_HOST`, `APP_KEY`) are passed to PHP-FPM workers (`clear_env = no`).
### Development example
### **Extended `docker-compose.yml` Example**
```yaml
version: '3'
services:
app:
image: jkaninda/nginx-php-fpm
container_name: app
restart: unless-stopped
image: jkaninda/nginx-php-fpm:8.5
ports:
- "80:80"
volumes:
# Project root
- ./:/var/www/html
- ~/.ssh:/root/.ssh # Use private CVS if needed
# Optional custom PHP config
# - ./php.ini:/usr/local/etc/php/conf.d/php.ini
environment:
- APP_ENV=development # or production
- LARAVEL_PROCS_NUMBER=2 # Optional: Queue worker processes
# - CLIENT_MAX_BODY_SIZE=20M # Optional
# - DOMAIN=example.com # Optional
- DOCUMENT_ROOT=/var/www/html # Optional
```
### **Default Web Root**
```
/var/www/html
PHP_OPCACHE_VALIDATE_TIMESTAMPS: 1
PHP_DISPLAY_ERRORS: "On"
CLIENT_MAX_BODY_SIZE: 20M
LARAVEL_QUEUE_OPTIONS: "redis --sleep=3 --tries=3"
LARAVEL_PROCS_NUMBER: 2
volumes:
- ./:/var/www/html
```
---
@@ -151,7 +216,7 @@ services:
### **Dockerfile**
```Dockerfile
FROM jkaninda/nginx-php-fpm:8.3
FROM jkaninda/nginx-php-fpm:8.5
# Copy Laravel project files
COPY . /var/www/html
# Storage Volume
@@ -161,23 +226,32 @@ WORKDIR /var/www/html
# Fix permissions
RUN chown -R www-data:www-data /var/www/html
USER www-data
```
---
## **Custom Nginx Configuration**
To enable custom Nginx configurations, use the following files:
- `/var/www/html/conf/nginx/nginx.conf`
- `/var/www/html/conf/nginx/nginx-site.conf`
To use custom Nginx configurations, add the following files to your project:
- `conf/nginx/nginx.conf`: replaces `/etc/nginx/nginx.conf`
- `conf/nginx/nginx-site.conf`: replaces the generated server block. PHP-FPM listens on `127.0.0.1:9000`.
---
## **Custom PHP Configuration**
Most common settings can be changed with [environment variables](#environment-variables).
For anything else, either:
- mount or copy your own `.ini` file into `/usr/local/etc/php/conf.d/`, or
- place a `php.ini` file at `conf/php/php.ini` in your project; it is copied into `conf.d` at startup.
---
## **Supervisord Integration**
Supervisord can be used to manage tasks or processes within the container.
Place your programs in `conf/worker/supervisor.conf` in your project, or mount them into `/etc/supervisor/conf.d/`.
### **Example Configuration for Kafka Consumer**
```conf
@@ -196,16 +270,23 @@ stdout_logfile=/var/www/html/storage/logs/kafka.log
## **Fixing Storage Permissions**
If you encounter storage permission issues, run the following commands:
`www-data` has UID/GID `1000` in both Debian and Alpine variants. If you encounter permission issues, run:
```sh
docker compose exec php-fpm /bin/bash
docker compose exec app chown -R www-data:www-data /var/www/html/storage /var/www/html/bootstrap/cache
docker compose exec app chmod -R 775 /var/www/html/storage
```
Then inside the container:
To match your host user, rebuild with `--build-arg USER_ID=$(id -u) --build-arg GROUP_ID=$(id -g)`.
---
## **Building & Testing Locally**
```sh
chown -R www-data:www-data /var/www/html/
chmod -R 775 /var/www/html/storage
make build-8.5 # Debian image
make build-8.5-alpine # Alpine image
make test # Integration test (Laravel + MySQL)
```
---
@@ -236,5 +317,3 @@ Whether you're managing internal APIs or exposing public endpoints, **Goma Gatew
## ⭐️ **Support the Project**
If this project helped you, do not skip on giving it a star. Thanks!