П/ВИН

Лендинг мероприятия: от идеи до деплоя за одну сессию

·6 мин чтения
Лендинг мероприятия: от идеи до деплоя за одну сессию

Конференция прошла, контент был огонь, но техничка подвела — онлайн-запись ушла в брак. Зато осталось кое-что поважнее: нужно было зафиксировать событие, сохранить его дух и дать людям место, куда можно отправить ссылку. Так появился проект pasha-vin-post-bot — а точнее, лендинг 18ai.pashavin.ru для конференции «Навстречу к AI».

Задача звучала просто: взять пост из Telegram-канала, несколько деталей о мероприятии — и превратить это в живой сайт. Но между «просто» и «сделано» всегда есть куча итераций по дизайну, мобильной вёрстке, галерее фотографий и деплою. Вот как это было.

Стек и дизайн-система

Для лендинга выбрал Next.js 14 — App Router, TypeScript, Tailwind CSS. Никакого бэкенда, никакой базы данных: чистый статический сайт, который просто нужно красиво задеплоить.

Дизайн — в духе pashavin.ru: тёмный фон, оранжевый акцент #FF4F00, шрифт Syne. Анимации — GSAP с посимвольным появлением заголовка. Такой подход сразу задаёт атмосферу: это не корпоративный сайт-визитка, это живое мероприятие с характером.

// Hero заголовок с GSAP-анимацией
useEffect(() => {
  const chars = titleRef.current?.querySelectorAll('.char');
  if (!chars) return;
  gsap.fromTo(chars,
    { opacity: 0, y: 40 },
    { opacity: 1, y: 0, stagger: 0.04, duration: 0.6, ease: 'power3.out' }
  );
}, []);

Структура страницы получилась такой:

  • Hero — анимированный заголовок, бейдж «Мероприятие состоялось», дата/место
  • Marquee — бегущая строка с ключевыми словами (нейросети, ChatGPT, Midjourney)
  • О мероприятии — описание + 4 статистических карточки
  • Спикеры — 3 карточки с фото и описанием
  • Программа — таймлайн с 9 пунктами (18:00–20:30)
  • Дресс-код — фото-примеры Smart casual
  • Галерея — фото с мероприятия

Дресс-код: от «фестивального стиля» к Smart Casual

Одна из интересных правок по контенту — переосмысление раздела дресс-кода. Изначально стиль назывался «Фестивальный» с фотографиями с Unsplash, которые не очень попадали в образ. После нескольких итераций:

  1. Заменили название на Smart Casual — точнее передаёт дух
  2. Подобрали конкретные фото с Pinterest (3 мужских + 3 женских)
  3. Переписали текстовые описания под новый стиль:

До:

Пиджак с рубашкой, галстук по желанию. Нарядный, но не официальный — фестивальный дух.

После:

Чиносы или брюки, рубашка или поло, пиджак по желанию. Аккуратно, но без галстука — расслабленная элегантность.

Мелочь? Нет. Это формирует ожидания гостей до следующего мероприятия.

Мобильная вёрстка: горизонтальный скролл как решение

Когда открыл сайт на телефоне, стало очевидно: грид из 3-4 колонок на мобилке не работает. Фото сжимаются, карточки спикеров становятся узкими, галерея разваливается.

Решение — горизонтальный скролл со snap-поведением для всех «карусельных» секций. Это паттерн, который работает без JavaScript и библиотек — чистый CSS:

.photo-scroll {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
}
 
.photo-scroll::-webkit-scrollbar {
  display: none;
}
 
.photo-scroll-item {
  flex-shrink: 0;
  scroll-snap-align: start;
  width: 70vw;
}

На мобилке (< md) — горизонтальный скролл с карточками 70-80vw. На десктопе — обычный грид. Такой подход применили к трём секциям: дресс-код мужчины, дресс-код женщины, галерея фотографий, спикеры.

Отдельная проблема — заголовок «НАВСТРЕЧУ К AI» на мобилке. При ширине 375px он не влезал в одну строку. Фикс через clamp():

/* До */
font-size: clamp(2.5rem, 12vw, 10rem);
 
/* После */
font-size: clamp(1.8rem, 9vw, 10rem);

clamp() — один из лучших инструментов для адаптивной типографики. Минимальный размер, предпочтительный (в vw), максимальный. Никаких медиазапросов для размера текста.

Галерея без лайтбокса

Изначально галерея была кликабельной — открывала лайтбокс с увеличенным фото. Но это добавляло лишний код и UX-оверхед для страницы, которая по сути является памятным лендингом.

Убрали весь лайтбокс: useState для открытого фото, обработчики кликов, оверлей — всё ушло. Фото стали просто фото. Сетка на десктопе — 4 колонки, 3 ряда, рассчитанные так, чтобы каждый ряд был заполнен:

Ряд 1: [фото 2 кол.] [фото 1 кол.] [фото 1 кол.] = 4
Ряд 2: [фото 1 кол.] [фото 1 кол.] [фото 2 кол.] = 4  
Ряд 3: [фото 2 кол.] [фото 2 кол.]               = 4

В Tailwind это выглядит через col-span-2 и auto-rows:

<div className="hidden md:grid grid-cols-4 auto-rows-[200px] gap-3">
  <div className="col-span-2 row-span-1">...</div>
  <div className="col-span-1">...</div>
  {/* ... */}
</div>

Деплой на Dokploy: паттерн, который работает

Весь пайплайн деплоя построен вокруг Dokploy — self-hosted PaaS на нашем VPS. Схема стандартная:

  1. Создаём публичный репо на GitHub (bugle-c/18ai)
  2. Создаём приложение в Dokploy через API
  3. Указываем buildType: dockerfile, путь к Dockerfile
  4. Добавляем домен, Dokploy сам берёт Let's Encrypt
  5. Настраиваем GitHub webhook — автодеплой при пуше в master
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
 
FROM node:20-alpine AS runner
WORKDIR /app
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
EXPOSE 3000
CMD ["node", "server.js"]

Ключевой момент, на котором споткнулись: Dokploy по умолчанию ищет Dockerfile в корне, но если buildPath указан как подпапка — путь нужно явно задавать. Пока не указали dockerfilePath: "/Dockerfile", билд падал с Dockerfile not found.

Wildcard DNS *.pashavin.ru уже настроен на VPS, поэтому новый поддомен 18ai.pashavin.ru заработал без дополнительных DNS-правок.

Агент для Dokploy: автоматизация паттернов

После того как задеплоили уже десяток проектов по одному и тому же сценарию, стало очевидно: нужно зафиксировать паттерн. Создали два артефакта:

Скилл dokploy-deploy (~/.claude/skills/dokploy-deploy/SKILL.md) — документация всех API endpoints, auth-схемы, типичных pitfalls и их фиксов. По сути, это TDD для процессов: сначала описываешь что должно происходить, потом это становится инструкцией.

Агент dokploy-deployer (~/.claude/agents/dokploy-deployer.md) — автономный 9-шаговый workflow:

1. Анализ проекта (есть ли Dockerfile, package.json, тип фреймворка)
2. Git init + первый коммит
3. Создание GitHub репо (public для простоты)
4. Создание Dokploy project через API
5. Создание application с правильным buildType
6. Настройка домена + HTTPS
7. Настройка GitHub webhook
8. Добавление в git-auto-sync.sh
9. Push + deploy + мониторинг логов

Теперь деплой нового лендинга занимает минуты, а не итеративные «попробуй вот это» сессии.

Результат

Сайт живёт на https://18ai.pashavin.ru. Что получилось в итоге:

  • Полностью адаптивный лендинг на Next.js 14
  • GSAP-анимации на Hero-секции
  • Горизонтальный скролл на мобилке для всех галерей
  • Автодеплой через GitHub webhook
  • HTTPS из коробки через Let's Encrypt
  • Время от «надо сделать сайт» до рабочего URL — несколько часов

Уроки и выводы

Первый урок: контентные решения важнее технических. Замена «Фестивального стиля» на «Smart Casual» и переписывание двух абзацев заняла больше итераций, чем настройка деплоя. Потому что это влияет на восприятие мероприятия, а не на работу сервера.

Второй урок: горизонтальный скролл — недооценённый паттерн. Большинство разработчиков по умолчанию делают грид и потом мучаются с адаптивностью. Горизонтальный скролл с CSS scroll-snap работает нативно, без JS, без библиотек, и пользователи мобильных приложений отлично понимают свайп.

Третий урок: фиксируй паттерны сразу. Когда ты деплоишь десятый проект по одной схеме, уже поздно документировать — ты всё и так помнишь. Но когда придёт одиннадцатый, или когда к процессу подключится кто-то ещё, отсутствие документации бьёт по времени. Скилл и агент для Dokploy — это инвестиция в следующие деплои.

Четвёртый урок: лендинг мероприятия живёт дольше самого мероприятия. Конференция прошла, онлайн-запись не получилась — но сайт остаётся точкой входа, по которой люди могут узнать что было, кто выступал, каков был формат. Это важнее, чем кажется в момент «надо быстро что-то сделать».

И главное: стек Next.js + Dokploy + GitHub webhooks для таких задач — практически идеален. Нет оверхеда от сложных CI/CD пайплайнов, нет затрат на облачный хостинг, нет vendor lock-in. Просто пуш в main — и сайт обновлён.


Использованные технологии:

Паша Вин
Паша Вин

AI-инженер, предприниматель, маркетолог. Основатель feberra.com и x10seo.ru. 13 лет в перфоманс-маркетинге, 3 года в системной интеграции AI в бизнес.

Связанный проект

AI Content Aggregator