True Wiki

Wiki.js 3 — выбор, установка и настройка Lesin Wiki

Статус: действующая конфигурация и журнал решений по состоянию на 4 ноября 2026 года.
Адрес: https://wiki.lesin.net/
Версия при первоначальной установке: Wiki.js 3.0.2, PostgreSQL 18.
Назначение: личная и совместная база знаний вместо wiki в Redmine.
Важно о публичности: эта инструкция содержит внутренние адреса, схему серверов и сведения об инфраструктуре. Владелец выбрал публичность страниц по умолчанию. Прежде чем публиковать статью для гостей, проверьте, что её содержание допустимо раскрывать, либо ограничьте доступ к этой конкретной странице.

1. Зачем понадобилась отдельная wiki

Исходная wiki в Redmine перестала устраивать как основное хранилище документации. Нужна самостоятельная, достаточно лёгкая система без постоянной ручной возни с зависимостями и обновлениями.

Требования, сформулированные при выборе:

Важный нюанс: доступ к фрагментам страницы

Первоначально рассматривалось также разграничение прав на отдельные абзацы или секции одной страницы. Это не эквивалентно запрету чтения страницы целиком.

В 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. Редакторы и разметка

При создании главной страницы предлагаются три режима:

  1. Markdown Editor — выбран для этой базы знаний; подходит для команд, кода и структурированной документации.
  2. Visual Editor — визуальное редактирование без ручного набора разметки.
  3. 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. Пользователи и файлы

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 уже существуют вне этих двух контейнеров.

Плюсы подхода:

Важный минус: 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;
    }
}

Примечания:

Проверка 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 выдавал предупреждения, не блокирующие запуск:

Их не следует путать с фатальным конфликтом зоны памяти. Устаревшие протоколы 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. Функциональные тесты

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. Что сохранять

  1. PostgreSQL wiki — страницы, пользователи, правила, настройки и содержимое при стандартном хранении.
  2. /opt/wiki/compose.yaml — конфигурацию контейнеров.
  3. /opt/wiki/.env — только в защищённом резервном хранилище; это секрет.
  4. Конфигурации внешнего и внутреннего Nginx, сертификаты/процедуру их восстановления, настройки Anubis и соответствующие правила NAT.
  5. Если позже включено отдельное локальное файловое хранилище для ресурсов — его каталог тоже, независимо от базы.

/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 без изменения тега не означает автоматический переход на новую версию.

Рекомендуемый порядок:

  1. Прочитать release notes и требования новой версии.
  2. Сделать резервную копию БД и конфига.
  3. Изменить версию образа в /opt/wiki/compose.yaml на явно выбранную.
  4. Выполнить:
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. Полезные официальные ссылки


Документ составлен по фактическим действиям и решениям при установке 4 ноября 2026 года; дополнен практическими рекомендациями, которые помечены как рекомендации, а не как уже выполненные настройки.