Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 41 additions & 12 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,19 +1,48 @@
FROM php:8.2-cli
FROM php:8.2-cli-alpine

RUN apt-get update && \
apt-get install -y git default-jre-headless
LABEL maintainer="PHP Documentation Team <[email protected]>"
LABEL description="Image for building and serving PHP documentation (php-chunked-xhtml format)"

WORKDIR /var/www
ENV LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
DOC_DIR=/var/www \
PHD_DIR=/opt/phd

ADD https://api.github.com/repos/php/phd/git/refs/heads/master version-phd.json
ADD https://api.github.com/repos/php/doc-base/git/refs/heads/master version-doc-base.json
# 🔧 PhD dependencies
RUN apk add --no-cache \
git \
icu-dev \
libxml2-dev \
libxslt-dev \
gettext \
autoconf \
g++ \
pkgconfig \
&& docker-php-ext-install intl xsl

RUN git clone --depth 1 https://github.com/php/phd.git && \
git clone --depth 1 https://github.com/php/doc-base.git
# 📦 Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

RUN echo 'memory_limit = 512M' >> /usr/local/etc/php/conf.d/local.ini
# Install PhD and the PHP package (stable compatible version --addpackage)
RUN git clone https://github.com/php/phd.git "$PHD_DIR" \
&& cd "$PHD_DIR" \
&& git checkout c3e2d8c \
&& git clone https://github.com/php/phd-php.git "$PHD_DIR/phpdotnet/phd/Package/PHP" \
&& composer install --no-dev --no-progress --prefer-dist || true

ENV FORMAT=xhtml
WORKDIR $DOC_DIR

CMD php doc-base/configure.php --disable-segfault-error && \
php phd/render.php --docbook doc-base/.manual.xml --output=/var/www/en/output --package PHP --format ${FORMAT}
# Default formats and package
ENV FORMAT=php-chunked-xhtml
ENV PACKAGE=PHP

# Grant full permissions to /var/www (useful on Windows/WSL2)
RUN mkdir -p /var/www/output && chmod -R 777 /var/www

# Entry script
COPY .docker/entrypoint.sh /usr/local/bin/entrypoint.sh
RUN sed -i 's/\r$//' /usr/local/bin/entrypoint.sh && chmod +x /usr/local/bin/entrypoint.sh

EXPOSE 8000
RUN chmod -R 777 /var/www
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
109 changes: 109 additions & 0 deletions .docker/entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#!/bin/sh

# POSIX-compliant entrypoint for building PHP documentation
# Fully compatible with Linux, Alpine, and macOS environments

set -e

LANGUAGE=${1:-en}
FORMAT=${2:-xhtml}
PACKAGE=${PACKAGE:-PHP}
MANUAL_PATH="/var/www/$LANGUAGE/.manual.xml"

# 🧩 Step 1. Verify prerequisites (avoid silent empty mounts)
echo "🔍 Checking required documentation repositories..."

# Check doc-base presence (must contain configure.php)
if [ ! -f /var/www/doc-base/configure.php ]; then
echo "❌ doc-base is missing or incomplete!"
echo "👉 Please clone it before running Docker:"
echo " git clone https://github.com/php/doc-base ../doc-base"
echo ""
exit 1
fi

# Check language documentation presence
if [ ! -d "/var/www/$LANGUAGE" ] || [ ! -f "/var/www/$LANGUAGE/sources.xml" ]; then
echo "❌ doc-${LANGUAGE} is missing or incomplete!"
echo "👉 Please clone it before running Docker:"
echo " git clone https://github.com/php/doc-${LANGUAGE} ../doc-${LANGUAGE}"
echo ""
echo "💡 Tip: remove any empty folders and rebuild containers with '--force-recreate'."
exit 1
fi

done
echo "✅ All prerequisites found."
echo ""

echo "🧩 Building PHP documentation..."
echo "Language: $LANGUAGE"
echo "Format: $FORMAT"
echo "Docbook: $MANUAL_PATH"

# Add the PHP package to the include_path for PhD.
export PHP_INCLUDE_PATH="$PHD_DIR/phpdotnet/phd/Package:$PHD_DIR/phpdotnet/phd/Package/PHP:$PHP_INCLUDE_PATH"

# 🧹 Clean if necessary
if [ -f "$MANUAL_PATH" ]; then
echo "🧹 Removing old .manual.xml..."
rm -f "$MANUAL_PATH" || true
fi

echo "ℹ️ Generating .manual.xml for $LANGUAGE..."
cd /var/www/doc-base
php configure.php \
--disable-segfault-error \
--basedir="/var/www/doc-base" \
--output="$MANUAL_PATH" \
--lang="$LANGUAGE"

if [ ! -f "$MANUAL_PATH" ]; then
echo "❌ Failed to generate $MANUAL_PATH"
exit 1
fi
echo "✅ Generated $MANUAL_PATH"

# Verify PHP package presence
if [ ! -d "$PHD_DIR/phpdotnet/phd/Package/PHP" ]; then
echo "❌ PHP package not found in $PHD_DIR/phpdotnet/phd/Package/PHP"
exit 1
fi

# Normalize Windows CRLF endings and adjust doc-base paths
echo "🩹 Patching entity paths to use doc-base…"
tr -d '\r' < "$MANUAL_PATH" > "$MANUAL_PATH.clean" && mv "$MANUAL_PATH.clean" "$MANUAL_PATH"
sed -i "s#/var/www/$LANGUAGE/entities/#/var/www/doc-base/entities/#g" "$MANUAL_PATH"
sed -i "s#/var/www/$LANGUAGE/version.xml#/var/www/doc-base/version.xml#g" "$MANUAL_PATH"
sed -i "s#/var/www/$LANGUAGE/sources.xml#/var/www/doc-base/sources.xml#g" "$MANUAL_PATH"
head -n 25 "$MANUAL_PATH"

# 🧩 Include the PHP package for PhD
export PHP_INCLUDE_PATH="$PHD_DIR/phpdotnet/phd/Package:$PHD_DIR/phpdotnet/phd/Package/PHP:$PHP_INCLUDE_PATH"

cd /var/www/$LANGUAGE

# 🏗️ Render the documentation
php -d include_path="$PHP_INCLUDE_PATH" \
"$PHD_DIR/render.php" \
--docbook "$MANUAL_PATH" \
--package "$PACKAGE" \
--format "$FORMAT"

# 🔎 Locate the output directory
OUTDIR=""
for d in php-chunked-xhtml xhtml phpweb php; do
if [ -d "/var/www/$LANGUAGE/output/$d" ]; then
OUTDIR="/var/www/$LANGUAGE/output/$d"
break
fi
done

if [ -d "$OUTDIR" ]; then
echo "✅ Build complete: $OUTDIR"
echo "View the documentation on http://localhost:8000"
else
echo "❌ No output directory found in /var/www/$LANGUAGE/output/"
ls -R "/var/www/$LANGUAGE/output" || true
exit 1
fi
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,50 @@ already exist.
You can also build the `web` version of the documentation with `make php`
and the output will be placed in output/php-web

### 🐋 Building with Docker Compose (alternative modern setup)

A `compose.yaml` file is available for contributors who prefer a simple,
cross-platform Docker workflow instead of `make`.

It builds and serves the PHP manual locally in any translation
(English by default, or another language via `LANGUAGE`).

#### Prerequisites

- Docker ≥ 24 and Docker Compose ([install guide](https://docs.docker.com/get-docker/))
- Local clone structure:
```
php-doc/
├─ doc-base/ ← common build files, scripts, entities, configure.php
├─ doc-en/ ← English manual (contains this Docker setup)
└─ doc-fr/ ← French manual or your official language repository (doc-es, doc-ja...)
```

#### Usage

From inside `php-doc/doc-en/`:

```bash
# Default build (English)
docker compose up --build
```
To build another translation:
**Linux / macOS**
```
LANGUAGE=fr docker compose up --build
```
**Windows PowerShell**
```bash
$env:LANGUAGE="fr"; docker compose up --build

Remove-Item Env:LANGUAGE # Revert back to English
```
The process will:

1. Build a minimal PHP 8.2 environment with PhD.
2. Generate `.manual.xml` and render the manual in HTML (php-chunked-xhtml).
3. Start a local PHP web server on http://localhost:8000 where you can view the documentation.

## Translations

For the translations of this documentation, see:
Expand Down
22 changes: 22 additions & 0 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
services:
phpdoc:
build:
dockerfile: .docker/Dockerfile
container_name: phpdoc-builder
working_dir: /var/www
user: "0:0"
volumes:
- ../doc-${LANGUAGE:-en}:/var/www/${LANGUAGE:-en}
- ../doc-en:/var/www/en
- ../doc-base:/var/www/doc-base
command: ["${LANGUAGE:-en}", "xhtml"]

phpdoc-web:
image: php:8.2-cli-alpine
container_name: phpdoc-web
working_dir: /var/www/${LANGUAGE:-en}/output
volumes:
- ../doc-${LANGUAGE:-en}/output/php-chunked-xhtml:/var/www/${LANGUAGE:-en}/output
ports:
- "8000:8000"
command: ["php", "-S", "0.0.0.0:8000", "-t", "/var/www/${LANGUAGE:-en}/output"]