A battle-tested, production-grade Docker template combining Nginx and PHP-FPM on Alpine Linux. Engineered for security, performance, and developer productivity with zero-configuration deployment and enterprise-grade defaults.
- Alpine Linux - Minimal footprint (~50MB base image)
- PHP-FPM - Optimized with opcache, APCu, and performance tuning
- Nginx - Hardened configuration with security headers
- Supervisor - Process management with auto-restart
- Tini - Proper init system for graceful shutdowns
- Health Checks - Built-in endpoints for monitoring
- Non-root runtime - Container runs as unprivileged
appuser, reducing attack surface - Locked-down defaults - Nginx hides server details, security headers applied
- Minimal Alpine base - Smaller attack surface, fewer vulnerabilities to patch
- Security headers - X-Frame-Options, X-Content-Type-Options, X-XSS-Protection enabled
- Tuned opcache - Pre-configured for speed with sensible caching defaults
- Unix socket communication - PHP-FPM and Nginx communicate via socket (faster than TCP)
- Gzip compression - Built-in compression for faster response times
- Browser caching - Optimized cache headers for static assets
- Fast startup - Lightweight Alpine base means quick container spin-up (<3s)
- Multiple PHP versions - Pre-built images for PHP 7.4, 8.1, 8.2, 8.3, 8.4
- Easy customization - Override PHP settings via environment variables or
.envfile - Version-locked Alpine - Each PHP version paired with compatible Alpine release
- Common extensions included - mysqli, pdo_mysql, gd, curl, zip, mbstring, opcache, and more
- Zero configuration - Just run
docker compose upand start coding - Health endpoints - Built-in
/fpm-pingand/fpm-statusfor monitoring - Sample dashboard - Included PHP info page to verify configuration
- CI/CD ready - GitHub Actions workflow included for automated builds
- Hot reload - Mount your code and see changes instantly
- Graceful shutdowns - Tini init system handles signals properly
- Supervised processes - Supervisor manages nginx + php-fpm, auto-restarts on failure
- Health checks - Docker health checks ensure container is responding
- Detailed logging - Structured logs for debugging and monitoring
- Clear documentation - Comprehensive troubleshooting guide included
services:
app:
build: .
image: ghcr.io/nooblk-98/php-nginx:latest
ports:
- "80:80"# permissions for files
chown -R www-data:www-data /var/www/html# Start the container
docker compose up -d# View logs
docker compose logs -f# Visit your application
open http://localhostdocker run -d \
--name php-nginx \
-p 80:80 \
-v $(pwd)/src:/var/www/html \
lahiru98s/php-nginx-docker-template:8.3# Docker Hub
docker pull lahiru98s/php-nginx-docker-template:8.3
# GitHub Container Registry
docker pull ghcr.io/nooblk-98/php-nginx-docker-template:8.3| PHP Version | Alpine Version | Image Tag | Status |
|---|---|---|---|
| 8.4 | edge | 8.4, latest |
β Stable |
| 8.3 | 3.20 | 8.3 |
β Stable |
| 8.2 | 3.20 | 8.2 |
β Stable |
| 8.1 | 3.18 | 8.1 |
β Stable |
| 7.4 | 3.15 | 7.4 |
Dockerfile locations:
- PHP 7.4: php74/Dockerfile
- PHP 8.1: php81/Dockerfile
- PHP 8.2: php82/Dockerfile
- PHP 8.3: php83/Dockerfile
- PHP 8.4: php84/Dockerfile
# Default: PHP 8.3 on Alpine 3.20
docker build -t php-nginx:8.3 .# Build PHP 8.2 on Alpine 3.19
docker build \
-t php-nginx:8.2 \
--build-arg PHP_VERSION=82 \
--build-arg ALPINE_VERSION=3.19 \
.# Build from version-specific Dockerfile
docker build -t php-nginx:8.4 -f php84/Dockerfile .The docker-compose.yml mounts configs.php_overrides into /etc/php${PHP_VERSION}/conf.d/99-overrides.ini.
services:
app:volumes:
- ./src:/var/www/html # Your application code
- ./nginx/nginx.conf:/etc/nginx/nginx.conf # Custom nginx config
- ./php/php.ini:/etc/php83/php.ini # Custom PHP config- FPM Ping:
http://localhost/fpm-ping- Returnspongif PHP-FPM is healthy - FPM Status:
http://localhost/fpm-status- Detailed PHP-FPM pool statistics
# Check container health
docker inspect --format='{{.State.Health.Status}}' php-nginx
# View health check logs
docker inspect --format='{{json .State.Health}}' php-nginx | jq# View all logs
docker compose logs -f
# View specific service
docker logs php-nginx
# Nginx access logs
docker exec php-nginx tail -f /var/log/nginx/access.log
# PHP-FPM logs
docker exec php-nginx tail -f /var/log/php-fpm/error.logSolution: Use the Alpine release that ships that PHP minor version.
- PHP 8.1 β Alpine 3.18
- PHP 8.2 β Alpine 3.20
- PHP 8.3 β Alpine 3.20
- PHP 8.4 β Alpine edge
docker build --build-arg PHP_VERSION=81 --build-arg ALPINE_VERSION=3.18 .Solution: Ensure mounts are writable by the app user (UID 1000).
# On host
chown -R 1000:1000 ./src
# Or in docker-compose.yml
services:
app:
user: "1000:1000"Solution: Enable buildx cache in GitHub Actions.
- name: Build and push
uses: docker/build-push-action@v5
with:
cache-from: type=gha
cache-to: type=gha,mode=maxSolution: Verify PHP-FPM socket and nginx configuration.
# Check if socket exists
docker exec php-nginx ls -la /run/php/php-fpm.sock
# Test ping endpoint
docker exec php-nginx curl -f http://localhost/fpm-ping
# Check nginx config
docker exec php-nginx nginx -tSolution: Check PHP error logs and permissions.
# Enable error display temporarily
docker exec php-nginx sed -i 's/display_errors = Off/display_errors = On/' /etc/php83/php.ini
docker exec php-nginx supervisorctl restart php-fpm
# Check logs
docker exec php-nginx tail -f /var/log/php-fpm/error.log- nginx.conf - Nginx global settings
- default.conf - Server block configuration
- php.ini - PHP runtime settings
- fpm-pool.conf - PHP-FPM pool configuration
- supervisord.conf - Process supervision
We welcome contributions! Please follow these steps:
-
Fork the repository
gh repo fork nooblk-98/php-nginx-docker-template
-
Create a feature branch
git checkout -b feature/amazing-feature
-
Make your changes
- Follow existing code style
- Update documentation if needed
- Test your changes thoroughly
-
Commit your changes
git commit -m "feat: add amazing feature" -
Push to your fork
git push origin feature/amazing-feature
-
Open a Pull Request
- Describe your changes clearly
- Reference any related issues
- Test with multiple PHP versions
- Ensure security best practices
- Update README for new features
- Add comments for complex configurations
- Run shellcheck on scripts
This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0). See LICENSE for full details.
- Built with Alpine Linux
- Powered by Nginx and PHP-FPM
- Process management by Supervisor
- Init system by Tini
Made with β€οΈ by NoobLK
