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

Конференция прошла, контент был огонь, но техничка подвела — онлайн-запись ушла в брак. Зато осталось кое-что поважнее: нужно было зафиксировать событие, сохранить его дух и дать людям место, куда можно отправить ссылку. Так появился проект 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, которые не очень попадали в образ. После нескольких итераций:
- Заменили название на Smart Casual — точнее передаёт дух
- Подобрали конкретные фото с Pinterest (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. Схема стандартная:
- Создаём публичный репо на GitHub (
bugle-c/18ai) - Создаём приложение в Dokploy через API
- Указываем
buildType: dockerfile, путь к Dockerfile - Добавляем домен, Dokploy сам берёт Let's Encrypt
- Настраиваем 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 →