Quick start
Run a PHP script
The php image is a CLI image. Its entrypoint renders php.ini from your environment and then runs whatever command you pass.
docker run --rm adamrollogi/php:8.4 php -v
docker run --rm -v $(pwd):/app -w /app adamrollogi/php:8.4 php artisan migrate
docker run --rm -v $(pwd):/app -w /app adamrollogi/php:8.4 composer install
Serve an application over HTTP
php-nginx runs Nginx and PHP-FPM together. Containers run as an unprivileged user by default, so bind to a port above 1024.
docker run --rm -d -p 8080:8080 \
-e NGINX_PORT=8080 \
-v $(pwd)/public:/var/www/html:ro \
adamrollogi/php-nginx:8.4
/health returns 200 OK and is what the built-in Docker health check uses.
curl -sf http://localhost:8080/health
phpinfo(), so a misconfigured deployment cannot leak environment variables.HTTPS with a self-signed certificate
Useful for local development or behind a load balancer that re-encrypts.
docker run --rm -d -p 8080:8080 -p 8443:8443 \
-e NGINX_PORT=8080 \
-e NGINX_SSL_ENABLED=true \
-e NGINX_SSL_PORT=8443 \
-e NGINX_SSL_SELF_SIGNED=true \
-v $(pwd)/public:/var/www/html:ro \
adamrollogi/php-nginx:8.4
Plain HTTP on 8080 redirects to HTTPS on 8443, except for /health and ACME challenges under /.well-known/.
HTTPS with your own certificate
Mount the certificate and key read-only. Running as root here only so that ports 80 and 443 can be bound.
docker run --rm -d -p 80:80 -p 443:443 --user root \
-e NGINX_SSL_ENABLED=true \
-e NGINX_SERVER_NAME=app.example.com \
-v /path/to/cert.pem:/etc/nginx/ssl/cert.pem:ro \
-v /path/to/key.pem:/etc/nginx/ssl/key.pem:ro \
-v $(pwd)/public:/var/www/html:ro \
adamrollogi/php-nginx:8.4
Set NGINX_SERVER_NAME so the HTTP to HTTPS redirect targets your hostname rather than whatever Host header a client sends. See SSL and HTTPS.
Docker Compose
services:
app:
image: adamrollogi/php-nginx:8.4
ports:
- "8080:8080"
environment:
NGINX_PORT: 8080
PHP_MEMORY_LIMIT: 256M
PHP_POST_MAX_SIZE: 32M
PHP_UPLOAD_MAX_FILESIZE: 32M
php.date.timezone: Europe/London
fpm.pool.pm.max_children: 20
volumes:
- ./public:/var/www/html:ro
healthcheck:
test: ["CMD", "healthcheck.sh"]
interval: 30s
timeout: 3s
retries: 3
worker:
image: adamrollogi/php:8.4
command: php artisan queue:work
working_dir: /app
volumes:
- ./:/app
The php.* and fpm.pool.* keys are the generic overrides: any php.ini or FPM pool setting can be set this way. See PHP settings.
Development with Xdebug
docker run --rm -d -p 8080:8080 \
-e NGINX_PORT=8080 \
-v $(pwd)/public:/var/www/html \
adamrollogi/php-nginx-dev:8.4
Xdebug connects back to host.docker.internal:9003 when triggered. See the php-nginx-dev page for the variables.