Wiki.js в Docker Compose: готовый файл
Большинство self-hosted вики решают одну задачу — дать команде общее место для документации — но упираются в детали: где хранить историю правок так, чтобы можно было откатиться на конкретный коммит, и как завести вход через корпоративный LDAP или Google-аккаунты без танцев с бубном. Wiki.js закрывает оба вопроса сразу: контент можно синхронизировать с Git-репозиторием, а авторизация поддерживает десяток источников из коробки — от локальных паролей до SAML. Ниже — рабочий docker-compose.yml, разбор мастера установки и настройка этих двух возможностей, ради которых Wiki.js чаще всего и выбирают.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Чем Wiki.js отличается от других вики-движков
Wiki.js написан на Node.js, хранит структуру и метаданные в реляционной БД (по умолчанию PostgreSQL, но поддерживаются MySQL/MariaDB, SQLite и MS SQL Server), а сам контент страниц — как обычный текст, который при желании синхронизируется с внешним Git-репозиторием. Это отличает его от большинства конкурентов, где история правок живёт только внутри БД самого приложения.
| Wiki.js | BookStack | Outline | |
|---|---|---|---|
| Стек | Node.js + PostgreSQL/MySQL | PHP + MySQL/MariaDB | Node.js + PostgreSQL |
| Структура контента | плоская, с деревом папок и тегами | книга → глава → страница | коллекция → документ (вложенность) |
| Редактор | Markdown, визуальный (блочный), HTML | WYSIWYG (TinyMCE) + markdown | markdown с живым предпросмотром |
| Версионирование | встроенное + опциональная синхронизация с Git | встроенное в БД | встроенное в БД |
| Авторизация | локальная, LDAP, OAuth2/OIDC, SAML, Auth0, Azure AD и др. | локальная, LDAP, SAML2 | Google, Slack, OIDC |
| Лицензия | AGPL, self-hosted | MIT, self-hosted | BSL (self-hosted с ограничениями) |
Если команде важна прежде всего строгая иерархия «книга — глава — страница», BookStack окажется удобнее — там навигация встроена в саму структуру. Wiki.js выигрывает там, где нужна гибкость: плоское дерево с тегами легче подстроить под нестандартную организацию контента, а синхронизация с Git превращает вики в что-то среднее между базой знаний и версионируемой документацией разработчика.
Требования к серверу
Node.js-приложение плюс PostgreSQL — стек лёгкий, но не бесплатный по памяти: сама Node.js держит процесс, а Postgres резервирует память под shared_buffers даже при небольшой базе.
| Размер команды | vCPU | RAM | Диск |
|---|---|---|---|
| до 15 человек | 1 | 1-2 ГБ | 15 ГБ |
| 15-50 человек | 2 | 2-4 ГБ | 30 ГБ |
| 50+ человек, много вложений | 2-4 | 4-6 ГБ | от 50 ГБ |
Цифры ориентировочные: на реальный расход диска сильнее всего влияет объём загружаемых изображений и файлов, а не количество текстовых страниц — оно обычно измеряется в мегабайтах даже при тысячах статей.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверГотовый docker-compose.yml
Структура каталогов на сервере:
/opt/wikijs/
├── postgres-data/ # данные PostgreSQL
├── .env
└── docker-compose.yml
Создаём каталоги и файл переменных окружения:
mkdir -p /opt/wikijs/postgres-data
cd /opt/wikijs
nano .env
Содержимое .env — пароль сгенерируйте сами, не берите пример из статьи:
DB_PASSWORD=замените_на_свой_пароль
Сам docker-compose.yml:
services:
db:
image: postgres:16-alpine
container_name: wikijs-db
restart: unless-stopped
environment:
POSTGRES_DB: wikijs
POSTGRES_USER: wikijs
POSTGRES_PASSWORD: ${DB_PASSWORD}
volumes:
- ./postgres-data:/var/lib/postgresql/data
networks:
- wikijs-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U wikijs"]
interval: 10s
timeout: 5s
retries: 6
wiki:
image: ghcr.io/requarks/wiki:2
container_name: wikijs
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
DB_TYPE: postgres
DB_HOST: db
DB_PORT: "5432"
DB_USER: wikijs
DB_PASS: ${DB_PASSWORD}
DB_NAME: wikijs
ports:
- "127.0.0.1:3000:3000"
networks:
- wikijs-net
networks:
wikijs-net:
driver: bridge
Заметьте: у контейнера wiki нет отдельного тома для контента — страницы и настройки хранятся в базе, а не на диске приложения. Это удобно для бэкапа (одна точка вместо двух), но означает, что без синхронизации с Git единственная копия истории правок — сама база PostgreSQL. Порт 3000 смотрит только на 127.0.0.1, наружу отдаём через реверс-прокси — раздел про HTTPS ниже.
Если планируете вынести PostgreSQL на отдельный сервер вместо контейнера рядом, сама установка и настройка описаны в статье про PostgreSQL на VPS — в DB_HOST тогда указывается внешний адрес вместо db.
Первый запуск и мастер установки
Поднимаем стек:
docker compose up -d
docker compose logs -f wiki
Первый старт занимает 20-40 секунд: контейнер wiki ждёт готовности db (за это отвечает healthcheck), затем накатывает миграции схемы. В логах должна появиться строка о том, что сервер слушает порт 3000.
Открываем http://<IP-сервера>:3000 (или домен, если прокси уже настроен) — попадаем в мастер установки:
- Site Info — название сайта и язык интерфейса по умолчанию.
- Admin Account — email и пароль первого администратора. Используйте нормальный пароль сразу, менять его после установки не так удобно, как в других движках.
- Telemetry — Wiki.js спрашивает разрешение на отправку анонимной статистики использования; можно отключить без последствий для работы.
После завершения мастера попадаете на пустую главную страницу — контент создаётся через + New Page в правом нижнем углу, с выбором редактора (Markdown или визуальный) прямо в диалоге создания страницы.
Версионирование контента через Git
Ключевая особенность Wiki.js — модуль Storage (Администрирование → Storage), который умеет синхронизировать содержимое страниц с внешним репозиторием параллельно с хранением в базе. По сути это второй источник правды: база остаётся рабочей копией для быстрого рендеринга, а Git получает каждый коммит при сохранении страницы.
Настройка через админку:
Администрирование → Storage→ включаем модуль Git.- Указываем URL репозитория (GitHub, GitLab, Bitbucket или собственный Git-сервер), ветку и способ авторизации — SSH-ключ или токен доступа.
- Задаём режим синхронизации: Push (Wiki.js отправляет изменения при каждом сохранении страницы), Pull (подтягивает изменения из репозитория — полезно, если кто-то правит файлы напрямую), либо оба направления сразу.
Если для этого нужен собственный Git-сервер, а не внешний GitHub/GitLab, рабочий вариант — поднять Gitea на VPS: лёгкий сервер, которого для хранения markdown-файлов вики более чем достаточно.
Практическая польза от такой синхронизации — не только резервная копия. Каждая страница в репозитории лежит обычным .md-файлом с метаданными в frontmatter, поэтому историю правок можно смотреть через git log, а откат к старой версии страницы — это git revert конкретного коммита, а не борьба с внутренним UI истории версий (хотя такой UI в Wiki.js тоже есть — Page → View Source → History, для правок, откатов и просмотра diff без выхода из интерфейса).
Из ограничения стоит знать: удаление страницы из вики не всегда синхронно удаляет файл из репозитория — поведение зависит от режима, поэтому первое время после включения модуля стоит проверять репозиторий вручную, а не полагаться на него вслепую.
Источники авторизации: локальные пользователи, LDAP, OAuth2, SAML
Второй пункт, ради которого выбирают Wiki.js, — гибкость входа. Настройка идёт через Администрирование → Login, где можно включить сразу несколько провайдеров параллельно (пользователь на экране входа выбирает, каким способом заходить):
- Local — email и пароль, хранятся в базе Wiki.js с хешированием. Подходит для небольших команд без внешнего каталога пользователей.
- LDAP / Active Directory — указывается адрес сервера, base DN, атрибуты для маппинга имени и email. Полезно, когда в компании уже есть корпоративный каталог и не хочется дублировать учётки.
- OAuth2 / OIDC — готовые пресеты для Google, GitHub, Microsoft Azure AD, Auth0, Okta, Discord и других, плюс generic OAuth2/OIDC для произвольного провайдера — достаточно указать Client ID, Client Secret и endpoint'ы авторизации.
- SAML 2.0 — для интеграции с корпоративными SSO-системами (Okta, OneLogin, ADFS и подобными), которые SAML используют вместо OAuth2.
Каждый провайдер настраивается отдельным блоком: можно, например, разрешить регистрацию только через корпоративный OAuth2-домен, а логин-пароль оставить исключительно для служебной записи администратора — флагом Registration у конкретного провайдера, а не глобальной настройкой.
Права доступа настраиваются отдельно в Администрирование → Groups — можно ограничить видимость разделов дерева страниц по группам, независимо от способа входа пользователя.
HTTPS через реверс-прокси, бэкап и обновление
Отдавать вход по HTTP нельзя — куки сессии и пароль администратора пойдут открытым текстом. Проще всего закрыть это Caddy с автоматическим Let's Encrypt:
# /etc/caddy/Caddyfile
wiki.your-domain.example {
reverse_proxy 127.0.0.1:3000
}
Если Caddy на сервере ещё не настроен, есть отдельный разбор установки Caddy с авто-SSL на VPS. После того как домен заработал по HTTPS, зайдите в Администрирование → General и поправьте Site URL на реальный https:// адрес — Wiki.js использует его для генерации ссылок и для корректной работы OAuth2/SAML redirect URI, которые провайдеры сверяют строго.
Резервное копирование сводится к дампу PostgreSQL — весь контент, настройки и группы пользователей живут в базе:
docker exec wikijs-db pg_dump -U wikijs wikijs > /opt/wikijs/backups/wikijs-$(date +%F).sql
Восстановление:
docker exec -i wikijs-db psql -U wikijs wikijs < /opt/wikijs/backups/wikijs-2026-08-15.sql
Если включена синхронизация с Git, репозиторий уже работает как вторая копия контента — но настройки и права доступа он не хранит, дамп базы всё равно нужен. Для регулярного автоматического бэкапа удобнее общий пайплайн, например через BorgBackup в Docker Compose, а не разовый cron-скрипт под один сервис.
Обновление — стандартный pull + up:
docker compose pull wiki
docker compose up -d wiki
Миграции схемы БД накатываются автоматически при старте новой версии контейнера. Перед обновлением на мажорную версию стоит сделать свежий дамп и заглянуть в changelog проекта — как и у любого приложения с автоматическими миграциями, откатиться на предыдущую версию после неудачной миграции штатными средствами не получится.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли использовать SQLite вместо PostgreSQL, чтобы не поднимать отдельный контейнер БД?
Да, Wiki.js поддерживает SQLite (DB_TYPE: sqlite, с томом под файл базы вместо сервиса db). Для тестового стенда или совсем маленькой команды это упрощает конфиг, но для продакшена с несколькими одновременными редакторами PostgreSQL надёжнее — SQLite хуже переносит параллельную запись.
Что произойдёт с содержимым страниц, если удалить контейнер wiki?
Ничего — сам контейнер не хранит данные, весь контент в базе db. Удалять и пересоздавать контейнер приложения безопасно в любой момент, если не трогать volume postgres-data.
Как перенести существующую вики на markdown-файлах в Wiki.js?
Проще всего через модуль Git из раздела выше в режиме Pull: указываете репозиторий с готовыми .md-файлами, и Wiki.js импортирует их как страницы при первой синхронизации. Структура папок репозитория при этом становится структурой дерева страниц.
Визуальный редактор и Markdown-редактор можно использовать вперемешку на разных страницах?
Да, выбор редактора делается индивидуально при создании каждой страницы, конфликтов между страницами с разными редакторами нет — они хранятся как обычный markdown/HTML-текст независимо от того, чем создавались.
Нужен ли Redis или другой кэш для нормальной работы?
Нет, для типового объёма Wiki.js обходится без внешнего кэша — рендеринг markdown в HTML достаточно быстрый на лету. Отдельный кэш имеет смысл рассматривать только при очень большом трафике на чтение, что для внутренней документации компании редкость.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →