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:

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

  • Для работы необходим контейнер базы данных db из образа: postgres:11-alpine;
  • Контейнер Вики wiki из образа: ghcr.io/requarks/wiki;
  • К каждому контейнеру подключены свои volumes. Внутренний для базы данных и три внешних для Вики;
  • Поскольку веб Вики будет светить наружу, то контейнер Вики из соображений безопасности не должен работать от рута. Это уже сделано по дефолту;
  • Пользователь контейнера Вики пишет/читает в своих 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:

  • Возникнет ошибка при сохранении страниц;
  • При очистке кэша в Вики перестанут отображаться все картинки;
  • И даже вот такое может быть:
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:

docker ps - посмотреть контейнеры
docker images - посмотреть образы
docker cp локальный_путь контейнер:путь_в_контейнере - скопировать в контейнер
docker cp контейнер:путь_в_контейнере локальный_путь - скопировать из контейнера
docker exec контейнер команда - выполнить команду в контейнере
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 завершён. Думаю неплохо получилось.

Добавить комментарий