Wiki.js 3 — выбор, установка и настройка Lesin Wiki
Статус: действующая конфигурация и журнал решений по состоянию на 4 ноября 2026 года.
Адрес: https://wiki.lesin.net/
Версия при первоначальной установке: Wiki.js3.0.2, PostgreSQL18.
Назначение: личная и совместная база знаний вместо wiki в Redmine.
Важно о публичности: эта инструкция содержит внутренние адреса, схему серверов и сведения об инфраструктуре. Владелец выбрал публичность страниц по умолчанию. Прежде чем публиковать статью для гостей, проверьте, что её содержание допустимо раскрывать, либо ограничьте доступ к этой конкретной странице.
1. Зачем понадобилась отдельная wiki
Исходная wiki в Redmine перестала устраивать как основное хранилище документации. Нужна самостоятельная, достаточно лёгкая система без постоянной ручной возни с зависимостями и обновлениями.
Требования, сформулированные при выборе:
- Современный Markdown: заголовки, таблицы, ссылки, подсветка кода, примечания, диаграммы.
- Удобная структура: страницы и вложенные страницы без жёсткого ограничения по типу «книга → глава → страница».
- Вложения: загрузка изображений, архивов и других файлов, управление ими и правами доступа.
- Авторизация: локальные учётные записи, группы, возможность подключения других способов входа.
- Разграничение чтения: отдельно для гостей и зарегистрированных пользователей; возможность закрыть конкретную страницу независимо от положения в дереве.
- Диаграммы: как текстовые Mermaid (аналог GitHub), так и редактируемые мышкой, наподобие Microsoft Visio (diagrams.net/draw.io).
- Self-hosted: запуск на своём Debian-сервере, интеграция с существующими Nginx, Anubis и HTTPS.
- Минимум обслуживания: предпочтительно предсказуемые обновления и резервное копирование.
Важный нюанс: доступ к фрагментам страницы
Первоначально рассматривалось также разграничение прав на отдельные абзацы или секции одной страницы. Это не эквивалентно запрету чтения страницы целиком.
В Wiki.js 3 правила доступа применяются к страницам по группам, путям, шаблонам и тегам. Встроенного отдельного ACL на произвольный абзац внутри одной Markdown-страницы как подтверждённой функции не обнаружено. Если нужно действительно скрывать часть материала от гостей, безопаснее вынести её в отдельную страницу с ограниченным доступом. CSS-скрытие, условное отображение на клиенте и «спрятанные» HTML-блоки не заменяют проверку прав на сервере.
2. Какие системы сравнивали
| Система | Плюсы | Минусы применительно к этой задаче |
|---|---|---|
| BookStack | Очень понятный интерфейс, зрелая модель ролей, права на конкретные страницы; штатный diagrams.net, Markdown-редактор; PHP + MariaDB. | Структура ориентирована на книги/главы/страницы; меньше гибкости для произвольной технической иерархии; Mermaid не так органично встроен, как в Wiki.js 3. |
| Wiki.js 3 | Современный Markdown, произвольные вложенные пути, развитые правила доступа, Mermaid, draw.io, Excalidraw, PlantUML/Kroki, поиск, файлы, история. | Функций больше — админка сложнее; версия 3 на момент установки относительно новая, поэтому изменения и дефекты нужно отслеживать. |
| An Otter Wiki | Очень лёгкая установка, Markdown, история через Git, Mermaid. | Для нужных сценариев не хватало подтверждённых гибких правил доступа к отдельным страницам. |
| Docmost | Современное оформление, удобный визуальный редактор и диаграммы. | Детальное разграничение прав связано с коммерческими возможностями; более многокомпонентная инфраструктура (в частности, PostgreSQL/Redis). |
Отдельная особенность BookStack: можно повторно вставлять содержимое других страниц/блоков с проверкой прав доступа к источнику; это удобный обходной путь для ситуаций, когда части документа рассчитаны на разные аудитории, но не прямой ACL произвольного абзаца.
Решение: выбрана Wiki.js 3. Решающими стали гибкая структура технических материалов, Markdown, несколько форматов диаграмм и детальные правила чтения/изменения страниц. BookStack остался наиболее близкой альтернативой, если когда-либо важнее станет простота, а не свобода структуры и редакторов.
Ресурсы: Wiki.js, документация Wiki.js 3, BookStack — диаграммы, BookStack — роли.
3. Возможности Wiki.js 3
3.1. Редакторы и разметка
При создании главной страницы предлагаются три режима:
- Markdown Editor — выбран для этой базы знаний; подходит для команд, кода и структурированной документации.
- Visual Editor — визуальное редактирование без ручного набора разметки.
- AsciiDoc Editor — альтернативный формат текстовой документации.
Поддерживаются вложенные страницы, поиск, история версий, просмотр исходного текста/истории с учётом разрешений, совместное редактирование Markdown (при включённой функции).
Важное различие с хранением .md на диске: Wiki.js принимает и редактирует Markdown, но по умолчанию хранит материалы в PostgreSQL, а не как независимый набор файлов .md в каталоге сервера. Если понадобятся внешняя синхронизация или файловое хранение, их нужно проектировать отдельно.
3.2. Диаграммы как в Visio
| Инструмент | Для чего | Как устроен |
|---|---|---|
| Mermaid | Блок-схемы, последовательности, состояния, ER, Gantt | Исходник пишется текстом, wiki строит изображение. |
| draw.io / diagrams.net | Сетевые схемы, серверы, архитектура, UML, произвольные фигуры | Мышкой в визуальном редакторе; схема хранится в редактируемом XML. |
| Excalidraw | Эскизы и объясняющие схемы в стиле виртуальной доски | Визуальное редактирование; в Wiki.js 3 предусмотрен отдельный редактор. |
| PlantUML / Kroki | Диаграммы, определяемые текстом | Используются специальные блоки; конкретные расширения и внешние сервисы стоит проверять в настройках. |
Mermaid в Wiki.js 3: не следует рассчитывать, что любой обычный кодовый блок с языком mermaid автоматически превратится в диаграмму. Документация третьей версии задаёт специальный контейнер block-diagram:
::block-diagram
```mermaid
flowchart LR
Client[Посетитель] --> Proxy[Nginx + Anubis]
Proxy --> Wiki[Wiki.js]
Wiki --> DB[(PostgreSQL)]
```
::
Draw.io в Wiki.js 3: используется блок block-drawio с XML-содержимым. Он поддерживает редактирование диаграммы на холсте. В параметре server можно указать собственный сервер diagrams.net; если оставить пустым, используется публичный draw.io. Для схем внутренней сети приватный собственный экземпляр редактора может быть предпочтительнее.
Документация: Mermaid / Diagram, Draw.io, синтаксис блоков при переходе на 3.x.
3.3. Пользователи и файлы
- Локальная авторизация по email и паролю доступна из коробки; есть другие способы аутентификации через провайдеров.
- Управление доступом — через группы и их
Page Rules. - Права на просмотр вложений (
View Assets) и на загрузку (Upload Assets) различаются. - По умолчанию база данных хранит содержимое и ресурсы, если не настроено другое хранилище в Administration → Storage.
- В админке имеются настройки общих возможностей: поиск, просмотр дерева, комментарии, совместное редактирование, оценки.
4. Принятая схема размещения
| Узел | Роль | Адрес / порт |
|---|---|---|
| server4 | Внешний Nginx, TLS/Let's Encrypt, вход через существующий Anubis | wiki.lesin.net:443, Anubis 127.0.0.1:8001 |
| server1 | Внутренний Nginx, маршрутизация виртуальных хостов по Host |
192.168.0.141:443 |
| server1 | Docker: Wiki.js 3 | порт хоста 8081 → порт контейнера 3000 |
| server1 | Docker: PostgreSQL 18 | 5432 только внутри Docker-сети, наружу не опубликован |
| OPNsense | Существующая внешняя маршрутизация/NAT к reverse proxy | Точные правила не изменялись в рамках установки wiki |
Интернет / браузер
|
| HTTPS https://wiki.lesin.net/
v
server4: Nginx :443 (внешний TLS)
|
| proxy_pass http://127.0.0.1:8001
v
server4: Anubis (антибот-проверка)
|
| общий upstream на server1; сохраняется Host: wiki.lesin.net
v
server1: Nginx :443 (внутренний HTTPS-vhost)
|
| proxy_pass http://127.0.0.1:8081
v
server1: Docker Wiki.js :3000
|
v
server1: Docker PostgreSQL :5432
Примечание о факте проверки: домен, Docker, сертификат и внешний проброс были запущены в ходе настройки. Маршрут через Anubis потребовал отдельного vhost на server1. Окончательную проверку всех действий через всю цепочку, включая загрузку файлов и WebSocket, следует выполнить отдельно; из переписки нельзя считать её полностью завершённой.
5. Почему Docker, а не установка в Debian напрямую
Wiki.js можно устанавливать не только через Docker: официально поддерживается установка из архива с Node.js и systemd. Но в данном окружении выбрали Docker Compose, чтобы не обслуживать отдельную версию Node.js и зависимости вручную. Сами Nginx и Anubis уже существуют вне этих двух контейнеров.
Плюсы подхода:
- два контейнера (
wikiиdb) и одна понятная конфигурация; - воспроизводимый запуск с конкретными версиями;
- отдельная постоянная база данных;
- запуск после перезагрузки (
restart: unless-stopped); - обновления через Compose, без установки Node.js на хост.
Важный минус: Docker сам по себе не заменяет резервные копии PostgreSQL.
6. Установка на server1: Docker Compose
Ниже зафиксирован использованный вариант с портом 8081, а не абстрактный шаблон. Пароли в статье не приводятся.
6.1. Каталог и переменные окружения
На server1 под root:
mkdir -p /opt/wiki
cd /opt/wiki
umask 077
printf 'DB_PASS=%s\nADMIN_PASS=%s\nADMIN_EMAIL=admin@example.com\n' \
"$(openssl rand -hex 24)" \
"$(openssl rand -hex 24)" > .env
chmod 600 .env
nano .env
Заменить admin@example.com на реальный адрес администратора. Не публиковать .env, не вставлять его содержимое в wiki и не пересылать пароли в переписке. ADMIN_PASS применяется при первоначальном создании администратора, а не принудительно меняет пароль при каждом запуске.
6.2. /opt/wiki/compose.yaml
services:
db:
image: postgres:18
restart: unless-stopped
environment:
POSTGRES_DB: wiki
POSTGRES_USER: wiki
POSTGRES_PASSWORD: ${DB_PASS}
volumes:
- wiki-db:/var/lib/postgresql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U wiki -d wiki"]
interval: 5s
timeout: 5s
retries: 20
wiki:
image: ghcr.io/requarks/wiki:3.0.2
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
ADMIN_EMAIL: ${ADMIN_EMAIL}
ADMIN_PASS: ${ADMIN_PASS}
DB_HOST: db
DB_PORT: 5432
DB_NAME: wiki
DB_USER: wiki
DB_PASS: ${DB_PASS}
ports:
- "8081:3000"
volumes:
wiki-db:
Здесь wiki-db — постоянный именованный Docker volume. У PostgreSQL 18 точка монтирования в этом Compose — /var/lib/postgresql (не путать с путём для некоторых предыдущих версий PostgreSQL).
6.3. Запуск и диагностика
cd /opt/wiki
docker compose config --quiet
docker compose pull
docker compose up -d
docker compose ps
docker compose logs --tail=100 wiki
Временный доступ для проверки без внешнего Nginx:
http://192.168.0.141:8081/
Именно HTTP, а не HTTPS: TLS завершается на Nginx. Первые логин/пароль — из .env.
6.4. Почему порт 8081
Изначально был выбран 8080:3000, но Docker не смог создать контейнер:
failed to bind host port 0.0.0.0:8080/tcp:
address already in use
Порт 8080 оказался занят существующим сервисом; ничего отключать не стали. В Compose изменили публикацию на:
ports:
- "8081:3000"
Применили docker compose up -d — Wiki.js открылась на http://192.168.0.141:8081/.
Полезные команды для занятых портов:
ss -lntp | sort -V
ss -H -ltn '( sport = :8081 )'
docker ps --format 'table {{.Names}}\t{{.Ports}}'
6.5. Ошибка Firefox при неправильном протоколе
Во время первой проверки по 192.168.0.141:8080 Firefox показал:
SSL_ERROR_RX_RECORD_TOO_LONG
Это происходило при попытке говорить HTTPS с портом, обслуживающим только HTTP, и само по себе не свидетельствует о неисправности сертификата wiki. Для прямого подключения к контейнеру использовать http://192.168.0.141:8081/; для публичного сайта — https://wiki.lesin.net/ через Nginx. Также проверять настройки HTTPS-Only в браузере.
Рекомендация по защите (не обязательно уже применена): поскольку снаружи к Wiki.js обращается локальный Nginx на том же server1, можно в дальнейшем ограничить публикацию контейнерного порта loopback-адресом:
ports:
- "127.0.0.1:8081:3000"
После этого прямой доступ к 192.168.0.141:8081 перестанет работать, но proxy_pass http://127.0.0.1:8081 на server1 продолжит работать. Вносить изменение следует только после проверки всей цепочки прокси.
7. Домен, DNS и причина отказа от /wiki
Сначала планировался адрес https://lesin.net/wiki/. Для Wiki.js 3 установка в подпапку официально не поддерживается: это усложняет маршруты, ссылки на ресурсы и работу веб-приложения. От переписывания ссылок JavaScript и HTML через Nginx отказались.
Итоговый адрес:
https://wiki.lesin.net/
Никаких редиректов с lesin.net/wiki/ не создавали по желанию владельца.
DNS: поддомен wiki направляется на тот же внешний reverse proxy, который обслуживает другие сайты. В качестве варианта рассматривалась запись CNAME wiki → lesin.net, если основной домен указывает на тот же внешний адрес.
Проверка:
dig +short wiki.lesin.net
Документация: Почему Wiki.js не работает из подпапки.
8. Внешний Nginx на server4
Файл: /etc/nginx/sites-enabled/wiki.lesin.net.conf (именно с расширением .conf, как было выбрано при установке).
Сертификат для wiki.lesin.net создан Certbot на внешнем Nginx. Полный файл содержит TLS-настройки и директивы Certbot, поэтому ниже дан существенный фрагмент рабочего маршрута, который нужно помещать в существующий server на 443, не затирая выданный сертификат.
server {
listen 443 ssl;
server_name wiki.lesin.net;
# Указать реальные пути, которые создал Certbot на server4.
ssl_certificate /etc/letsencrypt/live/wiki.lesin.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/wiki.lesin.net/privkey.pem;
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:8001;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
Примечания:
- Это образец для документации, не снимок фактического файла (пути Certbot и другие SSL-директивы следует сверять с сервером).
- На
server4Anubis уже слушал127.0.0.1:8001и использовался дляlesin.netи других доменов, включаяrealax.ru. Новый экземпляр Anubis не создавали. - Для корректной маршрутизации важно сохранять исходный
Host: wiki.lesin.netдо внутреннего виртуального хоста. - Предыдущий фильтр по
Refererвстречался в конфигурации других сайтов, но не является надёжной защитой: его можно подделать. Не полагаться на него как на механизм контроля доступа. - При нескольких прокси нужно дополнительно проверить, правильно ли до приложения дошли внешний HTTPS, адрес клиента и WebSocket Upgrade. На практике более аккуратно отправлять
Connection: upgradeтолько при настоящем WebSocket-запросе (черезmapв контекстеhttp).
Проверка Nginx:
nginx -t && systemctl reload nginx
Сертификат для внешнего Nginx получали командой (после настройки DNS):
certbot --nginx -d wiki.lesin.net
Это команда для первоначального выпуска/настройки, не нужно повторять её без необходимости.
9. Anubis и внутренний Nginx на server1
9.1. Почему одной настройки на server4 было недостаточно
Anubis выступает как антибот-прокси с заданным upstream/TARGET. Он не обязан самостоятельно перенаправлять каждый домен на произвольный порт приложения. Существующая связка с другими сайтами работала благодаря виртуальным хостам внутреннего Nginx, которые маршрутизируют запросы по заголовку Host.
На server1 не было server_name wiki.lesin.net, поэтому при включении Anubis запрос мог попадать не в Wiki.js. Для исправления добавили отдельный HTTPS-vhost на server1.
9.2. Внутренний HTTPS-vhost на server1
Файл: /etc/nginx/sites-enabled/wiki.lesin.net.conf.
server {
listen 443 ssl;
server_name wiki.lesin.net;
# Здесь должны стоять существующие и действительные
# пути к сертификату НА server1.
ssl_certificate /etc/letsencrypt/live/lesin.net/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lesin.net/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_session_timeout 60m;
client_max_body_size 100M;
location / {
proxy_pass http://127.0.0.1:8081;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_buffering off;
proxy_request_buffering off;
proxy_read_timeout 300s;
proxy_send_timeout 300s;
}
}
Критично для TLS: путь /etc/letsencrypt/live/lesin.net/... был использован как пример на основании существующего внутреннего домена. Не следует считать, что сертификат lesin.net обязательно покрывает wiki.lesin.net: это определяется его SAN-именами, либо wildcard-сертификатом. При включённой проверке сертификатов у Anubis нужно, чтобы имя, на которое он подключается (SNI), и сертификат были согласованы. Не отключать TLS-проверку лишь ради обхода несовпадения, если можно правильно настроить внутренний сертификат и SNI.
Проверка SAN сертификата на server1:
openssl x509 -in /etc/letsencrypt/live/lesin.net/fullchain.pem \
-noout -subject -ext subjectAltName
Проверка самого виртуального хоста (временно -k, только для диагностики, если сертификат ещё не настроен на правильный хостнейм):
curl -kI --resolve wiki.lesin.net:443:127.0.0.1 \
https://wiki.lesin.net/
Проверка конфигурации:
nginx -t && systemctl reload nginx
9.3. Реальная ошибка: конфликт SSL shared cache
При проверке nginx -t на server1 получено:
[emerg] the size 10485760 of shared memory zone "SSL"
conflicts with already declared size 52428800
in /etc/nginx/sites-enabled/wiki.lesin.net.conf:10
Причина: другие виртуальные хосты уже задавали зону shared:SSL размером 50 МБ, а новый конфиг запросил для неё 10 МБ.
Исправление состояло в удалении повторной строки из конфига wiki, не затрагивая другие сайты:
sed -i '/ssl_session_cache shared:SSL:10m;/d' \
/etc/nginx/sites-enabled/wiki.lesin.net.conf
nginx -t && systemctl reload nginx
Дополнительно Nginx выдавал предупреждения, не блокирующие запуск:
- устаревший синтаксис
listen ... http2в другом виртуальном хосте; - повторные объявления
TLSv1,TLSv1.1,TLSv1.2в существующих SSL-настройках.
Их не следует путать с фатальным конфликтом зоны памяти. Устаревшие протоколы TLS стоит устранить отдельно, после аудита общего конфига.
9.4. Реальная ошибка: неверное имя файла
Первоначально Nginx на server4 не запускался, потому что искал несуществующий файл:
open() "/etc/nginx/sites-enabled/wiki.lesin.net" failed (2: No such file or directory)
На самом деле конфигурация была сохранена как wiki.lesin.net.conf, а ссылка wiki.lesin.net оказалась битой.
Диагностика:
ls -l /etc/nginx/sites-enabled/wiki.lesin.net*
Исправление, только если путь wiki.lesin.net — битая символьная ссылка:
rm /etc/nginx/sites-enabled/wiki.lesin.net
nginx -t
Файл .conf оставили на месте. Не удалять другие конфигурации и не переименовывать без необходимости.
10. Настройки приложения после первого входа
10.1. General
Раздел: Administration → General.
| Поле | Принятое/рекомендуемое значение |
|---|---|
| Site Title | Lesin Wiki |
| Site Hostname | wiki.lesin.net (без https:// и без /) |
| Allow Browsing | Включить, если нужно дерево доступных страниц |
| Allow Search | Включить |
| Allow Collaborative Editing | Включить, если требуется совместное редактирование |
| Allow Comments | На старте можно выключить |
| Allow Ratings | На старте выключить |
| Allow Profile Editing | Включить для локальных аккаунтов |
| Reason for Change | По желанию |
Важно: это рекомендации из настройки, а не подтверждение, что каждый переключатель уже фактически сохранён. Проверять текущие значения следует в админке.
10.2. Security / обратные прокси
Раздел: Administration → Security.
Включить Trust X-Forwarded- Proxy Headers*, поскольку приложение расположено за внешним Nginx, Anubis и внутренним Nginx. Это важно для правильного определения HTTPS, перенаправлений и IP пользователя.
Предостережение: доверять заголовкам прокси безопасно, только если сама Wiki.js не принимает произвольный трафик из интернета в обход доверенной цепочки и прокси корректно контролируют эти заголовки. Приоритет — ограничить порт 8081 локальным интерфейсом, когда прямой доступ больше не нужен.
Желательно настроить 2FA для аккаунта администратора и хранить уникальные пароли вне самой wiki.
Документация: General, Authentication / Reverse Proxies, Permissions.
11. Права доступа: выбранная модель «публично по умолчанию»
После обсуждения принято решение: любая обычная страница — доступна гостям по умолчанию, независимо от расположения. Закрывать страницы планируется индивидуально, по мере необходимости. Специальные каталоги public, servers, private не нужны: они были только примерами, реальная структура ещё не утверждена.
11.1. Где настраивать
Administration → Groups → Guests → Page Rules.
В Wiki.js 3 правила задаются группам, а не непосредственно переключателем «приватно» на каждой странице.
11.2. Общее правило гостей
В Default Rule:
| Параметр | Значение |
|---|---|
| Enforcement Mode | Allow |
| Read Pages | Включить |
| View Assets | Включить |
| Write Comments | Выключить, если не нужны анонимные комментарии |
| Site Filter | Any Site |
| Locale Filter | Any Locale |
| Matching Pattern | Path Starts With... |
| Path | Пустое значение — если интерфейс принимает его как правило на весь сайт |
Сохранить сначала Apply для выбора разрешений, затем изменения самой группы. Не путать цвета переключателей внутри Deny: включённое разрешение в Deny означает, что запрещается именно эта операция!
После сохранения проверить главную страницу в приватном окне Firefox (гость, не вошедший в Wiki.js). Если область действия пустого пути работает иначе в конкретной сборке, подобрать глобальный шаблон через интерфейс и проверить результат на тестовой странице; не публиковать секретные материалы, пока проверка не завершена.
11.3. Как закрыть конкретную страницу
В группе Guests добавить новое Deny-правило:
| Параметр | Значение |
|---|---|
| Enforcement Mode | Deny |
| Permissions | Read Pages, View Assets |
| Matching Pattern | Path is Exactly |
| Path | Точный путь страницы, без ведущего / |
Для запрета всего подраздела используется Path is Exactly... + Children.
Более конкретный путь и более точный шаблон имеют приоритет над общим разрешением. При одинаковой специфичности Deny перекрывает Allow, а Force Allow может иметь приоритет выше. Порядок специфичности описан в документации по правам.
Если страницу требуется закрыть не только гостям, но и некоторым зарегистрированным пользователям, аналогичные ограничения нужно проверить в их группах. При членстве пользователя в нескольких группах права могут взаимодействовать.
Проверка безопасности: открывать адрес закрытой страницы без авторизации и от пользователя каждой нужной группы; отдельно проверять прямые URL вложений, картинки, поиск, исходный текст и историю. Наличие страницы в меню или отсутствие ссылки не равно ограничению доступа.
11.4. Ограничение доступа к части страницы
Правила Page Rules привязаны к страницам и их атрибутам, а не к отдельным Markdown-секциям. Надёжный вариант для чувствительных фрагментов: отдельная закрытая страница; публичная страница содержит лишь безопасную информацию или ссылку на закрытое дополнение.
12. Главная страница
После установки Wiki.js показала экран «Welcome to Wiki.js» с кнопками Create the homepage / Administration Area и выбором трёх редакторов. Для первой страницы был выбран Markdown Editor.
Заголовок главной страницы — True Wiki. Подготовлен текст о персональной базе знаний, Linux, домашней инфраструктуре, веб-технологиях, Docker/Proxmox, сетях и локальных LLM, со ссылкой на профессиональный профиль:
Профиль Александра Лесина в LinkedIn
Примечание: содержимое LinkedIn при подготовке страницы прочитать автоматически не удалось, поэтому описание на главной основано на направлениях работы, обсуждавшихся при настройке, а не на подтверждённом списке должностей/работодателей.
13. Что важно проверить после настройки
13.1. Функциональные тесты
-
https://wiki.lesin.net/открывается без ошибок сертификата. - Гость видит главную страницу и обычные новые страницы.
- Точное запрещающее правило скрывает выбранную страницу от гостя.
- Запрет действует также на связанные ресурсы, если они не должны быть публичными.
- Администратор входит и выходит без неправильных
http://-редиректов. - Работают создание и редактирование Markdown-страниц.
- Работают поиск и дерево страниц.
- Файл размером в несколько мегабайт загружается и скачивается.
- Mermaid-блок рендерится.
- Draw.io-диаграмма создаётся и повторно открывается для редактирования.
- Работает совместное редактирование/WebSocket, если включено.
- Anubis показывает проверку гостю, но не ломает логин, загрузку файлов, редактор и WebSocket.
- После
docker compose restartданные и файлы остаются на месте.
13.2. Команды диагностики
На server1:
cd /opt/wiki
docker compose ps
docker compose logs --tail=100 wiki
docker compose logs --tail=100 db
ss -lntp | grep -E ':(443|8081)\b'
nginx -t
curl -I http://127.0.0.1:8081/
curl -kI --resolve wiki.lesin.net:443:127.0.0.1 https://wiki.lesin.net/
На server4:
nginx -t
systemctl status nginx --no-pager -l
journalctl -u nginx -n 50 --no-pager
curl -I https://wiki.lesin.net/
curl -I проверяет HTTP-ответ, но не заменяет проверку в браузере для JavaScript, Anubis, загрузки файлов и WebSocket.
14. Резервное копирование, восстановление и обновление
14.1. Что сохранять
- PostgreSQL
wiki— страницы, пользователи, правила, настройки и содержимое при стандартном хранении. /opt/wiki/compose.yaml— конфигурацию контейнеров./opt/wiki/.env— только в защищённом резервном хранилище; это секрет.- Конфигурации внешнего и внутреннего Nginx, сертификаты/процедуру их восстановления, настройки Anubis и соответствующие правила NAT.
- Если позже включено отдельное локальное файловое хранилище для ресурсов — его каталог тоже, независимо от базы.
/opt/wiki/.env никогда не следует прикладывать к публичной статье или обычному архиву без шифрования.
14.2. Резервная копия PostgreSQL
На server1, при работающем контейнере БД:
cd /opt/wiki
mkdir -p /root/wiki-backups
chmod 700 /root/wiki-backups
backup="/root/wiki-backups/wiki-$(date +%F-%H%M%S).dump"
docker compose exec -T db pg_dump -U wiki -d wiki -Fc > "$backup"
chmod 600 "$backup"
ls -lh "$backup"
Формат -Fc удобен для pg_restore. Важно следить за exit code команды и периодически проверять возможность восстановления на тестовой базе. Не хранить единственную резервную копию на том же диске.
14.3. Восстановление (только при реальной необходимости)
Осторожно: операция изменяет/заменяет содержимое базы. Перед ней сделать дополнительную копию, убедиться в совместимости версий PostgreSQL и Wiki.js и проверить выбранный
.dump.
Типовая последовательность для восстановления в существующую БД:
cd /opt/wiki
docker compose stop wiki
# Пример: подставить действительное имя файла архива.
docker compose exec -T db pg_restore \
-U wiki -d wiki --clean --if-exists --no-owner \
< /root/wiki-backups/ИМЯ_АРХИВА.dump
docker compose start wiki
Это пример процедуры, а не выполненное действие; восстановление в занятую БД или при несовместимой схеме может потребовать отдельного плана. Для миграции на новый сервер переносить также Compose, секреты и внешние ресурсы.
14.4. Обновление Wiki.js
Поскольку при установке выбран закреплённый тег 3.0.2, docker compose pull без изменения тега не означает автоматический переход на новую версию.
Рекомендуемый порядок:
- Прочитать release notes и требования новой версии.
- Сделать резервную копию БД и конфига.
- Изменить версию образа в
/opt/wiki/compose.yamlна явно выбранную. - Выполнить:
cd /opt/wiki
docker compose config --quiet
docker compose pull wiki
docker compose up -d
docker compose ps
docker compose logs --tail=100 wiki
Не использовать бесконтрольно latest, а при обновлениях PostgreSQL между major-версиями отдельно учитывать необходимость миграции данных — простая смена образа БД не гарантирует совместимость её каталога.
Не выполнять docker compose down -v при обычном обслуживании: флаг -v удаляет именованные тома, в том числе том PostgreSQL.
15. Принятые решения и известные ограничения
| Вопрос | Решение |
|---|---|
| Wiki в Redmine | Заменить отдельной системой |
| Основная wiki | Wiki.js 3 |
| Установка в хостовый Debian | Возможна, но выбрали Docker Compose |
| База | PostgreSQL 18 |
| Каталог установки | /opt/wiki на server1 |
| Порт контейнера/хоста | 3000 / 8081 (8080 оказался занят) |
| Домен | wiki.lesin.net |
Подпапка /wiki |
Отвергнута из-за неподдерживаемой схемы размещения |
| SSL | Внешний Nginx/Certbot; внутренняя TLS-маршрутизация server1 |
| Антибот | Использовать уже работающий Anubis, без нового экземпляра |
| Редактор | Markdown, при необходимости Visual/AsciiDoc |
| Диаграммы | Mermaid и diagrams.net/draw.io прежде всего |
| Публичность | По умолчанию гостям разрешено чтение страниц |
| Закрытые страницы | Индивидуальные Deny-правила в соответствующих группах |
| Фрагменты одной страницы | Не считать встроенной ACL-функцией; выносить секреты в отдельные страницы |
| Хранение Markdown | По умолчанию БД, не отдельные .md-файлы |
| Резервные копии | Дамп PostgreSQL + конфигурации + внешние файлы при их появлении |
16. Полезные официальные ссылки
- Wiki.js 3: установка Docker и установка без Docker
- Wiki.js 3: требования и конфигурация
- Wiki.js 3: общие настройки
- Wiki.js 3: группы, разрешения и приоритет правил
- Wiki.js 3: авторизация и reverse proxy
- Wiki.js 3: Mermaid
- Wiki.js 3: Draw.io
- Wiki.js 3: FAQ, в том числе размещение в подпапке
- Wiki.js 3: обновление и изменения синтаксиса блоков
- BookStack: визуальные диаграммы
- BookStack: роли и права
Документ составлен по фактическим действиям и решениям при установке 4 ноября 2026 года; дополнен практическими рекомендациями, которые помечены как рекомендации, а не как уже выполненные настройки.