Захотел блог. Не на Medium, не на Telegram-канале, а свой — с доменом, RSS, Schema.org и Django Admin вместо CMS. Собрал с нуля и задеплоил на продакшн за 40 минут. С помощью Claude Code и Agent Teams.

Как это работало

Написал план в plan mode: структура проекта, модели, API, фронтенд, Docker, nginx. Claude Code запустил команду агентов — несколько параллельных процессов, каждый со своей задачей. Один собирает backend, другой фронтенд, третий Docker-конфиги. Не по очереди, а одновременно.

Agent Teams — это когда Claude Code порождает несколько независимых агентов через Task tool. Каждый работает в своём контексте, не мешает другим. Результаты собираются вместе. В моём случае: один агент изучил паттерны из существующего проекта Villa Metrics (settings.py, Dockerfiles, docker-compose), второй — конфигурацию nginx-proxy. Параллельно. За секунды вместо минут.

40 минут — от пустой папки до работающего https://blog.sovetum.ru с SSL-сертификатом.

Стек: шесть контейнеров для блога

                    blog.sovetum.ru
                         │
                    ┌────┴────┐
                    │  Nginx  │ (SSL, routing)
                    └────┬────┘
              ┌──────────┼──────────┐
              ▼          ▼          ▼
         /api/*     /admin/*       /*
              │          │          │
         ┌────┴──────────┴───┐  ┌──┴──────────┐
         │  Django + Gunicorn│  │  Next.js 14  │
         │  (port 8060)      │  │  (port 3060) │
         └────┬──────────┬───┘  └──────────────┘
              │          │
         ┌────┴───┐ ┌───┴────┐
         │ Postgres│ │  Redis │──► Celery Worker
         │   16   │ │   7    │──► Celery Beat
         └────────┘ └────────┘

Звучит как overkill. Но у меня уже есть паттерн с других проектов (Villa Metrics, Gonka) — Django + Next.js + PostgreSQL + Redis + Celery. Копируешь структуру, меняешь порты, работает.

Шесть контейнеров: - PostgreSQL 16 — посты и теги - Redis 7 — брокер для Celery - Django + Gunicorn — API и админка - Celery Worker — AI-пайплайн (пока заглушки) - Celery Beat — планировщик - Next.js 14 — фронтенд с SSG

Порты: Django на 8060, Next.js на 3060, PostgreSQL на 5460, Redis на 6360. Все на 127.0.0.1 — наружу только через nginx.

Backend за час

Django 5, DRF, модель Post с 15 полями. Самое интересное — pipeline_state JSONField. Это чекпоинт для AI-пайплайна: каждая фаза записывает свой статус, и при повторном запуске завершённые фазы пропускаются.

Markdown рендерится в HTML при сохранении поста. Pygments с темой Monokai для подсветки кода. Количество слов считается автоматически.

RSS-фид чуть не убил полчаса. DRF Response оборачивает XML в JSON-кавычки — получается "<?xml version..." вместо чистого XML. Переключился на django.http.HttpResponse с content_type="application/xml" — заработало.

Frontend: минимализм из принципа

Next.js 14 с App Router. Три зависимости: next, react, react-dom. Ни Tailwind, ни UI-библиотек. Чистый CSS с custom properties и prefers-color-scheme для тёмной темы.

Шрифт — JetBrains Mono. Макет — 640px max-width. Никаких картинок, никаких комментариев, никаких кнопок шеринга. Текст и код.

generateStaticParams пре-рендерит страницы постов при билде. На каждой странице — Schema.org BlogPosting JSON-LD: headline, wordCount, keywords, datePublished. Плюс Open Graph, canonical URL, RSS autodiscovery.

Три бага на деплое

Баг 1: симлинк nginx. Создал абсолютный симлинк для конфига nginx. Снаружи путь /mnt/apps/nginx-proxy/nginx/sites-available/blog.sovetum.ru. Внутри Docker-контейнера этот путь не существует. Посмотрел на существующие симлинки — все относительные: ../sites-available/blog.sovetum.ru. Переделал, заработало.

Баг 2: пароль PostgreSQL. В docker-compose.prod.yml написал POSTGRES_PASSWORD=\${POSTGRES_PASSWORD}. Docker Compose не подставляет переменные из env_file в сам compose-файл — это не Bash. Контейнер БД запустился с пустым паролем. Пришлось удалить volume и пересоздать с env_file: .env.prod.

Баг 3: кеш Next.js. Создал тестовый пост, обновил страницу — «Пока нет постов». SSR с revalidate: 60 — но standalone-билд закешировал пустой ответ при сборке. Перезапуск контейнера помог.

SSL через Docker

Certbot работает через Docker:

docker run --rm \
  -v /etc/letsencrypt:/etc/letsencrypt \
  -v /mnt/apps/nginx-proxy/www:/var/www/html \
  certbot/certbot certonly --webroot \
  -w /var/www/html -d blog.sovetum.ru

Авто-обновление — скрипт по крону каждое воскресенье в 3:00.

Итог

Блог на blog.sovetum.ru. Django REST API, Next.js с SSG, шесть Docker-контейнеров, SSL, RSS, sitemap, Schema.org. 40 минут от пустой папки до продакшна.

Claude Code Agent Teams сделали разницу. Не потому что написали код лучше меня — а потому что делали десять вещей параллельно, пока я пил кофе.