Wiki.js Docker — продолжаем изучение вариантов развёртывания Wiki.js, на этот раз будем ставить в Docker и попробуем всё настроить как надо.
Развёртывание Wiki.js в Docker простое, но простота эта иллюзорная. Мы добавляем ещё один уровень абстракций, а значит усложняем конечную систему. Весьма полезно развернуть сначала без Docker, понять работу и устройство Вики. Так и было сделано и именно по этой причине.
Итак, что же удалось узнать до текущего момента? В папке Вики не хранятся данные, только скрипты. За исключением файла конфига и файла сертификата. В варианте с Docker там ещё будет папка с бэкапами. И это не просто папка для бэкапов, а именно Local Storage. От его работоспособности многое зависит. Кроме этого по пути /wiki/data/cache
лежат файлы динамически генерируемого кэша. Всё остальное в базе данных.
Поэтому нет смысла делать примонтированный в папку (далее — внешний) volume
на всю папку Вики. Там файлы статические, точно такие же как в образе Docker. И тут ещё могут вылезти проблемы, об этом в соответствующем разделе.
Внешний volume
для Postgre тоже не нужен, нет необходимости туда что-то копировать или оттуда. Для сохранения информации используется система архивации через Local Storage и Utilites-Export to Disk. Хотя именно какого-то вреда от внешнего volume
для Postgre не было замечено.
Заранее узнал от какого пользователя стартует контейнер Вики:
# docker-compose exec wiki id uid=1000(node) gid=1000(node) groups=1000(node)
Первый пользователь созданный в системе имеет UID=1000
, GID=1000
. Мы его создаём при установке Ubuntu Server. У меня это и будет пользователь node
.
Указал важные моменты, которые позволят не собрать все грабли, которые тут есть. В этой, третьей по счёту, части не буду подробно останавливаться на уже рассказанном. Если что-то непонятно, то Welcome! в первую часть, вторую часть.
Этапы установки
При развёртывании в Docker мы свободны в выборе хостовой ОС. Использую Ubuntu Server, но это может быть Suse, CentOS или другой произвольный дистрибутив. Тот который привычен в работе.
Будем последовательно рассматривать следующее:
- Установка Docker Engine;
- Docker Compose;
- Настройка папок;
- Заполнение конфига Compose;
- Запуск Compose;
- Настройка/обновление;
- Автостарт Compose.
После чего дополнительно рассмотрим:
- Выявленные проблемы;
- Полезности, которые могут пригодится.
Docker Engine
Чистая установка Ubuntu Sever v.22.04 LTS. Docker можно сразу выбрать для установки на последнем окне установки Ubuntu Sever. Для определённости делать этого не будем, поставим руками.
Устанавливаем Docker через репозиторий, как написано на странице проекта:
node@wiki:~$ sudo -s # curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg # echo \ "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null # apt-get update # apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-compose -y # docker run hello-world Hello from Docker! This message shows that your installation appears to be working correctly.
Docker работоспособен, удалим ненужный образ hello-world
:
# docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest feb5d9fea6a5 7 months ago 13.3kB # docker rmi -f feb5d9fea6a5 Deleted: sha256:feb5d9fea6...
Всё на месте, службы docker.service
, containerd.service
уже на автостарте, делать ничего не надо. Тут полезно заметить, что:
The Docker daemon always runs as the root user.
И создавать отдельную группу и отдельного пользователя для старта сервиса Docker нет смысла, тем более что если и сделать это:
The docker group grants privileges equivalent to the root user.
От рута оно работает by design.
Docker Compose
Docker Compose relies on Docker Engine for any meaningful work.
Это мы уже сделали, теперь Compose, тут существует определённая неразбериха. Так как есть docker compose
и docker-compose
. Если не вдаваться в подробности, то это два одинаковых проекта.
# docker compose version Docker Compose version v2.5.0 # docker-compose version docker-compose version 1.29.2
Для определённости буду пользоваться docker-compose
.
Папки
Создаём папку для проекта Compose и для бэкапов:
# mkdir /opt/wikijs # mkdir /opt/wikijs/wiki # mkdir /opt/backup
После чего копируем в /opt/wikijs/wiki
сертификат cert-wiki.pfx
через WinSCP. Создаём там файл конфига config.yml
.
# cd/opt/wikijs/wiki
# vimconfig.yml
А правильный конфиг будет такой, сделал на основе того, что уже есть в контейнере по дефолту:
port: 80 bindIP: 0.0.0.0 db: type: $(DB_TYPE) host: '$(DB_HOST)' port: $(DB_PORT) user: '$(DB_USER)' pass: '$(DB_PASS)' db: $(DB_NAME) storage: $(DB_FILEPATH) ssl: $(DB_SSL) ssl: enabled: true port: 443 provider: custom format: pfx pfx: cert-wiki.pfx passphrase: 'passwd' dhparam: null logLevel: $(LOG_LEVEL:info) logFormat: $(LOG_FORMAT:default) ha: $(HA_ACTIVE)
Как видно тут используются переменные, они подтянутся из конфига Compose, где мы их и пропишем. Сменим разрешения для папок и файлов, чтобы пользователь от которого стартует контейнер Вики мог там свободно оперировать:
# chown -R node:node /opt/wikijs/wiki # chown -R node:node /opt/backup
Большая часть работы ведётся в папке /opt/wikijs
.
Конфиг Compose
Теперь конфигурационный файл Compose, наполняем его следующей информацией:
# cd /opt/wikijs # vim docker-compose.yml
version: "3" services: db: image: postgres:11-alpine environment: POSTGRES_DB: wiki_db_mos_1 POSTGRES_PASSWORD: LyDfsJVMR9G POSTGRES_USER: wiki_db_adm logging: driver: "none" restart: unless-stopped volumes: - db-data:/var/lib/postgresql/data wiki: image: ghcr.io/requarks/wiki container_name: wikijs volumes: - ./wiki/config.yml:/wiki/config.yml - ./wiki/cert-wiki.pfx:/wiki/cert-wiki.pfx - /opt/backup:/wiki/backup depends_on: - db environment: DB_TYPE: postgres DB_HOST: db DB_PORT: 5432 DB_USER: wiki_db_adm DB_PASS: LyDfsJVMR9G DB_NAME: wiki_db_mos_1 restart: unless-stopped ports: - "80:80" - "443:443" volumes: db-data:
Что есть в этом конфиге:
- Для работы необходим контейнер базы данных
db
из образа:postgres:11-alpine
; - Контейнер Вики
wiki
из образа:ghcr.io/requarks/wiki
; - К каждому контейнеру подключены свои
volumes
. Внутренний (data volume) для базы данных и три внешних для Вики; - Поскольку веб Вики будет светить наружу, то контейнер Вики из соображений безопасности не должен работать от рута. Это уже сделано по дефолту;
- Пользователь контейнера Вики пишет/читает в своих
volumes
, чтобы он мог это делать и меняли права на папки.
Внутри контейнера Вики абсолютный путь должен начинаться с /wiki
.
Запуск Compose
Compose можно запустить как приложение и в бэкграунде, сначала запускаем как приложение. Запускать надо из папки, где лежит docker-compose.yml
. Это у нас /opt/wikijs
. При этом необходимые images
будут автоматически скачаны.
# docker-compose up Creating network "wikijs_default" with the default driver Creating volume "wikijs_db-data" with default driver Pulling db (postgres:11-alpine)... df9b9388f04a: Pull complete 7902437d3a12: Pull complete ...
Это аналог команды node server
в установке без Docker. Выводится подробный лог. Пользоваться таким запуском полезно, если нужно проконтролировать корректность работы. Должна получиться примерно вот такая картинка:

Настройки
Переходим в вебе по адресу нашей Вики порт 80. Далее вводим e-mail и пароль админа для Вики, происходит первоначальное заполнение базы данных.
Как уже говорил, настройку самой Вики подробно рассказал в отдельной статье. Но обязательно нужно ещё раз обратить внимание на путь к Local Storage. Тут он будет:
/wiki/backup
То есть абсолютный путь к папке внутри контейнера, без завершающего слеша. Всё проверяем, стартуем Compose в бэкграунде:
# docker-compose up -d
-d, --detach Detached mode: Run containers in the background, print new container names.
Обновление
С Docker оно простое и удобное:
# docker-compose pull wiki # docker-compose up --force-recreate
Автостарт Compose
Пока у нас Compose не стартует самостоятельно после перезапуска системы. Делаем следующее:
# vim /etc/systemd/system/docker-compose.service
[Unit] Description=Docker Compose Requires=docker.service After=docker.service [Service] Restart=always ExecStart=/usr/bin/docker-compose up ExecStop=/usr/bin/docker-compose down WorkingDirectory=/opt/wikijs [Install] WantedBy=multi-user.target
Включаем docker-compose.service
и проверяем его работу:
# systemctl daemon-reload # systemctl start docker-compose # systemctl status docker-compose # systemctl enable docker-compose Created symlink /etc/systemd/system/multi-user.target.wants/docker-compose.service → /etc/systemd/system/docker-compose.service. # systemctl stop docker-compose # systemctl status docker-compose
Перезагружаем систему и ещё раз проверяем что работает.
Проблемы
Тут их как никогда много. Если сделать volume
на всю папку Вики, могут возникнуть разные проблемы, в основном из-за кривых прав на файлы и папки для volume
:
- С файлами кэша. Ведь эти файлы должны правильно синхронизироваться между контейнером и
volume
; - Проблемы с папкой
/wiki/data/uploads/
через неё загружаются файлы картинок. В результате файлы картинок загрузить нельзя; - Обновление на новую версию не происходит. В чём дело не разбирался.
Если криво настроен Local Storage:
- Возникнет ошибка при сохранении страниц;
- При очистке кэша в Вики перестанут отображаться все картинки;
- И даже вот такое может быть:

Пролечил отключением volume
, деактивацией Local Storage, затем перезапустил Compose, папка backup
в контейнере вообще исчезла, так и должно быть. Активировал Local Storage, подключил volume
. В результате две папки backup
слились таки в одну и всё наконец заработало.
Пароль базы данных не может быть произвольным. Допустим, Ly$DfsJVMR9G
неправильный. При старте Compose как приложения об этом выдаётся сообщение:
WARNING: The DfsJVMR9G variable is not set. Defaulting to a blank string.
Конфиг Compose считает что есть какая-то переменная DfsJVMR9G
, потому что впереди знак $
.
Конечно изначально всего этого не знал и количество словленных граблей не поддаётся подсчёту.
Полезности
Полезные команды Docker:
docker ps - посмотреть контейнеры docker images - посмотреть образы docker cp локальный_путь контейнер:путь_в_контейнере - скопировать в контейнер docker cp контейнер:путь_в_контейнере локальный_путь - скопировать из контейнера docker exec контейнер команда - выполнить команду в контейнере docker exec -it контейнер /bin/bash (или /bin/sh) - интерактивный режим docker rm контейнер - удалить контейнер docker rmi {-f} образ - удалить образ
Если нужно запустить контейнер Вики от другого пользователя, например от рута, то в docker-compose.yml
нужно добавить после строки wiki
:
wiki: user: "0:0"
Порты можно прописать двумя разными способами:
ports: - "80:80" - "443:443" или ports: - "80:3000" - "443:3443"
При втором варианте Compose прозрачно перекидывает запросы. Естественно в конфиге Вики должно соответствовать. Редирект с HTTP на HTTPS работает корректно и во втором случае.
Если нужно перенести базу, делаем дамп базы. Дамп создаётся в текущую папку:
# docker exec wikijs_db_1 pg_dump wiki_db_mos_1 -U wiki_db_adm -F c > wikibackup.dump wikijs_db_1 - имя контейнера базы wiki_db_mos_1 - имя базы wiki_db_adm - имя пользователя базы
Вот есть неплохое видео про установку Wiki.js под Docker.
Заключение
Выводы следующие: хотя установка под Docker проще и есть приятности с простотой работы и обновления, но гораздо больше "подводных камней" и неочевидных моментов. На этом цикл статей про Wiki.js завершён. Думаю неплохо получилось.
Приглашаю поделиться мнением в Tелеграм канал
Добрый день!
Добавлю по поводу настройки LocalStorage, потому что сама долго не могла понять - почему не работает.
в docker-compose стоит добавить строки
wiki:
image: ghcr.io/requarks/wiki:2
user: "1000:1000"
Указывает пользователя и группу node. Иначе папка /wiki/backup создается не от того пользователя и нет прав доступа на запись бекапов
Добрый день!
Спасибо, Мария. Контейнер wiki должен по умолчанию стартовать от пользователя
1000:1000
. Это можно проверить, если удалитьuser: "1000:1000"
и выполнить командуdocker-compose exec wiki id
.Вы правы, стартует от него и работает от него. но каталог /wiki/backup у меня монтировался от root и потому не работали бекапы. я не сразу сообразила и заметила, помогло указание пользователя принудительно