TGViewer
Make. Build. Break. Reflect. Make. Build. Break. Reflect. @makebreakreflect · 1.37K subscribers
Post #272 666
#cloudfront #aws #troubleshooting #одинденьизжизни

Однажды меня попросили сделать перенос старого SPA (Single Page Application)-приложения на новый S3 bucket в CloudFront.
Но не просто перенос, а хитрый: часть путей должна идти на новое приложение, а часть - оставаться на старом.
Legacy страницы типа /welcome, /login-start, /login-end пока не переписаны в новом коде, их надо сохранить.
А всё остальное - на свежий app-v2.
По сути частичная миграция на новое приложение, не ломая старое.

Казалось бы, что может пойти не так? 😁

Задача звучит просто:
- /* > новый bucket (app-v2)
- /welcome*, /login-start*, /login-end*, /help-bot* > старый bucket
- /assets/*, /sdk.js > старый bucket

Открываю Terraform, добавляю новый origin для app-v2 bucket.
Меняю default_cache_behavior на новый origin.
Добавляю ordered_cache_behavior для legacy путей на старый bucket.
Terraform plan - всё как задумано.
Apply. Жду. Готово.

Иду проверять.
- https://stage-app.example.com/ - работает, новое приложение грузится. ✅
- https://stage-app.example.com/?appId=xxx - работает, редиректит. ✅
- https://stage-app.example.com/welcome - ...

"Server Error. An unexpected error happened."


Чо. 🤡

Первая мысль - кэш CloudFront. Делаю invalidation. Жду. Проверяю.
Та же херня.

Вторая мысль - может origin неправильный?
Проверяю напрямую S3 bucket:
curl -I "http://stage-app.example.com.s3-website-us-east-1.amazonaws.com/index.html"
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 4755

Bucket работает. index.html есть. 4755 байт. Всё ок.

Третья мысль - может custom_error_response мешает?
В CloudFront есть глобальный обработчик 404 ошибок, который возвращает /index.html.
Думаю: "А, наверное S3 возвращает 404, а CloudFront берёт index.html с дефолтного origin!"
Убираю custom_error_response. Apply. Проверяю.
Та же херня. Даже хуже - теперь вместо "Server Error" просто "Not found".

Возвращаю custom_error_response. Сижу, чешу репу.

Ладно, поехали курлить по-взрослому.
curl -sI "https://stage-app.example.com/welcome"
HTTP/2 200
content-type: text/html
x-cache: Hit from cloudfront

Стоп. 200? Не 404? CloudFront отдаёт 200 и HTML?
Смотрю body:
curl -s "https://stage-app.example.com/welcome" | head -20

Да, это HTML старого приложения. webpackJsonstatham@app/web. Всё верно.
Так почему "Server Error" в браузере?

Если HTML грузится, значит проблема в JavaScript.
Приложение падает после загрузки.
Открываю DevTools > Network.

И тут я вижу ЭТО:
/static/js/main.a1b2c3d4.chunk.js → content-type: text/html ❌
/static/css/main.e5f6g7h8.chunk.css → content-type: text/html ❌

JS файлы возвращают HTML вместо JavaScript.
Браузер пытается выполнить HTML как JavaScript.
Приложение падает с "Server Error".
Сука. 😁

Проверяю напрямую S3:
curl -sI "http://stage-app.example.com.s3-website-us-east-1.amazonaws.com/static/js/main.a1b2c3d4.chunk.js"
HTTP/1.1 200 OK
Content-Type: text/javascript
Content-Length: 1080675

S3 отдаёт правильно! 1MB JavaScript!

А через CloudFront:
curl -sI "https://stage-app.example.com/static/js/main.a1b2c3d4.chunk.js"
HTTP/2 200
content-type: text/html
x-cache: Error from cloudfront

CloudFront отдаёт HTML. И x-cache: Error from cloudfront. Красота.

Теперь понятно что происходит.
Сажусь рисовать на планшете путь запроса (а я всегда рисую).

Проблема:
1. Браузер > /welcome
2. CloudFront матчит /welcome* > origin: OLD bucket
3. S3 не находит файл /welcome (это SPA route, не файл)
4. S3 возвращает error_document = index.html
5. Браузер получает HTML старого приложения ✅

6. HTML содержит: <script src="./static/js/main.a1b2c3d4.chunk.js">
7. Браузер резолвит ./static/... относительно /welcome
8. Браузер запрашивает /static/js/main.a1b2c3d4.chunk.js

9. CloudFront матчит /* (default) > origin: app-v2 bucket
10. В app-v2 bucket НЕТ файла main.a1b2c3d4.chunk.js!
11. S3 возвращает 404
12. CloudFront custom_error_response > /index.html
13. Браузер получает index.html (HTML) вместо JavaScript
14. JavaScript парсер: "че за херня, это не JS"
15. Приложение: "Server Error"🐒
  • 👍 8
More from @makebreakreflect
  1. Sep 24, 2026Но стоит взять задачу из смежной области, где общее понимание есть, а глубокой экспертизы…
  2. Sep 23, 2026В удивительнейшее время живём. - https://typesafe.ai/blog/introducing-system-one-models-an…
  3. Sep 22, 2026#aws #elasticache #redis #kubernetes #troubleshooting #devops #sre #longread Ничего не пре…
  4. Sep 18, 2026Вся эта неделя была очень странной. Опус отупел до уровня 3 модели. Фейбл сжигает токены б…
  5. Sep 16, 2026Post #382
  6. Sep 15, 2026Apple наконец слила beta и release в один продукт и избавились от лишнего шага в релизном…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →