Как запускать свои ИИ-сервисы: Docker для начинающих

Это текстовая версия видео. Если удобнее смотреть — ролик на YouTube, 20 минут. Здесь то же самое, плюс всё для копирования и скачивания: значения переменных, готовая конфигурация Dockhost и docker-compose.yml для своего сервера.
Ты запустишь свой трекер задач с ИИ-ассистентом: в своих Docker-контейнерах, со своей базой данных, на своём адресе и со своим ключом к модели. Программировать не нужно: всё делается мышкой в интерфейсе облака, примерно за 15 минут. Маркетолог, который не пишет код, дошёл по этой инструкции до страницы входа за 12 минут.
Трекер здесь — пример. Главное — схема из пяти частей: образ, контейнер, переменные окружения, диск и маршрут. По ней же поднимаются сотни других готовых сервисов — от веб-аналитики до ИИ-чата для команды.
Что получится
tududi — открытый менеджер задач с ИИ-ассистентом. Мы запустим его в облаке как свой сервис: программа работает у тебя, а не у кого-то другого. Такой подход называют self-hosted.
Из чего состоит связка:
- два контейнера — в одном само приложение, во втором база данных PostgreSQL, где лежат задачи;
- два диска — чтобы данные и файлы не пропадали;
- маршрут — чтобы открыть трекер в браузере по твоему адресу.

Почему два контейнера, а не один
tududi умеет хранить всё в одном файле внутри своего контейнера и может обойтись без внешней базы. Мы всё равно выносим данные в отдельную PostgreSQL по двум причинам:
- приложение можно обновлять и пересоздавать, а задачи остаются в твоей базе и живут отдельно от программы;
- так видно, как контейнеры находят друг друга и работают вместе. Без этого не обойтись в следующих роликах серии.
Вариант попроще, с одним контейнером, — в разделе «Вариант попроще: один контейнер с SQLite».
Что понадобится
- Аккаунт Dockhost и ключ к ИИ-моделям. Как их получить и выбрать модель — в первой статье серии.
- Примерно 15 минут на запуск и ещё несколько на настройку трекера.
- Около 910 ₽ в месяц вместе с ИИ — расчёт в разделе «Сколько стоит».
Я поднимаю всё на Dockhost: у нас на нём прод, и он даёт ресурсы для воркшопов. По каким критериям выбирать провайдера и какие есть альтернативы — в статье «Как выбрать LLM-шлюз». Та же связка запускается на любом сервере с Docker — файл для этого — в разделе «Свой сервер: docker-compose.yml».
Шаг 1. Создай проект
В панели Dockhost создай новый проект и назови его, например, ai-tracker.
Проект — это твой мини-дата-центр. Внутри — своя изолированная сеть, в ней работают контейнеры: виртуальные компьютеры, каждый со своей программой. Контейнеры видят друг друга, к ним можно подключать диски, а из интернета доступно только то, что ты сам откроешь.
Это не аренда виртуального сервера: операционную систему настраивать не нужно, программы ставить тоже. Ты только говоришь, какой контейнер запустить и что ему дать.

Шаг 2. Задай переменные окружения
Настройки передаются программам через переменные окружения — пары «название = значение», которые программа получает при запуске. Базе нужны имя и пароль, а приложению — адрес этой базы.
Открой Окружение → Переменные окружения → Добавить и создай три переменные. У каждой поставь галочку «Глобальная переменная»: такую переменную автоматически получают все контейнеры проекта, и задавать её ещё раз не придётся.
| Переменная | Значение | Зачем |
|---|---|---|
POSTGRES_DB | tududi | Имя базы данных |
POSTGRES_PASSWORD | твой пароль | Пароль базы |
DATABASE_URL | postgres://postgres:ПАРОЛЬ@database/tududi | Адрес базы для tududi |
POSTGRES_DB=tududi
POSTGRES_PASSWORD=ЗАМЕНИ_на_свой_пароль
DATABASE_URL=postgres://postgres:ЗАМЕНИ_на_свой_пароль@database/tududiИмя пользователя базы можно не задавать: тогда PostgreSQL возьмёт стандартное — postgres. Из интернета к базе никто не подключится: снаружи у неё не будет адреса, она доступна только внутри проекта.

Из чего состоит адрес базы
DATABASE_URL — адрес подключения к базе одной строкой:
postgres://— тип базы;postgres— пользователь, стандартный;ПАРОЛЬ— тот же, что вPOSTGRES_PASSWORD;@database— имя контейнера с базой. Внутри проекта контейнеры находят друг друга по имени, как компьютеры в сети. Сам контейнер мы создадим в шаге 4;/tududi— имя базы изPOSTGRES_DB.
В пароле базы не используй символы @ : / #: они сломают эту строку, и приложение не сможет подключиться к базе.
Шаг 3. Создай диски
Контейнер одноразовый: его можно удалить и создать заново за минуту, и всё, что было у него внутри, пропадёт. Поэтому данные хранят на подключаемом диске — в Docker это называется том. Удалишь контейнер — данные останутся на диске, и его можно подключить к новому контейнеру.
В «Обзоре» проекта, в блоке «Сетевые диски», нажми плюс и создай два диска с одинаковыми настройками:
| Имя | Для чего | Тип | Режим | Размер | Цена в месяц |
|---|---|---|---|---|---|
data | База данных | SSD | ReadWriteOnce | 5 GiB | ≈ 79 ₽ |
uploads | Файлы, прикреплённые к задачам | SSD | ReadWriteOnce | 5 GiB | ≈ 79 ₽ |
- ReadWriteOnce — диск подключается только к одному контейнеру. Для базы данных это как раз то, что нужно.
- 5 GiB под базу хватит с запасом на десять тысяч задач. Размер диска для файлов зависит от того, сколько ты прикрепляешь.
- Дешевле: HDD на 3 GiB обойдётся примерно в 23 ₽ в месяц.
Дождись зелёных индикаторов у обоих дисков.

Шаг 4. Запусти контейнер с базой
Сначала база, потом приложение: при запуске tududi сразу подключается к базе, и она должна уже работать.
Образ и контейнер
Образ — упакованная программа со всем, что ей нужно для работы. Контейнер — запущенная копия этого образа. Образы публикуют сами авторы программ в открытых каталогах, самый известный — Docker Hub. Скачал образ — получил готовый сервис, ничего не нужно устанавливать руками.
postgres:16-alpine читается так: программа postgres, версия 16, облегчённая сборка alpine.
Настройки контейнера
Открой Контейнеры → Добавить:
| Поле | Значение |
|---|---|
| Имя | database — ровно то, что стоит в DATABASE_URL |
| Образ | postgres:16-alpine |
| Количество реплик | 1 |
| Ресурсы | По умолчанию: 1 процессор с резервом 20%, 256 MiB памяти |
| Порты | 5432 |
| Переменные окружения | Не добавлять: глобальные из шага 2 база получит сама |
| Сетевые диски | data → /var/lib/postgresql/data |
| Цена | ≈ 247 ₽ в месяц |
- Ресурсы. Для базы личного или командного трекера настроек по умолчанию хватает.
- Порт — номер входа в контейнер; 5432 — стандартный для PostgreSQL. Без открытого порта к контейнеру не подключится никто. Этот порт открыт только внутри проекта: tududi до базы достучится, а из интернета — нет.
- Диск. По пути
/var/lib/postgresql/dataPostgreSQL складывает данные. Благодаря диску они переживут пересоздание контейнера.
Создай контейнер и дождись зелёного индикатора.

Шаг 5. Запусти контейнер с tududi
Снова Контейнеры → Добавить:
| Поле | Значение |
|---|---|
| Имя | tududi-app |
| Образ | chrisvel/tududi:1.5.0 |
| Количество реплик | 1 |
| Ресурсы | По умолчанию: 1 процессор с резервом 20%, 256 MiB |
| Порты | 3002 — на нём tududi открывает веб-интерфейс |
| Переменные окружения | Семь, см. ниже |
| Сетевые диски | uploads → /app/uploads |
| Цена | ≈ 247 ₽ в месяц |

Почему 1.5.0, а не latest
Цифры после двоеточия — версия образа. Часто пишут latest, «последняя», но это не версия, а ярлык. Автор выпустит обновление — и после перезапуска у тебя окажется другая программа, которую с твоими настройками никто не проверял. Поэтому в работе версию фиксируют. В 1.5.0 появилась поддержка PostgreSQL, и на ней проверена эта инструкция. Как переходить на новую версию — в разделе «Как обновлять».
Семь переменных
Скопируй и замени значения на свои:
TUDUDI_USER_EMAIL=твоя@почта.ru
TUDUDI_USER_PASSWORD=ЗАМЕНИ_на_длинный_случайный_пароль
TUDUDI_SESSION_SECRET=ЗАМЕНИ_на_случайную_строку_из_64_символов
TUDUDI_TRUST_PROXY=1
LLM_API_KEY=ЗАМЕНИ_на_свой_ключ
LLM_BASE_URL=https://inference.dockhost.io/v1
LLM_MODEL=google/gemini-3.1-flash-lite| Переменная | Что это |
|---|---|
TUDUDI_USER_EMAIL | Почта администратора — твой логин. Запомни её |
TUDUDI_USER_PASSWORD | Пароль администратора. Трекер будет открыт в интернете, поэтому — длинный и случайный |
TUDUDI_SESSION_SECRET | Ключ, которым tududi подписывает твой вход в браузере. Без него приложение придумывает новый ключ при каждом перезапуске и выкидывает тебя из аккаунта |
TUDUDI_TRUST_PROXY | 1 — трафик из интернета приходит к контейнеру через прокси Dockhost, и эта настройка говорит tududi, что посреднику можно доверять. Без неё вход может сбоить |
LLM_API_KEY | Твой ключ к моделям |
LLM_BASE_URL | Адрес шлюза. Подойдёт любой OpenAI-совместимый провайдер |
LLM_MODEL | Модель из каталога провайдера. google/gemini-3.1-flash-lite для разбора задач хватает, а запрос стоит копейки |
- Секрет сессии проще всего получить в терминале командой
openssl rand -hex 64. Нет терминала — подойдёт любой генератор паролей: 64 символа, латиница и цифры. Значение не должно начинаться с$: Dockhost прочитает его как ссылку на переменную проекта. - Переменные базы сюда добавлять не нужно:
DATABASE_URLглобальная, и tududi подхватит её сам. - Модели с «рассуждениями» для ассистента не бери: они тратят токены на скрытые размышления и могут вернуть пустой ответ (документация tududi).
- Регистрация в tududi по умолчанию закрыта: войти можешь только ты, а коллег добавляешь сам в разделе «Управление пользователями».
Свой ключ к ИИ
tududi не продаёт ИИ по подписке: он обращается к модели с твоим ключом, и ты платишь только за свои запросы. Такой подход называют BYOK — bring your own key, «принеси свой ключ». Подробнее о нём — в посте в Telegram-канале.
Подключи диск uploads по пути /app/uploads, создай контейнер и дождись зелёного индикатора.


Шаг 6. Выведи трекер в интернет
Оба контейнера работают, но пока только внутри проекта: снаружи до них не достучаться. Чтобы открыть tududi в браузере, нужны домен — адрес в интернете — и маршрут, который связывает этот адрес с контейнером.
Домен. Открой «Сетевые сервисы → Домены» и нажми «Добавить». Задай имя — в примере tududi.my — и выбери тип «Динамический»: Dockhost бесплатно выдаст адрес третьего уровня. Как подключить свой домен, читай в конце статьи.
Маршрут. Перейди в «Сетевые сервисы → Маршруты» и нажми «Добавить».
| Поле | Значение |
|---|---|
| Имя | tududi-web |
| Домен | tududi.my — созданный только что |
| Путь | / — все запросы по этому адресу |
| Тип | Внутренний |
| Сетевой сервис | tududi-app |
| Порт | 3002/TCP |
Порт 3002 — тот единственный вход, который ты открыл у контейнера tududi на шаге 5. Маршрут открывает его для всего интернета и стоит 15 ₽ в месяц. У базы маршрута нет, поэтому снаружи виден только трекер.

Теперь вернись в «Домены» и открой карточку домена. В поле «Хост» — адрес твоего трекера, вида rm25-i6rr-0477.gw-1a.dockhost.net. Маршрут обычно подхватывается за 10–15 секунд: если страница не открылась сразу, подожди и обнови её.

Шаг 7. Войди и включи ИИ-ассистента
Открой адрес из поля «Хост». На странице входа введи почту и пароль из переменных TUDUDI_USER_EMAIL и TUDUDI_USER_PASSWORD — это учётная запись администратора.

Это твой собственный трекер: на твоём облачном ресурсе, с твоей базой данных, с ИИ-моделью на твоём ключе и на твоём адресе в интернете. Не сервис по подписке — и для этого не пришлось программировать.
Общие настройки. В профиле открой раздел «Общие»: выбери русский язык, часовой пояс и впиши своё имя. Часовой пояс важен — от него зависят «Сегодня», сроки и утренний бриф. Часть новых разделов пока на английском: переводы ещё догоняют.
ИИ-ассистент. Открой раздел «AI Assistant». Сверху, в блоке «Server Configuration», видно, что ключ, адрес и модель приложение уже получило из переменных шага 5. Если вместо этого видишь «AI is not configured», перезапусти контейнер tududi-app: переменные читаются при старте.
Включи переключатель «AI Assistant (Insights)» — ИИ включается для каждого пользователя отдельно.
Ниже — поле «About You», до 500 символов. Напиши пару строк о себе и о том, каких ответов ждёшь, чтобы советы были по делу. И обязательно добавь требование отвечать на русском, иначе утренний бриф будет приходить на английском. Текст, который можно взять за основу:
Веду в трекере рабочие и личные проекты: маркетинг, запуск сайтов, найм, дела по дому. Жду конкретики: первый шаг, который можно сделать сегодня, реальные риски и сроки, без общих слов.
[Языковые требования]: Все ответы, комментарии, инсайты и УТРЕННИЙ БРИФ (Morning Brief / daily summary) генерируй ИСКЛЮЧИТЕЛЬНО на русском языке. Запрещено использовать английский язык даже в заголовках брифа.Мой вариант — для инженерных задач:
Жду от ассистента конкретных, глубоких инженерных ответов, сфокусированных на продакшен-решениях, архитектурных рисках и практической автоматизации.
[Языковые требования]: Все ответы, комментарии, инсайты и УТРЕННИЙ БРИФ (Morning Brief / daily summary) генерируй ИСКЛЮЧИТЕЛЬНО на русском языке. Запрещено использовать английский язык даже в заголовках брифа.Первую строку перепиши под себя, блок про язык оставь как есть. Нажми «Сохранить изменения».

Что умеет ИИ-ассистент
Разбор задачи
Открой любую задачу и нажми кнопку ИИ — значок с искрами справа, на уровне вкладок. Через пару секунд ассистент раскладывает её по блокам:
- «Об этой задаче» — о чём она и что считать готовым результатом;
- «Следующий шаг» — с чего начать прямо сейчас;
- «Как к этому подойти» — конкретные шаги по порядку;
- «Предложенные ссылки» — материалы по теме;
- «Будьте осторожны» — где обычно ошибаются в подобных задачах.
На скриншоте — задача «Настроить сбор заявок с лендинга в CRM» из проекта «Запуск лендинга под осеннюю акцию». В блоке «Будьте осторожны» ассистент написал: «Обязательно проверьте, как CRM обрабатывает дубли заявок с тем же номером телефона, чтобы при повторной отправке данные не затирались, а обновлялись или создавалась задача на существующего клиента».

Такой разбор стоит около 16 копеек. Ассистент сохраняет ответ: пока не нажмёшь «Сгенерировать заново», повторного запроса и расхода не будет. По тому же принципу ассистент разбирает и целый проект.
Утренний бриф
Главная фишка. Открой «Сегодня»: ассистент смотрит на все задачи сразу и собирает твой день — главный фокус, приоритетные дела с объяснением, почему именно они, и что вот-вот сгорит. Бриф собирается раз в день и тоже сохраняется.
Чтобы бриф был полезным, ему нужен материал: проекты, задачи со сроками, несколько закрытых за последние дни. На пустом трекере советовать нечего. На скриншоте — демо-аккаунт: четыре проекта, чуть больше десятка задач, пара просроченных.

Что ещё умеет tududi
Если ты сейчас в Todoist, TickTick или похожем сервисе, tududi — их полноценная альтернатива. Ты запускаешь его в России и не думаешь о блокировках и VPN — ни сейчас, ни потом. И он работает лично для тебя, со своим ассистентом.
- «Входящие» для быстрых записей, «Сегодня» и «Предстоящие».
- Проекты, собранные в области: например, «Работа» и «Личное».
- Повторяющиеся задачи, подзадачи, заметки, теги.
- На телефон ставится как приложение: открой адрес трекера в браузере телефона и добавь его на главный экран.
- Один трекер подойдёт и небольшой команде: администратор добавляет коллег в «Управлении пользователями», задачи можно назначать исполнителям.
- Задачи можно кидать прямо из Telegram. Как подключить — в посте в Telegram-канале.
И всё это — в твоём контейнере, с ИИ на твоём ключе и открытым кодом. А ещё у tududi есть свой API и MCP, поэтому дальше в серии он станет центром автоматизаций: задачи будут приходить в него сами.
Docker в пяти понятиях
Остановимся и разберёмся, что произошло. Ты взял два готовых образа программ и запустил из них два контейнера в своём мини-дата-центре. Передал им настройки через переменные, подключил диски, чтобы данные хранились отдельно, и вывел один контейнер наружу через маршрут. Это и есть Docker на практике.
| Понятие | Что это | В нашем проекте |
|---|---|---|
| Образ | Готовая упаковка программы со всем, что ей нужно для работы. Берётся из реестра, например Docker Hub | postgres:16-alpine, chrisvel/tududi:1.5.0 |
| Контейнер | Запущенный образ: программа работает изолированно, со своими ресурсами | database, tududi-app |
| Переменные окружения | Настройки, которые программа получает при запуске: пароли, адреса, ключи | POSTGRES_PASSWORD, DATABASE_URL, LLM_API_KEY |
| Диск (том) | Хранилище, которое живёт отдельно от контейнера: контейнер можно пересоздать, данные останутся | data — база, uploads — файлы |
| Маршрут | Правило, которое открывает контейнер в интернет по адресу. Внутри проекта контейнеры находят друг друга по имени без него | tududi-web → tududi-app:3002 |

Любой другой сервис поднимается по той же схеме: найти образ, прочитать в его документации, какие переменные и папки ему нужны, и повторить те же шаги. Если запускать контейнеры на своём сервере, все пять понятий описывают одним файлом — docker-compose.yml. Готовый файл для нашей связки — в следующем разделе.
Вариант попроще: один контейнер с SQLite
Если трекер нужен только тебе, можно обойтись без отдельной базы: по умолчанию tududi хранит данные в SQLite — базе в одном файле в папке /app/db. Чем этот вариант уступает PostgreSQL, см. в разделе «Почему два контейнера, а не один».
Что меняется в инструкции:
- переменные
POSTGRES_DB,POSTGRES_PASSWORDиDATABASE_URLне создавай, контейнерdatabaseне запускай; - диск
dataподключи к контейнеру tududi по пути/app/db, дискuploads— как раньше, к/app/uploads; - остальные переменные tududi те же: почта, пароль, секрет сессии,
TUDUDI_TRUST_PROXYи три переменные ИИ.
Стоимость: один контейнер 247 ₽ + два диска 158 ₽ + маршрут 15 ₽ ≈ 420 ₽ в месяц плюс ИИ.
Важно: если в проекте осталась глобальная переменная DATABASE_URL, tududi попробует подключиться к PostgreSQL и не запустится. В варианте с SQLite её быть не должно.
Готовая конфигурация Dockhost
Всё, что ты накликал, Dockhost хранит одним текстом в формате YAML: «Настройки → Конфигурация». Внутри — переменные, диски, контейнеры и сетевые настройки проекта. Этот текст можно скопировать и поднять ту же связку в другом проекте за минуту.

Как использовать мою конфигурацию:
- Скачай архив dockhost-ai-tracker.zip: внутри файл конфигурации и README с инструкцией. Или скопируй текст ниже.
- Замени все значения
ЗАМЕНИ_…на свои. Пароль базы встречается дважды: вPOSTGRES_PASSWORDи внутриDATABASE_URL. - Создай новый проект, открой «Настройки → Конфигурация», вставь текст и нажми «Применить».
- Проверь домен и маршрут в «Сетевых сервисах»: у нового проекта будет свой адрес в поле «Хост».
- Войди и включи ИИ-ассистента, как в шаге 7.
# Трекер задач tududi 1.5.0 + PostgreSQL 16 на Dockhost — конфигурация из ролика
# «Как запускать свои ИИ-сервисы: Docker для начинающих».
# Инструкция: https://iksanov.com/read/docker-trekker-zadach-s-ii/
#
# Перед применением замени все значения, которые начинаются с ЗАМЕНИ_.
# Пароль базы встречается дважды: в POSTGRES_PASSWORD и внутри DATABASE_URL — впиши одинаковый.
# Заполненный файл содержит пароли и ключ открытым текстом: не публикуй его и не пересылай в чаты.
version: 1
project: ai-tracker
timezone: UTC
# DNS configuration
dns:
nameservers:
- 8.8.8.8
- 8.8.4.4
cache: 30
loadBalance: false
# Environments configuration
environment:
variables:
POSTGRES_DB: tududi
# Пароль базы: латиница и цифры, без символов @ : / # — они ломают DATABASE_URL.
POSTGRES_PASSWORD: ЗАМЕНИ_пароль_базы
# Тот же пароль базы вместо ЗАМЕНИ_пароль_базы. database — имя контейнера с базой, tududi — имя базы.
DATABASE_URL: postgres://postgres:ЗАМЕНИ_пароль_базы@database/tududi
# Volumes configuration
volumes:
uploads:
size: 5Gi
type: ssd
mode: rwo
data:
size: 5Gi
type: ssd
mode: rwo
# Containers configuration
containers:
database:
image: postgres:16-alpine
replicas: 1
strategy: Recreate
resources:
cpu: 1
cpuFraction: 20
memory: 256Mi
ports:
- 5432/TCP
volumes:
- name: data
mountPath: /var/lib/postgresql/data
tududi-app:
image: chrisvel/tududi:1.5.0
replicas: 1
strategy: Recreate
resources:
cpu: 1
cpuFraction: 20
memory: 256Mi
ports:
- 3002/TCP
variables:
# Почта администратора — это логин в трекер.
TUDUDI_USER_EMAIL: ЗАМЕНИ_почта_администратора
# Длинный случайный пароль: трекер будет открыт в интернете.
TUDUDI_USER_PASSWORD: ЗАМЕНИ_пароль_для_входа
# 64 случайных символа: openssl rand -hex 64 или генератор паролей (латиница и цифры).
TUDUDI_SESSION_SECRET: ЗАМЕНИ_секрет_сессии
TUDUDI_TRUST_PROXY: 1
# Ключ к OpenAI-совместимому LLM-шлюзу.
LLM_API_KEY: ЗАМЕНИ_ключ_к_LLM
LLM_BASE_URL: https://inference.dockhost.io/v1
LLM_MODEL: google/gemini-3.1-flash-lite
volumes:
- name: uploads
mountPath: /app/uploads
# Network configuration
network:
domains:
tududi.my: ~
routes:
tududi-web:
domain: tududi.my
path: /
type: internal
service: tududi-app
port: 3002/TCPЗначение, которое начинается со знака $, Dockhost читает как ссылку на переменную проекта. Поэтому свои пароли и секрет с $ не начинай.
Свой сервер: docker-compose.yml
Если у тебя свой сервер или компьютер с Docker, ту же связку описывает один файл. Все пять понятий в нём на месте: image — образ, services — контейнеры, environment — переменные, volumes — диски, ports — вход снаружи.
- Скачай архив tududi-docker-compose.zip и распакуй: внутри
docker-compose.yml,.envи README. Файл.envначинается с точки, поэтому в Finder на macOS он скрыт: Cmd + Shift + . показывает скрытые файлы. - Открой
.envи заполни пустые значения. Пока обязательные значения пустые,docker composeне запустится и подскажет, что заполнить. - В папке с файлами запусти
docker compose up -d. - Открой
http://адрес-сервера:3002(на своём компьютере —http://localhost:3002) и войди с почтой и паролем из.env.
# tududi 1.5.0 + PostgreSQL 16 — тот же набор, что в ролике, для любого сервера с Docker.
# 1. Заполни файл .env рядом с этим файлом.
# 2. docker compose up -d
# 3. Открой http://адрес-сервера:3002 и войди с почтой и паролем из .env.
services:
database:
image: postgres:16-alpine
restart: unless-stopped
environment:
POSTGRES_DB: ${DB_NAME:-tududi}
POSTGRES_PASSWORD: ${DB_PASSWORD:?Заполни DB_PASSWORD в .env}
volumes:
- tududi_pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d ${DB_NAME:-tududi}"]
interval: 5s
timeout: 3s
retries: 10
tududi-app:
image: chrisvel/tududi:1.5.0
restart: unless-stopped
depends_on:
database:
condition: service_healthy
environment:
DATABASE_URL: postgres://postgres:${DB_PASSWORD}@database:5432/${DB_NAME:-tududi}
TUDUDI_USER_EMAIL: ${TUDUDI_USER_EMAIL:?Заполни TUDUDI_USER_EMAIL в .env}
TUDUDI_USER_PASSWORD: ${TUDUDI_USER_PASSWORD:?Заполни TUDUDI_USER_PASSWORD в .env}
TUDUDI_SESSION_SECRET: ${TUDUDI_SESSION_SECRET:?Заполни TUDUDI_SESSION_SECRET в .env}
TUDUDI_TRUST_PROXY: ${TUDUDI_TRUST_PROXY:-false}
LLM_API_KEY: ${LLM_API_KEY:-}
LLM_BASE_URL: ${LLM_BASE_URL:-https://inference.dockhost.io/v1}
LLM_MODEL: ${LLM_MODEL:-google/gemini-3.1-flash-lite}
volumes:
- tududi_uploads:/app/uploads
ports:
- "3002:3002"
volumes:
tududi_pgdata:
tududi_uploads:# Значения для docker-compose.yml. Заполни пустые строки и сохрани файл.
# Пока обязательные значения пустые, docker compose не запустится и подскажет, что заполнить.
# База данных. Пароль базы — латиница и цифры, без символов @ : / # — они ломают адрес подключения.
DB_NAME=tududi
DB_PASSWORD=
# Вход в трекер: почта администратора (это логин) и длинный случайный пароль.
TUDUDI_USER_EMAIL=
TUDUDI_USER_PASSWORD=
# Секрет сессии — 64 случайных символа: openssl rand -hex 64 или генератор паролей (латиница и цифры).
# Без него трекер будет выкидывать из аккаунта после каждого перезапуска.
TUDUDI_SESSION_SECRET=
# Трекер за обратным прокси (nginx, Caddy, Traefik) — поставь 1. Без прокси — false.
TUDUDI_TRUST_PROXY=false
# ИИ-ассистент: ключ, адрес OpenAI-совместимого шлюза и имя модели.
# Без ключа трекер работает, но ИИ-функции не включатся.
# Локальная модель через Ollama: LLM_BASE_URL=http://адрес-ollama:11434/v1 и LLM_MODEL=имя-модели
LLM_API_KEY=
LLM_BASE_URL=https://inference.dockhost.io/v1
LLM_MODEL=google/gemini-3.1-flash-liteПригодится дальше:
# запуск в фоне
docker compose up -d
# логи tududi — первое, куда смотреть, если что-то не так
docker compose logs -f tududi-app
# резервная копия базы в файл
docker compose exec -T database pg_dump -U postgres tududi > backup.sql
# остановить; данные в томах остаются
docker compose downПорт базы наружу не открыт: как и в Dockhost, к ней обращается только tududi внутри общей сети. Если трекер смотрит в интернет, ставь его за nginx или Caddy с HTTPS и включи TUDUDI_TRUST_PROXY=1.
Чем файл отличается от примера автора tududi: зафиксирована версия 1.5.0 вместо latest, пользователь базы — стандартный postgres, как в ролике, добавлены секрет сессии и переменные ИИ. Все переменные tududi — в справочнике.
Сколько стоит
Около 910 ₽ в месяц вместе с ИИ, а в экономном варианте — меньше 600 ₽. Цены — по калькулятору Dockhost на момент записи ролика.
| Что | В месяц |
|---|---|
| Два контейнера: 1 CPU, резерв 20%, 256 MiB | 2 × 247 ₽ = 494 ₽ |
| Два диска SSD по 5 GiB | 2 × 79 ₽ = 158 ₽ |
| Маршрут | 15 ₽ |
| Инфраструктура | ≈ 670 ₽ |
| ИИ: 50 запросов в день по 16 копеек | ≈ 240 ₽ |
| Итого | ≈ 910 ₽ |
Оговорка: 247 ₽ — цена контейнера, пока он укладывается в резерв процессора. Если нагрузка выйдет за резерв, цена вырастет: верхняя граница для таких настроек — 884,16 ₽ в месяц. tududi сейчас берёт тысячные доли ядра, так что запас большой.
Сколько стоит ИИ
Один запрос ассистента на модели google/gemini-3.1-flash-lite стоит в среднем 16 копеек. Тариф: 0,0329 ₽ за 1 тыс. входящих токенов и 0,1974 ₽ за 1 тыс. исходящих. За весь день съёмки ушло 21 тыс. входящих и 5,6 тыс. исходящих токенов — 1,79 ₽. Расход виден в панели: «AI-Платформа → LLM инференс → Потребление».

Ассистент сохраняет ответы: повторно открытый разбор или бриф ничего не стоит. 50 запросов в день — с запасом для одного человека.
Как сэкономить
- HDD вместо SSD для обоих дисков — минус около 110 ₽.
- Резерв процессора 10% вместо 20%: для одного человека хватит.
- Модель попроще.
gemini-2.5-flash-liteпримерно в 3 раза дешевле,qwen3.7-flash— примерно в 10 раз: расход на ИИ упадёт на 160–216 ₽. Модели «с рассуждениями» не бери: с ними инсайты могут приходить пустыми.
В сумме — меньше 600 ₽ в месяц. А вариант с SQLite без отдельной базы — около 420 ₽ плюс ИИ.
Безопасность и данные
Трекер открыт в интернете, а ИИ-ассистент отправляет текст задач провайдеру модели. Особенно важно помнить об этом, если ведёшь в нём рабочие задачи или подключаешь команду.
Пароль. Вход в трекер защищает только пароль, так что ставь длинный и случайный — из генератора паролей. То же для пароля базы и секрета сессии. Регистрация по умолчанию закрыта: чужой человек не сможет завести себе аккаунт.
Что уходит модели. Для разбора и брифа tududi отправляет провайдеру название задачи, статус, сроки, теги, начало заметок, название и описание проекта — подробно в документации tududi. Для обычных задач это нормально. С чувствительными данными, где стоит вопрос информационной безопасности, — осторожнее.
Если данные не должны уходить наружу. Всю схему можно поднять внутри своей инфраструктуры с локальной моделью, например через Ollama или LM Studio. В tududi для этого меняются только адрес и имя модели — переменные LLM_BASE_URL и LLM_MODEL.
Если модель внешняя, выбирай провайдера по тому, где он обрабатывает данные и что с ними делает. Критерии — в статье «Как выбрать LLM-шлюз».
Если что-то не работает
Первое, куда смотреть, — логи контейнера tududi-app: там видно, на чём он споткнулся. Частые случаи:
| Что видишь | Причина | Что сделать |
|---|---|---|
| Страница по адресу не открывается | Маршрут ещё не подхватился или в нём другой сервис и порт | Подожди 10–15 секунд. Проверь в маршруте tududi-app и 3002/TCP |
| Приложение не запускается, в логах ошибка подключения к базе | В пароле базы есть @ : / # или опечатка в имени database | Пароль только из латиницы и цифр. Имя в DATABASE_URL должно совпадать с именем контейнера базы |
| Выкидывает из аккаунта после перезапуска | Не задан TUDUDI_SESSION_SECRET: приложение придумывает новый при каждом старте | Задай секрет и перезапусти контейнер |
В логах ошибка про X-Forwarded-For | tududi работает за прокси, но не доверяет ему | TUDUDI_TRUST_PROXY=1 |
| «AI is not configured» | Переменные ИИ добавлены после запуска, а читаются они при старте | Перезапусти контейнер tududi-app |
| Инсайты приходят пустыми | Модель «с рассуждениями» | Возьми обычную модель в LLM_MODEL |
| Бриф на английском | В About You нет требования к языку | Добавь блок про язык из шага 7 |
Как обновлять
Обновить tududi — значит поменять номер версии в образе. Данные лежат на дисках, а не в контейнере, поэтому при смене образа они остаются.
- Прочитай список изменений новой версии: особенно то, что касается переменных и базы.
- Сделай резервную копию базы.
- В настройках контейнера
tududi-appзамениchrisvel/tududi:1.5.0на номер новой версии. - Перезапусти контейнер и проверь вход, задачи и ИИ-ассистента.
Если новая версия уже поменяла структуру базы, просто вернуть старый номер может не получиться — для этого и нужна копия. А версию базы postgres:16-alpine без нужды не меняй: переход на новую основную версию PostgreSQL требует переноса данных.
Свой домен
Бесплатный адрес третьего уровня годится для пробы. Для постоянной работы удобнее свой домен или поддомен — например, tasks.example.com. Понадобится доступ к DNS-записям домена: у регистратора или DNS-провайдера.
- Открой «Сетевые сервисы → Домены» и нажми «Добавить».
- Заполни форму: имя —
tasks.example.com, тип — «Внешний», имя домена —tasks.example.com. - Домен появится в списке с мигающим индикатором, IP-адресом и статусом «Проверка DNS».
- У регистратора или DNS-провайдера создай для
tasks.example.comA-запись со значением — этим IP-адресом. - Dockhost сам проверяет запись: когда найдёт, индикатор станет зелёным. Обычно это минуты, иногда — несколько часов.
- Создай маршрут так же, как в шаге 6, только в поле «Домен» выбери свой. Ждать конца проверки не нужно: маршрут можно назначить сразу.
На своём домене ставь самые сильные пароли и новый секрет сессии — учебные значения из пробного запуска не переноси.
Что дальше
В следующем ролике по той же схеме поднимем Windmill — наш основной движок автоматизаций. Он заметно сложнее tududi: контейнеров больше, но образы, переменные, диски и маршруты те же. После этой инструкции справишься. А tududi станет в серии центром автоматизаций: через API и MCP задачи будут приходить в него сами.
Между роликами — в Telegram-канале:
- подборки готовых сервисов, которые запускаются по той же схеме: для маркетологов, аналитиков, HR, руководителей;
- как кидать задачи в tududi прямо из Telegram;
- разборы вопросов из комментариев к роликам.
Хочешь так же у себя? Я Артём Иксанов, 18 лет в IT, и такие связки запускаю в проде. Если думаешь, какой процесс переложить на ИИ или какой сервис поднять у себя в команде, напиши мне с задачей на work@iksanov.com. Отвечу, с чего начать.