Skip to main content

🚀 Quick Start

Run it​

docker run --rm -p 8080:8080 ruseler/alpine-php-webserver

Open http://localhost:8080/. You'll see phpinfo() from the bundled index.php. The static probe at http://localhost:8080/test.html is also served.

Stop with Ctrl+C.

Serve your own code​

Bind-mount a local directory into /var/www/html:

docker run --rm -p 8080:8080 \
-v "$PWD/php:/var/www/html" \
ruseler/alpine-php-webserver

Nginx serves static files directly and hands *.php requests to PHP-FPM via the Unix socket at /run/php-fpm.sock.

The container runs as nobody (UID 65534)

Bind-mounted files must be readable by that user. For write access (sessions, caches, uploads), make the directory writable too:

sudo chown -R 65534:65534 ./php

Named Docker volumes get the right ownership automatically.

With Docker Compose​

Save as docker-compose.yml next to your code:

services:
web:
image: ruseler/alpine-php-webserver
restart: unless-stopped
ports:
- "8080:8080"
volumes:
- ./php:/var/www/html

Run it:

docker compose up -d
docker compose logs -f web

See Docker Compose for more realistic stacks (MariaDB, Redis, reverse proxy).

What port does it listen on?​

8080 inside the container. The image intentionally does not bind privileged ports because it runs as nobody. Map whatever public port you want:

docker run --rm -p 80:8080 ruseler/alpine-php-webserver # host 80 → container 8080

Tweaking limits on the fly​

The most common knobs are exposed as environment variables:

docker run --rm -p 8080:8080 \
-e client_max_body_size=64M \
-e upload_max_filesize=64M \
-e post_max_size=64M \
-e memory_limit=256M \
-e date_timezone=Europe/Madrid \
-v "$PWD/php:/var/www/html" \
ruseler/alpine-php-webserver

See Environment Variables for the full reference.

Next steps​


This documentation is a fork of erseco/alpine-php-webserver. The upstream documentation is available here.