Magento na OxPHP

Magento to najcięższy przepis w tym zestawieniu. Wymaga silnika wyszukiwania (OpenSearch), obszernej listy rozszerzeń oraz kroku wdrożenia zawartości statycznej. Działa w trybie routingu frameworka OxPHP, gdzie katalogiem głównym dokumentów jest pub/, ale jego zwersjonowane adresy URL zasobów statycznych wymagają jednego dodatkowego kroku, opisanego poniżej.

Stos w skrócie

  • Obraz OxPHP: ghcr.io/oxphp/oxphp:0.10.0-php8.4-alpine3.23 (PHP 8.4)
  • Tryb routingu: Framework (ENTRY_FILE=index.php; DOCUMENT_ROOT=/var/www/html/pub nadpisuje domyślne …/public)
  • Dodane rozszerzenia: bcmath, gd, intl, pdo_mysql, soap, xsl, zip, mbstring, ftp, pcntl, sockets
  • Usługi: OxPHP + MySQL 8.0 + OpenSearch 2.x
  • URL: http://localhost:8093 · panel administracyjny /admin · wewnętrzny http://localhost:9094/health
Wersja PHP

Magento 2.4.8 deklaruje "php": "~8.2 || ~8.3 || ~8.4" i odrzuca PHP 8.5, więc przypnij obraz z PHP 8.4. ext-sockets jest zależnością przechodnią (php-amqplib) i do skompilowania potrzebuje linux-headers.

Układ projektu

Magento Open Source z oficjalnego kanału dystrybucji wymaga kluczy autoryzacyjnych Adobe Marketplace. Aby zainstalować bez kluczy, sklonuj repozytorium open source (jego moduły są dostarczane w drzewie projektu poprzez replace, więc composer install pobiera wyłącznie zależności z Packagist):

bash
mkdir -p magento-oxphp git clone --branch 2.4.8 --depth 1 https://github.com/magento/magento2.git magento-oxphp/src # composer install runs later, inside the PHP 8.4 container (composer:2 is PHP 8.5 # and Magento rejects it): docker compose run --rm --no-deps -e COMPOSER_MEMORY_LIMIT=-1 app \ composer install --no-interaction --prefer-dist

Plik Dockerfile i plik compose

src/Dockerfile.oxphp nosi taką nazwę, aby uniknąć kolizji z własnymi zasobami Docker firmy Magento.

src/Dockerfile.oxphp
ARG OXPHP_VERSION=0.10.0 ARG PHP_VERSION=8.4 ARG ALPINE_VERSION=3.23 # ── PHP base: Magento runtime extensions ────────────────────── FROM php:${PHP_VERSION}-zts-alpine${ALPINE_VERSION} AS php-base RUN apk add --no-cache \ icu-libs libpng libjpeg-turbo freetype oniguruma libzip libxslt \ && apk add --no-cache --virtual .build-deps \ icu-dev libpng-dev libjpeg-turbo-dev freetype-dev oniguruma-dev \ libzip-dev libxslt-dev libxml2-dev linux-headers \ && docker-php-ext-configure gd --with-jpeg --with-freetype \ && docker-php-ext-install -j"$(nproc)" \ bcmath gd intl pdo_mysql soap xsl zip mbstring ftp pcntl sockets \ && apk del .build-deps # ── Composer ────────────────────────────────────────────────── FROM composer:2 AS composer # ── OxPHP artifacts (PHP 8.4 image) ─────────────────────────── FROM ghcr.io/oxphp/oxphp:${OXPHP_VERSION}-php${PHP_VERSION}-alpine${ALPINE_VERSION} AS oxphp # ── dev: OxPHP server + PHP CLI + Composer + Magento extensions ─ FROM php-base AS dev RUN apk add --no-cache libgcc git patch COPY --from=composer /usr/bin/composer /usr/local/bin/composer COPY --from=oxphp /usr/local/bin/oxphp /usr/local/bin/oxphp COPY --from=oxphp /usr/local/lib/liboxphp_bridge.so /usr/local/lib/ COPY --from=oxphp /usr/local/lib/php/extensions/ /tmp/oxphp-ext/ RUN cp /tmp/oxphp-ext/*/oxphp_sapi.so "$(php -r 'echo ini_get("extension_dir");')/" \ && rm -rf /tmp/oxphp-ext \ && echo "extension=oxphp_sapi.so" > /usr/local/etc/php/conf.d/oxphp-ext.ini RUN { \ echo "[opcache]"; echo "opcache.enable=1"; echo "opcache.enable_cli=1"; \ echo "opcache.validate_timestamps=1"; echo "opcache.revalidate_freq=0"; \ } > /usr/local/etc/php/conf.d/opcache-dev.ini RUN { \ echo "memory_limit=4G"; echo "max_execution_time=1800"; \ echo "realpath_cache_size=10M"; echo "realpath_cache_ttl=86400"; \ echo "upload_max_filesize=64M"; echo "post_max_size=64M"; \ } > /usr/local/etc/php/conf.d/magento.ini RUN getent passwd www-data >/dev/null \ || adduser -D -H -u 82 -G www-data -s /sbin/nologin www-data RUN mkdir -p /var/www/html/pub && chown -R www-data:www-data /var/www/html ENV LD_LIBRARY_PATH=/usr/local/lib WORKDIR /var/www/html EXPOSE 80 9090 CMD ["oxphp"]

Instalacja i pierwsze uruchomienie

bash
docker compose up -d db opensearch # composer install (see Project layout), then: docker compose run --rm app php bin/magento setup:install \ --base-url=http://localhost:8093/ \ --db-host=db --db-name=magento --db-user=magento --db-password=magento \ --admin-firstname=Admin --admin-lastname=User \ [email protected] --admin-user=admin --admin-password='Admin123!' \ --language=en_US --currency=USD --timezone=America/New_York \ --search-engine=opensearch --opensearch-host=opensearch --opensearch-port=9200 \ --opensearch-index-prefix=magento --opensearch-enable-auth=0 # production mode compiles DI and deploys static content docker compose run --rm app php bin/magento deploy:mode:set production # CRITICAL for OxPHP: make versioned static URLs resolve (see notes below) docker compose run --rm app sh -c \ 'ln -sfn . "pub/static/version$(cat pub/static/deployed_version.txt)"' docker compose up -d app

Uwagi dotyczące OxPHP

Note
  • Zwersjonowane statyczne adresy URL potrzebują dowiązania symbolicznego. Magento generuje adresy URL zasobów w postaci /static/version<timestamp>/frontend/…, podczas gdy pliki znajdują się w pub/static/frontend/…. nginx usuwa segment version<N>/ za pomocą reguły przepisywania; tryb frameworka OxPHP nie ma takiego przepisywania, więc każdy zwersjonowany zasób zwracałby 404, a witryna sklepu renderowałaby się bez stylów. Rozwiązaniem jest samoreferencyjne dowiązanie symboliczne, dzięki któremu zwersjonowana ścieżka wskazuje na rzeczywiste pliki:

    bash
    ln -sfn . "pub/static/version$(cat pub/static/deployed_version.txt)"

    Ponieważ dowiązanie symboliczne pozostaje wewnątrz DOCUMENT_ROOT (pub/), wpis SYMLINK_ALLOW_PATHS nie jest wymagany.

  • Uruchamiaj tryb produkcyjny. Pula workerów OxPHP jest wielowątkowa (PHP ZTS). Tryb deweloperski Magento generuje klasy DI oraz zasoby statyczne w locie (poprzez pub/static.php, którego tryb frameworka nie routuje), co grozi wyścigami pomiędzy wątkami workerów. deploy:mode:set production z wyprzedzeniem prekompiluje DI i wdraża zawartość statyczną, więc workery nigdy nie generują kodu w czasie obsługi żądania.

  • MySQL: --log_bin_trust_function_creators=1. Magento tworzy wyzwalacze i procedury składowane podczas instalacji; przy włączonym logowaniu binarnym (domyślnym w MySQL 8.0) użytkownik magento bez uprawnień SUPER w przeciwnym razie napotyka błąd 1419.

  • composer install działa w kontenerze z PHP 8.4. Standardowy obraz composer:2 to PHP 8.5, który Magento odrzuca; uruchom go zamiast tego przez zbudowany obraz app.

Weryfikacja

bash
curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8093/ # 200 storefront curl -s -o /dev/null -w "%{http_code}\n" http://localhost:8093/admin # 200 admin login curl -s http://localhost:8093/ | grep -oE '/static/version[0-9]+/[^"]+\.css' | head -1 | \ xargs -I{} curl -s -o /dev/null -w "%{http_code}\n" "http://localhost:8093{}" # 200 curl -s -o /dev/null -w "%{http_code}\n" http://localhost:9094/health # 200

Zobacz też