Міграція
Цей посібник допоможе перенести наявний PHP-застосунок на OxPHP. Почніть із розділу про те, що ви використовуєте зараз, — nginx + PHP-FPM або FrankenPHP і RoadRunner, — а перш ніж остаточно вирішити переходити, прочитайте розділ Що не переноситься.
З nginx + PHP-FPM
Більшість застосунків переходять без змін у коді. Типовий режим виконує кожен запит із чистого стану PHP — це той самий життєвий цикл, що й у PHP-FPM, — тож уся робота зводиться до перенесення конфігурації. Приклади розгортання — це готові рецепти для Laravel, Symfony, WordPress, Drupal, Magento та інших.
1. Оберіть режим маршрутизації, що відповідає вашому try_files
| nginx | OxPHP |
|---|---|
try_files $uri /index.php?$query_string (Laravel, Symfony, Yii) |
ENTRY_FILE=index.php (Framework) |
try_files $uri $uri/ /index.php з кількома точками входу PHP (WordPress, OpenCart) |
ENTRY_FILE не задано (Traditional) |
try_files $uri /index.html для односторінкового застосунку |
ENTRY_FILE=index.html (SPA) |
2. Зберіть образ
Почніть із дворядкового Dockerfile зі Швидкого старту. Розширення мають бути зібрані для потокобезпечного PHP — в етапі php:*-zts-alpine з тією самою мінорною версією PHP, що й в образі OxPHP; див. Встановлення розширень PHP у продакшні.
Переконайтеся, що кожне PECL-розширення, яке ви використовуєте, підтримує ZTS. OxPHP працює лише з потокобезпечним PHP, тож розширення без підтримки ZTS не вдасться завантажити.
3. Перенесіть конфігурацію
Образ не завантажує жодного php.ini. Тримайте свої налаштування PHP (memory_limit, upload_max_filesize, OPcache, …) у власному файлі будь-де в проєкті, наприклад docker/php.ini, і скопіюйте його в каталог конфігурації PHP в образі. Цей каталог — шлях усередині контейнера, а не у вашому проєкті:
FROM ghcr.io/oxphp/oxphp:0.13.0
COPY docker/php.ini /usr/local/etc/php/conf.d/zz-app.ini
COPY --chown=www-data:www-data . /var/www/html/publicPHP читає всі файли .ini у цьому каталозі в алфавітному порядку, і діє останнє значення, тож завдяки префіксу zz- ваш файл застосовується після власних файлів образу. Можна також змонтувати файл як том; див. Налаштування PHP.
Решта відповідає змінним середовища:
| nginx / PHP-FPM | OxPHP |
|---|---|
listen 443 ssl, ssl_certificate |
TLS_CERT, TLS_KEY, TLS_MIN_VERSION; див. TLS |
pm = static / pm = dynamic, pm.max_children |
PHP_WORKERS=N / PHP_WORKERS=MIN:MAX |
php_admin_value[...], php.ini |
ваш власний файл .ini, скопійований в образі до /usr/local/etc/php/conf.d/ (див. вище) |
gzip on, brotli on |
увімкнено типово, налаштовується через COMPRESSION_ENCODINGS; див. Стиснення |
expires 30d для статичних файлів |
STATIC_MAX_AGE (типово 30d) |
limit_req |
RATE_LIMIT, RATE_WINDOW_SECONDS (фіксоване вікно для кожної IP-адреси); див. Обмеження частоти запитів |
set_real_ip_from, real_ip_header |
TRUSTED_PROXIES; див. Довірені проксі |
error_page 404 /404.html |
ERROR_PAGES_DIR із файлами {status}.html; див. Сторінки помилок |
access_log |
ACCESS_LOG=all або error (рядки JSON); див. Журнал доступу |
location ~ ^/uploads/.*\.php$ { deny all; } |
PHP_DENY_PATHS=/uploads/**; див. Список заборони виконання PHP |
pm.status_path, ping.path |
INTERNAL_ADDR з /health і /metrics; див. Перевірки стану |
fastcgi_finish_request() |
oxphp_finish_request(); див. Рання відповідь |
4. Перевірте відмінності в поведінці
max_execution_timeрахує реальний час. У PHP-FPM час очікування бази даних або HTTP-виклику не зараховується, а в потокобезпечному PHP — зараховується. Повільний ендпоінт, який раніше ніколи не досягав ліміту, може почати повертати504. Див. Тайм-аути.php_sapi_name()повертаєcli-server. Коду, що розгалужується за значеннямfpm-fcgi, потрібна інша перевірка:function_exists('oxphp_request_id').- Кілька ключів
$_SERVERвідрізняються.SERVER_ADDR,PATH_TRANSLATEDіREDIRECT_STATUSне встановлюються, аPHP_AUTH_USER/PHP_AUTH_PWне видобуваються; натомість читайтеHTTP_AUTHORIZATION. Див. Відмінності від PHP-FPM. - Вбудовування у фрейми типово обмежене. Відповіді містять
X-Frame-Options: SAMEORIGINі відповідну політикуframe-ancestors. ЗадайтеFRAME_OPTIONS=off, якщо керуєте вбудовуванням в інший спосіб або вбудовуєте застосунок у сторінки іншого походження; див. Захист від клікджекінгу.
5. Розгортайте поруч зі старим стеком
Запустіть OxPHP поруч із nginx + PHP-FPM, спрямуйте на нього частину трафіку через наявний балансувальник навантаження, використовуйте /health/readiness для проб і порівняйте частоту помилок і затримку за /metrics, перш ніж переносити решту.
6. Вмикайте режим воркерів наостанок
Спершу виконайте міграцію в типовому режимі. Потім задайте WORKER_MODE_ENABLED=true і вкажіть в ENTRY_FILE скрипт воркера. Стан у статичних властивостях і довготривалі з’єднання відтепер зберігаються між запитами, тож перш ніж вмикати цей режим, прочитайте розділ Що скидається і що зберігається.
З FrankenPHP або RoadRunner
Скрипти воркерів зберігають свою форму: спершу одноразова ініціалізація, потім обслуговування запитів. Замініть цикл frankenphp_handle_request() одним викликом oxphp_worker($handler). OxPHP сам виконує цикл і викликає обробник для кожного запиту; усередині обробника читайте запит із суперглобальних змінних або через oxphp_http_request(). Цикл PSR-7 waitRequest() / respond() з RoadRunner не має відповідника: перенесіть обробник застосунку в той самий колбек. Див. oxphp_worker() і Режим воркерів.
Приберіть лічильник MAX_REQUESTS
Відповідника немає, і він вам не потрібен: воркер не розрахований на перезапуск кожні N запитів, а такий перезапуск лише приховує витік пам’яті. Якщо ви його підозрюєте, краще відстежуйте:
- Будуйте графік
oxphp_worker_memory_bytesдля кожного воркера і стежте, чи не зростає він невпинно. - Задайте
WORKER_MAX_MEMORY_MIBяк запобіжник. Воркер, що перевищив ліміт, замінюється раніше, ніж контейнерові забракне пам’яті, і кожен такий перезапуск враховується вoxphp_worker_recycles_by_reason_total{reason="max_memory"}. - Цей ліміт вимірює лише власну купу PHP. Якщо стек активно використовує розширення, порівнюйте
Worker::current()->rss()із власним порогом і викликайтеWorker::scheduleExit().
Що не переноситься
- OxPHP не підтримує зворотне проксіювання чи upstream-сервери: немає ні
proxy_pass, ні WebSocket-сервера. Якщо nginx також стоїть перед іншими сервісами, залиште проксі перед OxPHP для цих маршрутів. - Екземпляр має один порт і один протокол. Він обслуговує або звичайний HTTP, або HTTPS, але не обидва, тож для перенаправлення з порту 80 на HTTPS потрібен проксі або другий екземпляр. Сертифікат читається під час запуску, тож після його оновлення потрібен перезапуск; див. TLS.
- HTTP/3 і
103 Early Hintsпоки що недоступні; див. дорожню карту. - OxPHP працює лише в Linux і поширюється як образ Docker. Пакетів apt чи brew немає. Підтримуються PHP 8.4 і 8.5.
Промпти для вашого агента
Ці промпти розраховані на агента з підключеним MCP-сервером документації OxPHP — потрібні сторінки він прочитає сам.
Перенеси цей застосунок із nginx і PHP-FPM на OxPHP. Прочитай сторінку `getting-started/migration` через MCP-сервер документації OxPHP.
Перетвори серверні блоки nginx, налаштування пулу PHP-FPM і перевизначення php.ini з цього репозиторію на Dockerfile для OxPHP і змінні середовища, обери режим маршрутизації за правилами `try_files` і перелічи всі відмінності в поведінці та непідтримувані можливості, які стосуються цього коду, вказавши для кожної файл, якого вона стосується.Перенеси воркер FrankenPHP або RoadRunner із цього репозиторію на OxPHP. Прочитай сторінку `getting-started/migration` через MCP-сервер документації OxPHP.
Перепиши скрипт воркера навколо одного виклику `oxphp_worker()`, прибери будь-який лічильник, що перезапускає воркер кожні N запитів, і скажи, яку метрику та який ліміт пам’яті налаштувати натомість.Що далі
- Маршрутизація — докладно про режими маршрутизації Traditional, Framework, SPA і Worker
- Посібник із Docker — Dockerfile для розробки та продакшену, конфігурація Compose, монтування PHP ini
- Конфігурація — повний довідник змінних середовища
- Режим воркерів — постійні PHP-воркери, які ініціалізуються один раз і обробляють багато запитів
- Приклади розгортання — готові рецепти для Laravel, Symfony, WordPress, Drupal, Magento та інших