Files
diet/LESSONS.md
Денис Шкабатур 687b08787d feat: add Docker deployment to diet.dshkabatur.ru
- Add multi-stage Dockerfile (node:22-alpine build → nginx:alpine serve)
- Add nginx.conf for SPA routing inside container
- Add .dockerignore
- Deploy to dshkabatur.ru server with Docker + host Nginx + SSL (Certbot)
- Live at https://diet.dshkabatur.ru

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-11 12:37:39 +03:00

3.3 KiB
Raw Permalink Blame History

Lessons Learned — Опыт разработки

Этот файл фиксирует важные уроки, решения и инсайты, полученные в ходе разработки.


2026-02-11 — Старт проекта

Выбор стека

  • Vite + React + TS выбран вместо Astro/Next.js: проект интерактивный (поиск, фильтры, BMI калькулятор), Astro избыточен для SPA, Next.js избыточен без SSR.
  • Tailwind CSS 4 — utility-first, быстрая стилизация, отличная поддержка dark mode.
  • React Router 7 — client-side routing для SPA, нет нужды в серверном роутинге.

Решения по архитектуре

  • Данные хранятся как TS-модули (не JSON) — это даёт типизацию на уровне данных.
  • localStorage для пользовательских настроек (тема, закладки) — достаточно для статического приложения.
  • as const объекты вместо enum — лучше tree-shaking и удобнее в использовании с типами.

Проблемы и решения

  • Vite create cancelled: npm create vite@latest . отказывается работать в непустой директории. Решение: ручная инициализация проекта.
  • __dirname в ESM: В vite.config.ts нельзя использовать __dirname (CommonJS). Решение: fileURLToPath(new URL("./src", import.meta.url)).
  • Tailwind CSS 4: Использует @import "tailwindcss" вместо @tailwind директив. Кастомные цвета через @theme {}.
  • React Router 7: NavLink с end пропом для exact matching. Без end на / он будет активен на всех роутах.

UX решения

  • Тема: 3 режима (light/dark/system) — system слушает prefers-color-scheme и реагирует на изменения.
  • Мобильное меню закрывается при навигации — onClick={() => setMobileOpen(false)}.
  • ScrollToTop компонент обязателен для SPA — без него при навигации страница остаётся на том же скролле.

Деплой

  • Docker multi-stage build: node:22-alpine для сборки → nginx:alpine для раздачи. Итоговый образ маленький, без Node.js.
  • Nginx на хосте как reverse proxy: конфиг в /etc/nginx/conf.d/diet.dshkabatur.ru.conf, проксирует на 127.0.0.1:3080.
  • Certbot: --nginx --non-interactive --agree-tos --redirect — автоматически модифицирует nginx-конфиг, добавляет SSL и редирект HTTP→HTTPS.
  • Heredoc + sudo: через SSH нельзя легко передать heredoc в sudo tee. Решение: записать в /tmp/, потом sudo cp на место.
  • --restart unless-stopped: контейнер перезапускается при ребуте сервера.