Wiki.js Docker

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
# vim config.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:

Мы поменяли дефолтные имена и пароли. Это улучшает защищённость установки. В этом плюс. С другой стороны, в дальнейшем обязательно возникнет некоторая путаница. И станет невозможным перенос команд из солюшенов по принципу копи-паст. Поэтому лучше сразу определиться нужно ли это. Если нет, то оставить дефолтные значения:

POSTGRES_DB: wiki
POSTGRES_PASSWORD: wikijsrocks
POSTGRES_USER: wikijs

Что есть в этом конфиге:

  • Для работы необходим контейнер базы данных 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

То есть абсолютный путь к папке внутри контейнера, без завершающего слеша. Не забываем активировать хранилище (дёрнуть переключатель Active) и применить настройки, кнопка Apply.

Всё проверяем, Ctrl-Z чтобы прервать запущенный Compose и стартуем 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

Перезагружаем систему и ещё раз проверяем что работает.


Перенос Wiki

Иногда нужно перетащить установленную Вики с одного сервера на другой. Почитать можно в официальной документации, но там как всегда не особо подробно и понятно. Итак, на старом серваке смотрим:

# docker ps

CONTAINER ID   IMAGE                                                                                                             
5e00c9c0efc7   ghcr.io/requarks/wiki..
500e287475f2   postgres:11-alpine..                                                                                  

Нужен ID контейнера с базой данных. Далее выгружаем дамп:

# docker exec 500e287475f2 pg_dump wiki_db_mos_1 -U wiki_db_adm -F c > wikibackup.dump

Выполнено для базы wiki_db_mos_1 и пользователя wiki_db_adm. Имя базы и имя пользователя задавали выше. Эти имена не по умолчанию. Специально так делали для защиты установки. Дамп создаётся в текущей папке. Файл достаточно большой, для моей скромной Вики он составил 1,2Gb. Далее переносим файл дампа на новый сервер, проще опять через WinSCP. Например, в домашнюю папку пользователя node.

Смотрим уже на новом серваке:

# docker ps 

CONTAINER ID   IMAGE                                                                                                              984afc7a7c4b   ghcr.io/requarks/wiki.. 
daf02502011e   postgres:11-alpine.. 

Переходим в папку с закаченным дампом:

# cd /home/node

Останавливаем контейнер Вики:

# docker stop 984afc7a7c4b

984afc7a7c4b

Далее пересоздаём базу данных:

# docker exec -it daf02502011e dropdb -U wiki_db_adm wiki_db_mos_1
# docker exec -it daf02502011e createdb -U wiki_db_adm wiki_db_mos_1

Здесь также нужно обращать внимание на правильное имя базы данных и пользователя базы данных. И наконец, заливаем дамп в свежесозданную базу:

# cat wikibackup.dump | docker exec -i daf02502011e pg_restore -U wiki_db_adm -d wiki_db_mos_1

После чего стартуем контейнер Вики:

# docker stop 984afc7a7c4b 

984afc7a7c4b

Проблемы

Тут их как никогда много. Если сделать volume на всю папку Вики, могут возникнуть разные проблемы, в основном из-за кривых прав на файлы и папки для volume:

  • С файлами кэша. Ведь эти файлы должны правильно синхронизироваться между контейнером и volume;
  • Проблемы с папкой /wiki/data/uploads/ через неё загружаются файлы картинок. В результате файлы картинок загрузить нельзя;
  • Обновление на новую версию не происходит. В чём дело не разбирался.

Если криво настроен Local Storage:

  • Возникнет ошибка при сохранении страниц;
  • При очистке кэша в Вики перестанут отображаться все картинки;
  • И даже вот такое может быть:
Wiki.js Docker

Пролечил отключением 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 ps, то контейнер базы в постоянном ребуте. Такая проблема может возникать по разным причинам, у меня она появилась, когда закончилось место на диске VM. 🙂

Конечно изначально всего этого не знал и количество словленных граблей не поддаётся подсчёту.


Полезности

Полезные команды 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елеграм канал

3 thoughts on “Wiki.js Docker”

  1. Мария

    Добрый день!

    Добавлю по поводу настройки LocalStorage, потому что сама долго не могла понять - почему не работает.

    в docker-compose стоит добавить строки
    wiki:
    image: ghcr.io/requarks/wiki:2
    user: "1000:1000"

    Указывает пользователя и группу node. Иначе папка /wiki/backup создается не от того пользователя и нет прав доступа на запись бекапов

    1. Добрый день!
      Спасибо, Мария. Контейнер wiki должен по умолчанию стартовать от пользователя 1000:1000. Это можно проверить, если удалить user: "1000:1000" и выполнить команду docker-compose exec wiki id.

      1. Мария

        Вы правы, стартует от него и работает от него. но каталог /wiki/backup у меня монтировался от root и потому не работали бекапы. я не сразу сообразила и заметила, помогло указание пользователя принудительно

Leave a Comment

Scroll to Top