Безголовне розгортання WordPress: DNS, SSL і AI
Tech
AI
headless CMS
WordPress
Next.js

Безголовне розгортання WordPress: DNS, SSL і AI

Справжнє безголовне розгортання WordPress може зламати DNS, SSL, зображення та форми. Ось як я це виправив у production.

Uygar DuzgunUUygar Duzgun
Mar 27, 2026
Updated 4 квіт. 2026 р.
8 min read

Це Частина 2 моєї серії міграцій WordPress без headless. Розгортання headless WordPress — це там, де починаються справжні проблеми, бо DNS, SSL, зображення, форми та редиректи ламаються по-різному. У Частині 1 я за один день відбудував фронтенд за допомогою Claude Code, Stitch MCP і Next.js. У цій статті я показую проблеми розгортання, з якими зіткнувся, як їх виправив, і чому AI все одно потребував людського судження.

Проблема розгортання headless WordPress, про яку ніхто не говорить

Зібрати фронтенд — це найпростіше. У моєму досвіді розгортання headless WordPress стає складним у той момент, коли ти розділяєш один сайт на дві системи: Vercel для фронтенду та WordPress для бекенду. Тепер у тебе вже немає одного простого стеку. У тебе є DNS, сертифікати, медіа-URL, REST endpoints і адмін-доступ, які тягнуть у різні боки.

Коли `optagonen.se` переїхав на Vercel, кожен запит, який раніше йшов у WordPress, почав потрапляти на новий фронтенд. Це зламало GraphQL, завантаження, Contact Form 7 і адмін-доступ за один крок. Якщо ти плануєш власне розгортання headless WordPress, тобі потрібно продумати ці точки розриву ще до того, як перемкнеш DNS.

Я перевірив це на реальній міграції в продакшені, а не в пісочниці. Висновок був очевидний: код зробився швидко, але інфраструктура забрала час.

Розділення DNS для розгортання headless WordPress

Найчистіше рішення — дати WordPress власний піддомен: `wp.optagonen.se`. Так я розділив фронтенд і бекенд без примусу до reverse proxy всього через одне походження. Це також зробило архітектуру простішою для розуміння під час троблшутингу SSL і доставки медіа.

DomainPoints toPurpose
---------
`optagonen.se`VercelFrontend in Next.js
`wp.optagonen.se`Origin serverWordPress backend

Я додав `wp.optagonen.se` як alias у Hestia, вказав DNS A record на IP origin-сервера та оновив змінну середовища у фронтенді:

`WP_URL=https://wp.optagonen.se`
`CF7_FORM_ID=8`
`WP_APP_PASSWORD=...`

Ця частина проста на папері. На практиці розгортання headless WordPress спричинило ланцюгову реакцію. Кожна система, яка припускала старий домен, потребувала нового цільового адресату.

Розгортання headless WordPress і збої сертифікатів SSL

Першим зламався SSL. Старий сертифікат Let's Encrypt покривав лише `optagonen.se` і `www.optagonen.se`, тож `https://wp.optagonen.se` падав одразу. Це очікувана поведінка. Let's Encrypt перевіряє належність домену для кожного hostname, і браузер відхилить з’єднання, якщо сертифікат не збігається.

Вбудоване автоматичне продовження в Hestia не спрацювало, бо воно все ще намагалося валідовати основний домен через HTTP-01, але тепер основний домен вказував на Vercel. Certbot не спрацював з іншої причини: Hestia перехоплював ACME challenge і повертав свій власний thumbprint замість thumbprint Certbot. Саме такий конфлікт AI не може вивести з перших принципів. Потрібно знати, як поводиться панель.

Я виправив це, тимчасово виніс конфігурацію ACME challenge Hestia з шляху include для nginx, видав сертифікат лише для `wp.optagonen.se`, а потім скопіював оновлені файли назад у директорію SSL Hestia. Я також додав renewal hook, щоб процес залишався автоматичним.

Для довіри я спирався на офіційну документацію від Let's Encrypt і Certbot. Це допомогло підтвердити ACME flow, перш ніж я знову торкнувся продакшена.

Чому розгортання headless WordPress відхилило піддомен

Коли SSL запрацював, WordPress усе одно не прийняв новий хост. Замість того щоб повертати дані GraphQL, він редиректнув на `/wp-signup.php`. Це підказало, що WordPress не подобається вхідний host header.

Виправлення було одним nginx-директивою:

`proxy_set_header Host optagonen.se;`

Цей рядок змусив WordPress поводитися так, ніби запити все ще приходять з основного домену, тоді як браузер залишався на `wp.optagonen.se`. У розгортанні headless WordPress така нормалізація хоста важить більше, ніж люди очікують. WordPress дуже принциповий щодо URL сайту.

Я бачив цей самий клас проблем і в інших міграціях. Фронтенд працює, бекенд відповідає, а потім один невідповідний host header тихо ламає flow сесії.

Після розгортання headless WordPress зламались зображення

Після деплою кожне зображення повертало помилку 502. Це сталося тому, що медіа-URL у WordPress усе ще вказували на `/wp-content/uploads/...`, і ці шляхи тепер резолвились у бік Vercel замість origin-сервера. У моїй конфігурації проблема прийшла з двох місць: hardcoded URLs у статичних файлах і динамічні URL, які поверталися WPGraphQL.

Спочатку я виправив hardcoded URLs. Я замінив кожне посилання `https://optagonen.se/wp-content/uploads/` на `https://wp.optagonen.se/wp-content/uploads/` у всіх шести файлах. Це закрило приблизно 70 шляхів до зображень.

Потім я виправив динамічні GraphQL URL через rewrite в Next.js:

`/wp-content/uploads/:path*` → `https://wp.optagonen.se/wp-content/uploads/:path*`

Це зберегло фронтенд чистим і уникнуло переписування медіа-даних у WordPress. Також це зробило розгортання headless WordPress більш підтримуваним, бо браузер усе ще запитує той самий шлях, а сервер уже займається proxying.

Recommended reading

Якщо хочеш глибше зануритися в такий дизайн систем, я рекомендую прочитати мою AI-powered WordPress migration workflow і мою multi-agent content pipeline. Ці пости показують, як я структурую інфраструктуру та системи контенту навколо автоматизації.

Contact Forms, IDs і остання пастка деплою

Contact Form 7 спочатку виглядав нормально, але форма перестала працювати, бо ID у фронтенді був неправильний. Дефолтний form ID був `1`, але реальна форма в WordPress мала `8`. Швидка перевірка через API це підтвердила.

Це була невелика правка, але вона важлива. У розгортанні headless WordPress один неправильний ID може зробити робочу форму схожою на зламану, навіть якщо бекенд здоровий. Я встановив `CF7_FORM_ID=8`, і форма одразу повернулась в онлайн.

Ось чому я завжди тестую повний flow вручну:

Надішли форму з live фронтенду.
Перевір мережевий запит.
Підтвердь відповідь у WordPress.
Переконайся, що дані доходять до inbox або CRM.

Ця послідовність знаходить проблеми швидше, ніж гадати лише з логів.

Що AI допоміг зробити і що він пропустив

Claude Code допоміг мені рухатися швидко, але він не замінив розуміння. Він добре впорався з повторюваними частинами: grepping config files, генерацією nginx snippets, допомогою з командами certbot і масовою заміною image URLs. Він також тримав ланцюжок помилок у пам’яті, що заощадило час, коли одна правка створювала іншу проблему.

Однак AI не міг вирішити повну архітектуру. Він не знав, що Hestia перехоплюватиме ACME запити. Він не знав, коли використовувати піддомен замість reverse proxy. І він не знав порядок операцій, який дозволить уникнути простою.

Recommended reading

Це справжня цінність AI у розгортанні headless WordPress: він пришвидшує діагностику, але тобі все одно потрібна людина, яка розуміє стек. Я використовую той самий принцип у своїй роботі з AI automation systems for e-commerce і в роботі над моїм content pipeline.

Фінальна архітектура після деплою

Після виправлень стек стабілізувався у чистий розподіл:

ComponentLocationPurpose
---------
Next.js frontendVercelServes pages and handles routing
WordPress + WPGraphQL`wp.optagonen.se`Content API and media storage
Contact Form 7`wp.optagonen.se`Form handling
Image proxyNext.js rewrite ruleRoutes uploads to origin
Frontend SSLVercelAutomatic management
Backend SSLCertbot + renewal hookAuto-renewed certificates

Ця структура стабільна й проста для дебагу. Вона також зберігає швидкість фронтенду, одночасно зберігаючи редакційний workflow всередині WordPress. Для розгортання headless WordPress саме цей баланс — ціль.

Висновки з цього розгортання headless WordPress

Ось що я виніс із міграції:

Зміни DNS ламають більше, ніж ти очікуєш, особливо коли один домен тепер обслуговує дві системи.
SSL зазвичай ламається першим, бо валідація сертифіката залежить від маршрутизації.
Серверні панелі та зовнішні ACME інструменти можуть конфліктувати, якщо вони керують одним і тим самим доменом.
URL зображень живуть у більшій кількості місць, ніж ти думаєш, включно зі статичними файлами та GraphQL output.
AI корисний для дебагу, але він не може замінити інфраструктурне судження.

Ці уроки прийшли з реального переїзду в продакшені, а не з підручника. Саме тому я тепер закладаю стільки ж часу на деплой, скільки й на розробку.

Висновок

Розгортання headless WordPress не складне через код. Воно складне, бо DNS, SSL, медіа та host headers залежать одне від одного. У цій міграції я виправив розділення на піддомен, валідацію сертифікатів, доставку зображень і Contact Form 7, і я точно зрозумів, де AI допомагає, а де зупиняється.

Якщо ти плануєш власну міграцію, спочатку прочитай відбудову фронтенду, рано протестуй flow сертифікатів і перевір кожен медіа-шлях перед запуском. Потім перевір live сайт, підтвердь форми та переконайся, що бекенд поводиться так, як очікує WordPress.

Якщо хочеш більше практичних розборів деплою, продовжуй читати пов’язані пости й порівнюй їх зі своїм стеком. Це найшвидший спосіб уникнути помилок у твоєму наступному розгортанні headless WordPress.

Suggested image alt text:

Screenshot of Vercel and WordPress split architecture showing frontend and backend domains
Hestia control panel SSL setup for wp.optagonen.se certificate renewal
Next.js rewrite rule mapping WordPress uploads to the origin server