Alpine + Docker: поваренная книга разработчика

Автор: Евгений Голышев

Статья была опубликована в 237-м выпуске журнала Linux Format. По истечении полугода с момента публикации права на статью переходят ее автору, поэтому материал публикуется в нашем блоге.

Docker – одна из немногих технологий, которая, наделав несколько лет назад много шума, до сих пор остается с нами. Чтобы помочь разработчикам взглянуть на любимый Docker под другим углом, я достал свою поваренную книгу, смахнул с нее пыль и приготовился к тому, чтобы в рамках этой статьи поделиться своими рецептами.

Два из четырех фигурирующих здесь рецептов призваны уменьшить размер результирующих образов. Эта задача всегда была и остается актуальной для Docker’а, поэтому я начну свой небольшой сборник рецептов с рассказа об Alpine Linux, а потом перейду непосредственно к самим рецептам. Во-первых, именно Alpine является первым шагом на пути к компактным образам, а во-вторых, я хочу воспользоваться случаем и рассказать немного об этом дистрибутиве, чтобы исправить недостаток информации об Alpine на страницах этого журнала (по какой-то причине журнал до сих пор обходил этот дистрибутив стороной).

Немного об Alpine

Alpine Linux применяется в качестве основы для официальных Docker-образов; в свое время он вытеснил с этого места Ubuntu. Более того, в начале 2016-го стало известно, что Натанаэ́ль Копа [Natanael Copa], создатель дистрибутива, присоединился к команде Docker’а. При этом Alpine остается независимым дистрибутивом, подконтрольным только своему сообществу.

Вот список наиболее интересных, на мой взгляд, фактов:

  • Последняя на момент написания статьи версия дистрибутива – 3.8 – вышла 26 июня 2018 г., и ее официальный образ весит чуть больше 4 МБ.
  • Разработчики стараются придерживаться предсказуемого графика выпуска новых версий дистрибутива. Как правило, новые версии Alpine’а выходят два раза в год – в мае и декабре, но возможны и небольшие отклонения от графика. К примеру, версия 3.8 вышла с опозданием на пару месяцев.
  • Каждая версия дистрибутива поддерживается на протяжении двух лет. Так как новые версии Alpine’а выходят два раза в год, то одновременно поддерживается 3-4 версии дистрибутива.
  • В качестве системы инициализации используется OpenRC. Напомню, что стандартом де-факто сейчас является systemd.
  • Поддерживается 6 портов: x86 и x86_64, armhf и aarch64, ppc64le, s390x. Это меньше, чем у Debian, но больше, чем у Ubuntu.
Docker-образы на базе текущей и предыдущей версий Alpine’а весят чуть больше 4 МБ.

Статическая компоновка

Не вдаваясь в лишние подробности, сборку программы можно разделить на два этапа: получение объектных файлов (на каждую единицу компиляции – файл с расширением .c или .cpp – приходится по одному объектному файлу) и компоновку (или линковку, от англ. linkage). Суть компоновки заключается в создании исполняемого файла (или разделяемой библиотеки) из полученных ранее объектных файлов. Если у исполняемого файла есть зависимости в виде библиотек, то в задачи компоновщика также входит связывание [linking] исполняемого файла с этими библиотеками одним из двух способов: статически или динамически. Для статической компоновки необходимы статические библиотеки [static libraries], а для динамической – разделяемые [shared libraries].

Статическая библиотека представляет собой архив объектных файлов, который создается программой ar. Когда исполняемый файл компонуется со статической библиотекой, то составляющие данную библиотеку объектные файлы становятся частью этого исполняемого файла. Для сравнения, разделяемая библиотека представляет собой объектный файл. Когда исполняемый файл компонуется с разделяемой библиотекой, то в исполняемый файл попадает только информация об этой библиотеке. В таком случае, процесс компоновки будет осуществляться во время запуска программы динамически. (В силу ограниченного объема нашего урока, описание процесса компоновки пришлось сильно упростить, поэтому я настоятельно рекомендую обратиться к книгам «Linux API. Исчерпывающее руководство» Майкла Керриска и «Linux. Руководство программиста» Джона Фуско за более детальными подробностями по этому вопросу.)

С использованием разделяемых библиотек связан ряд преимуществ.

  • Использование разделяемых библиотек уменьшает расход дискового пространства и памяти: на диске хранится и в память загружается только одна копия разделяемой библиотеки, независимо от количества программ, которые ее используют.
  • Устранение ошибок и уязвимостей в разделяемой библиотеке не требует пересборки зависимых от нее программ (конечно, при условии, что исправления не затронули двоичную совместимость).

Все эти преимущества не имеют никакой ценности в контейнерах. Во-первых, философия Docker гласит, что на один контейнер полагается только один процесс. Таким образом, в контейнере не должно оказаться двух процессов, которые бы разделяли код одной и той же библиотеки. Во-вторых, Docker-образы, как правило, обновляются атомарно – если один из компонентов контейнера требует обновления, то пересобирается весь образ.

Всё указывает на то, что статические библиотеки подходят для Docker-образов с идеологической точки зрения. Теперь осталось разобраться, есть ли в этом какая-то практическая польза.

Использование разделяемых библиотек негативно сказывается на размере Docker-образа. В основном это связано с особенностью дистрибутивов. В дистрибутивах разделяемые библиотеки распространяются в отдельных пакетах, а с установкой любых пакетов связаны определенные накладные расходы, и чем меньше остается пакетов в образе после его сборки, тем меньше он в итоге занимает места. Таким образом, если компактность результирующего образа для вас не пустой звук, то польза от использования статических библиотек определенно есть.

К примеру, у Memcached есть две основные зависимости – пакет libevent-dev с библиотекой для ассинхронного неблокируещего ввода/вывода, и cyrus-sasl-dev с библиотекой, реализующей вторую версию SASL API. libevent-dev зачем-то тащит за собой пакет python2, который в установленном виде занимает 39 МБ. Это именно те накладные расходы, о которых я говорил выше. Таким образом, официальный Docker-образ с Memcached’ом 1.5.10, последней на момент написания статьи версией демона, весит почти 59 МБ, т. к. постоянно таскает за собой Python 2, о котором даже никто не вспоминает, когда запускает Memcached. Docker-образ со статически скомпонованным с этими библиотеками Memcached’ом, весит чуть больше 10 МБ. Предлагаю в этом убедиться на примере образа Memcached’а из проекта MMB. Для этого сначала получите исходники всего проекта, а затем (предпочтительнее) соберите образ –

$ git clone https://github.com/tolstoyevsky/mmb.git
$ cd mmb/memcached
$ IMAGE_NAME=$(grep "image: " docker-compose.yml | awk -F': ' '{print $2}')
$ docker build -t ${IMAGE_NAME} .

или вытяните его с Docker Hub’а:

$ docker pull cusdeb/memcached:1.5.10-amd64

(На самом деле, в этом образе используется еще одна нехитрая оптимизация, о которой будет рассказано сразу в следующем рецепте. Без нее, конечно, размер образа был бы чуть больше.)

Образ со статически скомпонованным Memcached’ом весит почти в 6 раз меньше официального образа.

Но за эту оптимизацию приходится платить. Дело в том, что при использовании Alpine в качестве базового образа статическая компоновка осложняется тем, что у этого дистрибутива туговато со статическими библиотеками. К примеру, как libevent-dev, так и cyrus-sasl-dev содержат только разделяемые варианты библиотек. Наличие обоих вариантов библиотек в Alpine отдается на откуп сопровождающим этих библиотек, и если сопровождающий решил, что библиотека, от которой зависит докеризуируемая вами программа, должна быть доступна только в разделяемом виде, то придется самостоятельно готовить ее статический вариант на этапе сборки самого образа, что потребует дополнительных сил на написание Dockerfile’а.

Поэтому для начала необходимо решить, что для вас имеет больший приоритет – быстрая докеризация или небольшой объем результирующего образа. Если образ предназначается для широкого круга пользователей, то лично я бы вложился в уменьшение его объема.

Докеризация только серверных частей

При докеризации клиент-серверного программного обеспечения не оставляйте в образе клиентов. В противном случае образ будет включать компоненты, которые примутся всюду за ним таскаться, и более того, о которых никто не вспомнит при запуске целевого сервера (немного напоминает историю с Python 2 и Memcached из предыдущего рецепта).

Клиенты, как правило, распространяются в дистрибутивах отдельно от серверов и, в отличие от последних, имеют минимум зависимостей и практически не требуют времени на их настройку, поэтому при решении узкоспециализированных я придерживаюсь идеи выкидывания из образа всего лишнего.

Тем не менее, если вам достаточно сделать docker exec для того, чтобы подключиться к серверу посредством клиента, запущенного в том же контейнере, что и сам сервер, то речь идет об учебной или просто несерьезной задаче, и волноваться вам не о чем. Во всех остальных случаях клиенты в Docker-образах с серверами являются лишними.

Сборка образов под ARM на машине x86

Благодаря широкому распространению одноплатных компьютеров (Raspberry Pi, Orange Pi, Banana Pi и т. д.), устройства на базе 32- и 64-битного процессора ARM, на которых можно запустить полноценную операционную систему, сейчас доступны как никогда. Более того, Docker поддерживает ARM уже достаточно давно: начиная с версии 1.10, вышедшей 4 февраля 2016 г., появилась возможность собрать клиентскую и серверную части под ARM, а с версией 1.12.1, вышедшей 18 августа того же года, официальная поддержка пришла на ARM-машины под управлением Debian Jessie, Ubuntu Trusty и Raspbian Jessie.

Тем не менее, Docker-образы не всегда удобно собирать непосредственно на одноплатниках – для экономии времени сборку лучше производить на рабочей станции или ноутбуке, которые, как правило, представляют собой машины на базе процессора x86. Один из способов этого добиться – поместить в базовый образ [base image] целевого Docker-образа двоичные файлы средства эмуляции в режиме пользователя [user mode emulation binaries].

Как в производных от Debian дистрибутивах, так и в Fedora двоичные файлы средства эмуляции в режиме пользователя содержатся в пакете qemu-user-static. Модуль ядра binfmt_misc, доступный в Linux начиная с версии 2.1.43 (которая, кстати, вышла в июне далекого теперь 1997 г.), позволяет распознавать различные форматы исполняемых файлов и ассоциировать их с произвольными приложениями. Другими словами, для определенного формата исполняемого файла можно зарегистрировать эмулятор, и при каждой попытке запустить исполняемый файл этого формата передавать его эмулятору, а не запускать на текущем процессоре. (В производных от Debian дистрибутивах также потребуется установить пакет binfmt-support, в который вынесена функция регистрации эмуляторов.) Таким образом, если предназначенный для запуска на одноплатнике образ включает эти бинарники, то на машине на базе процессора, отличного от ARM, сборка образа и запуск контейнера на его основе будут осуществляться с привлечением эмулятора, а на ARM-машинах всё будет выполняться на реальном процессоре.

Возможность прозрачного запуска собранных под ARM программ на x86-машинах доступна в ядре более 20 лет.

Предлагаю рассмотреть скрипт создания базового Docker-образа для ARM, который будет включать двоичные файлы средства эмуляции в режиме пользователя, чтобы любой образ на его основе мог быть без проблем собран и запущен на x86-машинах. Чтобы скрипт корректно отработал, в системе, где он будет запущен, должны находиться эти бинарники. В том случае, если этой системой является Fedora, установите пакет qemu-user-static, а если речь идет о Debian или Ubuntu, то qemu-user-static и binfmt-support.

А теперь перейдем к самому скрипту:

#!/bin/sh

set -e

if [ "$(id -u)" -ne "0" ]; then
  >&2 echo "This script must be run as root"
  exit 1
fi

mirror=http://dl-cdn.alpinelinux.org/alpine
alpine_ver=3.8
apk_ver=2.10.0-r3
chroot_dir=./alpine-baseimage

wget ${mirror}/v${alpine_ver}/main/armhf/apk-tools-static-${apk_ver}.apk

tar xzf apk-tools-static-${apk_ver}.apk

mkdir -p ${chroot_dir}/usr/bin

cp /usr/bin/qemu-arm-static ${chroot_dir}/usr/bin

./sbin/apk.static -X ${mirror}/v${alpine_ver}/main -U --allow-untrusted --root ${chroot_dir} --initdb add alpine-base
mknod -m 666 ${chroot_dir}/dev/full c 1 7
mknod -m 666 ${chroot_dir}/dev/ptmx c 5 2
mknod -m 644 ${chroot_dir}/dev/random c 1 8
mknod -m 644 ${chroot_dir}/dev/urandom c 1 9
mknod -m 666 ${chroot_dir}/dev/zero c 1 5
mknod -m 666 ${chroot_dir}/dev/tty c 5 0

IMAGE=$(sh -c "tar -C ${chroot_dir} -c . | docker import -")

docker tag ${IMAGE} alpine:${alpine_ver}-armhf

Обратите внимание на то, что версия утилиты apk-tools-static (в данном случае 2.10.0-r3) является плавающей – почти наверняка к выходу данной статьи в свет она изменится. Скрипту определенно следовало бы быть немного сложнее, чтобы учитывать эту особенность, но здесь он должен оставаться как можно более простым. Прежде чем переходить к его модернизации, проделайте следующее:

  • откройте http://dl-cdn.alpinelinux.org/alpine/v3.8/main/armhf/, чтобы подсмотреть текущую версию apk-tools-static;
  • обновите версию apk-tools-static в тексте скрипта;
  • запустите скрипт с правами суперпользователя (т.к. скрипту необходимо производить различные манипуляции с chroot-окружением).

В результате будет создан базовый Docker-образ alpine:3.8-armhf.

Напоследок стоит сказать, что эмулятор позволяет решить подавляющее большинство задач, но, к сожалению, не всё через него запускается или собирается. Тем не менее, случаи отказов являются большой редкостью и сильно зависят от того, насколько экзотическими являются те вещи, для запуска которых эмулятор привлекается. По моему опыту, запущенные через эмулятор FTP-сервер vsftpd и сборка watchtower ведут себя нестабильно. К счастью, на этом список известных мне проблем заканчивается.

Накладывание патчей при сборке образа

Между пакетами исходных текстов, на базе которых строятся двоичные пакеты дистрибутивов GNU/Linux, и Docker-образами есть много общего. Нередки случаи, когда докеризуемая программа собирается из исходников. Как и в случае с пакетами исходных текстов, в рамках Docker-образа, возможно, придется заняться полировкой исходных текстов целевой программы – из-за того, что разработчики ее оригинала не учитывали особенности той системы, в которой программу в данный момент хотят заставить работать. Этот рецепт посвящен распространению патчей в составе исходников Docker-образов, чтобы, как и в случае пакетов исходных текстов, внесенные в тот или иной кусок (известного) кода изменения находились у всех на виду и могли быть проанализированы и переиспользованы другими разработчиками.

В качестве примера хочу привести Docker-образ QEMU из проекта MMB: https://github.com/tolstoyevsky/mmb/tree/master/qemu. Одной из главных задач для MMB в один прекрасный момент стало предоставление пользователям компактного образа с эмулятором (а по совместительству и системой виртуализации) QEMU, поэтому в качестве основы для образа был выбран Alpine. Затем, чтобы не зависеть от версии QEMU, которая в тот или иной момент времени находится в репозитории дистрибутива, было принято решение собирать эмулятор из исходников. После этого выяснилось, что некоторые зависимости QEMU отсутствуют в Alpine, и возникла необходимость их тоже собирать из исходных текстов.

Библиотека numactl, одна из зависимостей QEMU, до версии 2.0.12 не собиралась в Alpine из-за того, что Musl, стандартная библиотека языка C, которую использует дистрибутив, нигдене объявляет макрос __GLIBC_PREREQ, фигурирующий в одном из модулей библиотеки. Таким образом, numactl оказалась зависима от Glibc. Чтобы исправить эту ситуацию, был взят на вооружение менеджер патчей quilt, тот самый, который используется в пакетах исходных текстов Debian.

К сожалению, quilt никак не может стать частью дистрибутива, вечно находясь в edge, тестируемой версии Alpine, поэтому менеджер патчей придется тоже собрать из исходников или написать примитивную альтернативу на базе программы patch и цикла for. Преимуществами использования quilt для управления патчами являются в первую очередь легкость отключения того или иного патча в серии или, при необходимости, изменение порядка их внесения.

Чтобы исправить сложившуюся с numactl ситуацию, можно воспользоваться самим quilt’ом, но для начала надо получить исходники библиотеки.

$ git clone https://github.com/numactl/numactl.git
$ cd numactl

Затем необходимо сообщить quilt’у о намерении создать новый патч:

$ quilt new adapt_to_musl.patch
$ quilt add syscall.c

syscall.c – тот самый модуль, в котором используется макрос __GLIBC_PREREQ. Теперь в него можно внести изменение, устраняющее проблему.

Моим решением на скорую руку было просто-напросто удалить __GLIBC_PREREQ из условия

#if defined(__GLIBC__) && __GLIBC_PREREQ(2, 11)

Это решает проблему и никак не влияет на логику – в случае использования Musl остаток выражения всегда будет ложным. Тем не менее, более красивым решением является добавление перед этим условием заглушки, которая выглядит следующим образом.

#ifndef __GLIBC_PREREQ
# define __GLIBC_PREREQ(x,y) 0
#endif

И наконец, надо обновить патч, чтобы он отражал сделанные только что изменения.

$ quilt refresh

В результате всех этих манипуляций в корне дерева исходных текстов библиотеки будет создана директория patches с двумя файлами – adapt_to_musl.patch и series. Второй файл является так называемой серией патчей и представляет собой список, который на данный момент состоит всего из одного-единственного патча. Посредством редактирования можно повлиять на поведение quilt.

Теперь, чтобы созданный патч был применен к numactl во время сборки образа, необходимо позаботиться о том, чтобы директория patches находилась корне исходных текстов библиотеки. Затем, вызов quilt push -a инициирует накладывание всех патчей, указанных в серии.

GNU или не GNU/Linux

Такие дистрибутивы, как Debian или Ubuntu (и многие другие), используют GNU Coreutils и GNU C Library (Glibc) в качестве Unix-подобного окружения и стандартной библиотеки языка C соответственно. Таким образом, Проект GNU, как разработчик этих компонентов, играет важную роль в дистростроении, особенно если учесть тот факт, что для сборки вышеперечисленных частей используется компиляторы C/C++ из состава коллекции компиляторов от GNU (GNU Compiler Collection, GCC). В связи с этим Debian и Ubuntu следует называть дистрибутивами GNU/Linux, т.е. дистрибутивами, в которых различные компоненты Unix-подобной операционной системы от GNU в сочетании с ядром Linux образуют прочную основу, на которой строится всё остальное.

Было даже время, когда полнофункциональную Linux-подобную операционную систему не представлялось возможным создать без привлечения арсенала GNU. Несмотря на то, что достойная альтернатива Coreutils в лице Busybox существовала с незапамятных времен, свободные компиляторы C/C++ и альтернативные стандартные библиотеки языка C не всегда дотягивали до функциональности своих GNU’шных собратьев. Но времена изменились, и сейчас Musl является достойной альтернативой Glibc, а Clang не только научился конкурировать с компиляторами C/C++ из состава GCC, но и начал в чем-то их превосходить. Таким образом, в новых операционных системах на базе ядра Linux появилась возможность без значительного ущерба для функциональности свести к минимуму использование кода от GNU, компенсировав его аналогами, распространяющимися под пермессивной лицензией (Apache 2.0, все виды BSD, MIT и т.д.) или лучше «заточенными» под встраиваемые устройства. К числу таких операционных систем принадлежит Alpine. (Однако, справедливости ради, стоит заметить, что значительная часть дистрибутива собирается не чем иным, как GCC.) Таким образом, в данном конкретном случае от GNU/Linux остается только Linux, в результате чего полное название дистрибутива – Alpine Linux. Данный подход является семантическим именованием: взглянув на одно лишь имя операционной системы, возможно не только понять, что она построена на базе ядра Linux, но еще и то, что в ней, к примеру, используется нечто отличное от Glibc. Для сравнения, полным названием Debian является Debian GNU/Linux. Глядя на это название, можно с уверенностью сказать, что концентрация распространяющегося под лицензией GPLv3 кода в базовой системе очень высока. К сожалению, не все проекты по разработке Linux-подобных операционных используют семантиче­ское именование. Отличным примером является Gentoo Linux.

Nextcloud: не только хранилище

Автор: Евгений Голышев

Статья была опубликована в 233-м выпуске журнала Linux Format. По истечении двух месяцев с момента публикации статьи материал публикуется в нашем блоге.

Nextcloud – это платформа, которая позволяет развернуть на своих вычислительных мощностях альтернативу сразу нескольким коммерческим сервисам. В арсенале этой платформы имеются средства для синхронизации контактов, календарей, списков дел и SMS между различными устройствами, а также голосовые и видеозвонки. Однако Nextcloud – это в первую очередь платформа для создания Dropbox-подобного хранилища на своем собственном сервере. В данной статье я хочу рассказать о том, что предлагает Nextcloud 13, и от каких публичных сервисов можно отказаться прямо сейчас; но для начала немного истории.

Сначала был ownCloud

Nextcloud начинался как проект под названием ownCloud и сейчас является его логическим продолжением. ownCloud был анонсирован на конференции Camp KDE 2010 и стартовал в рамках инициативы KDE Social Desktop (о которой подробно рассказыва-
лось в LXF122). Проект задумывался как свободный аналог закрытых решений, самыми известными из которых на тот момент были Dropbox и Ubuntu One.

Первая стабильная версия платформы со знаковым номером 1.0 вышла 24-го июня 2010-го года – через полгода после анонса проекта. Еще примерно через полгода в США была зарегистрирована компания ownCloud Inc. с целью упрощения привлечения инвестиций и финансирования ключевых разработчиков проекта. Это событие ознаменовало превращение ownCloud в полностью самостоятельный проект.

Однако выбранная компанией бизнес-модель, предполагавшая наличие двух версий платформы – Community Edition и Enterprise Edition, в основном требовала концентрации на коммерче­ской версии платформы Enterprise Edition, с целью получения максимальной прибыли: это задача любого бизнеса, и дело тут не в цинизме. Разработчики испытывали сильный дискомфорт, поскольку сложно было уделять внимание одной версии без ущерба для другой. И 2 июня 2016 г. ключевые разработчики проекта приняли решение форкнуть ownCloud с целью его альтернативного развития. Новый проект, получивший имя Nextcloud, вобрал в себя все коммерче­ские функции, ранее доступные в ownCloud Enterprise Edition. Более того, вскоре после форка была создана компания Nextcloud GmbH, с целью предоставления коммерче­ской техниче­ской поддержки всем тем, кто использует платформу на производстве или создает собственные продукты на базе Nextcloud. Таким образом, разработчикам теперь не надо разрываться между двумя версиями платформы, а текущая бизнес-модель компании стала ближе по духу к философии свободного программного обеспечения.

Почему Nextcloud популярен

Не секрет, что сейчас Nextcloud является одним из популярнейших представителей серверного программного обеспечения. Тем не менее, когда разработчики ownCloud только пришли на рынок со своим продуктом, на первых порах он не был востребован широким кругом пользователей, но немного позднее произошли несколько независимых друг от друга событий, которые сильно подогрели интерес сообщества сначала к ownCloud, а затем и к Nextcloud. Вот, на мой взгляд, наиболее значимые из них.

  • Откровения Эдварда Сноудена в 2013-м году заставили многих задуматься о том, что необходимо полностью или частично ограничить себя в использовании публичных Интернет-сервисов.
  • Одноплатный компьютер Raspberry Pi, появившийся в 2012-м году, породил целую волну достаточно мощных устройств, которые могут использоваться в качестве сервера и в буквальном смысле доступны каждому. К примеру, сегодня легко можно найти 50-долларовый одноплатник с 4-х ядерным процессором, 2 ГБ ОЗУ и нативной поддержкой SATA. Этого будет вполне достаточно для того, чтобы построить на базе Nextcloud полноценный NAS и обслуживать десяток пользователей.
  • Некоммерческий удостоверяющий центр Let’s Encrypt в конце 2015-го года начал выдавать TLS-сертификаты всем желающим.

Первое событие стало отличным источником мотивации, а последние два в несколько раз снизили затраты на приобретение и сопровождение домашнего сервера. Несмотря на то, что по очевидным причинами решение на базе Raspberry Pi и Nextcloud является медленным и ненадежным, оно очень популярно в силу своей простоты.

Установка Nextcloud

Пришло время установить Nextcloud и начать обзор его возможностей. Возможности платформы – это основная тема статьи, а установка является скорее ее побочной частью. Таким образом, для того чтобы не погружаться в установку сильно глубоко, я предлагаю развернуть Nextcloud посредством Docker. Для этих целей я специально подготовил проект MMB, который поможет развернуть платформу на машине на базе 32-битного процессора ARM (Raspberry Pi, Orange Pi, Banana Pi и т.д.) или 64-битного процессора x86 (рабочие станции и серверы). Я уже описывал установку Nextcloud при помощи MMB в одной из предыдущих статей.

Apps: модульная природа Nextcloud

Сначала ownCloud задумывался как свободный аналог Dropbox и Ubuntu One, но 30-го января 2012-го года вышел ownCloud 3.0 с поддержкой так называемых приложений (apps), которые существенно расширяли базовый функционал платформы, превращая ее в Dropbox-подобное хранилище на стероидах. С тех пор было выпущено большое количество как официальных, так и сторонних приложений. Сейчас, такие функции Nextcloud, как голосовые и видеозвонки, синхронизации контактов, календарей, списков дел и SMS между различными устройствами, а также много других возможностей, реализованы именно в виде приложений. Казалось бы, что может быть проще, чем открыть PDF-файл, не покидая веб-интерфейс платформы. Но даже такая функция не предусмотрена базовой версий Nextcloud и реализована в виде отдельного приложения.
Nextcloud делит приложения на те, которые сразу доступны после установки, и на те, которые необходимо предварительно активировать. Так, сразу после установки Nextcloud и создания учетной записи администратора, такие приложения, как галерея, видеопроигрыватель и просмотрщик документов в формате PDF, будут доступны сразу. Дело в том, что эти приложения считаются относительно простыми, т.к. не требуют изменения базы данных, и могут быть молча активированы без видимых последствий для всей платформы. Однако, такие приложения, как Calendar и Contacts (синхронизация календарей и контактов между различными устройствами), требуют внесения изменений в базу данных, что уже является чем-то серьезным. Активация таких приложений должна быть инициирована администратором платформы. Все приложения, которым будет посвящена оставшаяся часть статьи потребуют активации после установки Nextcloud, поэтому кликните на том месте, где должна быть аватарка (в правом верхнем углу экрана), и в появившемся меню выберите Приложения (Apps). Затем в списке Ваши приложения (Your apps) найдите Calendar, Contacts, Notes, Phone Sync и Talk и нажмите напротив каждого из них Включить (Enable). А теперь я предлагаю перейти к обзору основных возможности Nextcloud – синхронизация файлов между различными устройствами, а затем рассмотреть каждое из этих приложений по отдельности.

File Sync

Nextcloud – это в первую очередь Dropbox-подобное хранилище, поэтому его основные задачи – организация приватного или общего доступа к файлам, синхронизация их между различными устройствами и т.д. Доступ к файлам может быть организован как через веб-интерфейс, так и через клиенты. Официальные клиенты доступны для всех популярных мобильных и настольных операционных систем. Более того, Nextcloud предоставляет доступ к файлам по протоколу WebDAV, поэтому для работы с хранилищем достаточно возможностей штатного файлового менеджера. WebDAV (Web-based Distributed Authoring and Versioning) представляет собой расширение протокола HTTP. Его основной задачей является предоставление клиентам возможности монтирования разделяемых ресурсов (shares) поверх HTTP так, чтобы их поведение принципиально не отличалось от таких сетевых файловых систем, как NFS или SMB. Однако стоит заметить, что по сравнению с файловыми менеджерами со встроенной поддержкой WebDAV официальные клиенты предлагают расширенные возможности работы с хранилищем. Поэтому я настоятельно рекомендую установить клиенты Nextcloud на все свои устройства для удобства работы с платформой.

Calendar и Contacts

Приложение Calendar не уступает конкуренту от Google.

Синхронизация календарей и контактов между различными устройствами являются одной из самых востребованных возможностей после синхронизации файлов. Как ни странно, Google давно преуспел в решении этой задачи, а Nextcloud предлагает в лице приложений Calendar и Contacts альтернативу известному сервису. Эти приложения организуют доступ к календарям и контактам по протоколам CalDAV и CardDAV, которые являются расширениями WebDAV (см. выше). Существует достаточно много клиентов, поддерживающих эти протоколы, но среди них нет официального. Тем не менее, разработчики Nextcloud рекомендуют использовать свободный клиент под названием DAVdroid, поддерживающий сразу оба протокола. DAVdroid позволяет синхронизировать штатные календарь и записную книжку в операционной системе с сервером. При этом синхронизация является двухсторонней, т.е., например, любое изменение на сервере приводит к изменению в штатном календаре, и наоборот.
Для того чтобы начать синхронизации, сначала установите на мобильное устройство DAVdroid и официальный клиент Nextcloud. Затем запустите последний, авторизуйтесь, перейдите в настройки приложения и выберете в меню «Синхронизировать календарь и контакты» (Sync calendar & contacts). После этого запустится DAVdroid и вам потребуется ввести только пароль от учетной записи Nextcloud, т.к. все остальные параметры для подключения к DAV-серверу будут предзаполнены. На первых порах DAVdroid будет задавать много вопросов. Он спросит, нужно ли отключить оптимизацию батареи, предложит установить приложение OpenTask для синхронизации ко всему прочему еще и списка задач, потребует разрешение на доступ к штатному календарю и записной книжке. Отнеситесь к этому с пониманием. После того как настройка будет закончена, вы сможете указывать в DAVdroid, какие из существующих календарей синхронизировать с сервером, а также создавать новые. К этому моменту DAVdroid установлен и настроен, поэтому не составит никакого труда заставить его синхронизировать штатную записную книжку с сервером.

Phone Sync

Приложение Phone Sync – единая точка сбора SMS со всех ваших устройств.

Примечательно, что Google, будучи разработчиком Android, не предлагает решение доступное прямо «из коробки» в своей операционной системе для синхронизации SMS с удаленным сервером. Очевидно, что это достаточно редкая необходимость, востребованная в узких кругах. Тем не менее, эта задача решается достаточно изящно посредством SMS Backup+ – свободного приложения под Android, которое позволяет синхронизировать SMS с gmail’овским ящиком. Однако, несмотря на то, что решение выглядит красиво, в качестве хранилища используется неподконтрольный пользователю публичный сервис, поэтому я расскажу об альтернативном подходе, который предлагает Nextcloud. Для этих целей в арсенале платформы есть официальное приложение и мобильный клиент под названием Nextcloud SMS. Клиент ставится на все мобильные устройства, которые требуется синхронизировать с сервером, но к счастью или сожалению, синхронизация SMS с сервером не является двусторонней, как например, в случае синхронизации календарей и записной книжки. Таким образом, каждое новое сообщение, приходящее на устройство, синхронизируется с сервером, но удаление этого сообщения на сервере, не приводит к его удалению на устройстве.

Notes

Приложение Notes отлично дополняет арсенал платформы функ­цией ведения
заметок.

Возможность ведения заметок в Nextcloud присутствует, но по своим возможностям не дотягивает ни до Google Keeps, ни тем более до Evernote. Однако, функция реализована в платформе настолько просто и красиво, что мало кого оставит равнодушным. Дело в том, что каждая заметка представляет собой обычный текстовый файл, а приложение и официальный мобильный клиент Nextcloud Notes являются простыми редакторами этих файлов. Таким образом, заметки автоматически получают в свое распоряжение все возможности платформы: шифрование, общий доступ, версионирование и т.д. При этом для пользователя все максимально прозрачно, т.е. он работает с сущностью «заметка», а не «файл».

Talk

Приложение Talk претендует на звание лучшей альтернативы Skype и Hangouts.

Возможность совершения голосовых и видеозвонков уже существует в Nextcloud достаточно давно, но она была признана готовой только в 13-й версии платформы, и теперь известна всему миру под именем Nextcloud Talk. В арсенале платформы есть как официальное приложение, так и клиенты под Android и iOS. Стратегической целью разработчиков является обеспечение паритета в функциональности с такими известными в этой области решениями, как Skype и Hangouts. Однако, на данный момент возможности мобильных клиентов немного отстают от того, что предлагает приложение, ограничиваясь только голосовыми и видеозвонками. Тем не менее, платформа предлагает следующие возможности:

  • end-to-end шифрование. Даже в случае компрометации сервера данные не поддаются анализу, т.к. шифруются на стороне клиента.
  • Возможность организации групповых аудио и видеоконференций.
  • Возможность приглашения участников, у которых нет учетных записей в системе.
  • Возможность предоставления доступа к содержимому экрана.

К особенностям платформы можно отнести организацию канала связи при помощи WebRTC и кодирование звука и видео с помощью H.265.
Для использования Nextcloud Talk в локальной сети не требуется никакой настройки, однако от него в этом случае будет мало толка. Для полноценного общения через Интернет понадобятся STUN- и TURN-сервер. STUN (Session Traversal Utilities for NAT) позволяет установить прямое соединение между двумя и более участниками, находящимися за NAT. Официальное приложение по умолчанию использует для этих целей stun.nextcloud.com:443, поэтому в ряде случаев от администратора Nextcloud не требуется никаких действий. Тем не менее, STUN-сервера может оказаться недостаточно, и первым сигналом этому будет черный экран при установлении соединения между участниками. Дело в том, что STUN-сервер бессилен, если участники находятся за так называемым симметричным NAT. В этом случае на помощь приходит TURN-сервер. TURN (Traversal Using Relay NAT) расширяет возможности STUN, позволяя установить прямое соединение между двумя и более участниками, которые находятся за симметричным NAT. Возможно в недалеком будущем ситуация изменится, но сейчас TURN-север необходимо поднимать для своих нужд самостоятельно. Для этих целей я настоятельно рекомендую использовать coturn. Для того чтобы собрать и запустить свежую версию coturn, я предлагаю снова обратиться к MMB.

Заключение

Nextcloud имеет богатую историю и такой же богатый список возможностей, и я думаю, что у меня получилось уделить достаточное количество внимания как первому, так и второму. Основная мысль, которую я хотел выразить в этой статье, заключается в том, что Nextcloud способен решать широкий спектр различных задач, которые выходят далеко за рамки хранилища файлов в стиле Dropbox. Таким образом, если вы обзаведетесь сервером на базе Nextcloud, перед вами откроются большие возможности, которые будут расти от релиза к релизу платформы. Основной недостаток и главное преимущество Nextcloud являются двумя сторонами одной медали: для того чтобы ваш экземпляр платформы всегда оставался безопасным и находился в актуальном состоянии, вам необходимо самостоятельно следить за выходом обновлений и своевременно их устанавливать, не забывая перед этим делать резервные копии базы данных и т.д., но это необходимое условие для того, чтобы всегда держать все свои данные под контролем. Удачного хакинга и не забывайте, что с великой силой приходит великая ответственность.

Debian vs. Devuan

Devuan (читается как DevOne) является производным от Debian GNU/Linux дистрибутивом. Принципиальное отличие между Debian и Devuan заключается в отсутствии привязки к systemd у последнего. Несмотря на то, что дистрибутиву уже три года, все еще остается много вопросов относительно его появления и назначения. После того как наша команда добавила возможность кастомизации Devuan сначала в Pieman, а затем в CusDeb, я наконец хочу немного рассказать об этом дистрибутиве в нашем блоге. Основным источником разногласий, которые вылились в работу над Devuan, является переход Debian и Ubuntu на использование системы инициализации systemd. Но обо всем по порядку.

Ускорение загрузки

В конце 2000-х несколько крупных производителей операционных систем на базе ядра Linux пришли к выводу, что необходимо ускорять время загрузки своих систем и, как следствие, брать на вооружение альтернативную систему инициализации. Так как именно система инициализации отвечает за загрузку операционной системы, то стало очевидно, что начинать нужно именно с нее. В течении долгого времени дистрибутивы GNU/Linux использовали для этих целей SysVinit, которая сейчас считается классической системой инициализации и в данной статье противопоставляется всем другим.

Компания Canonical, которая является основным разработчиком дистрибутива Ubuntu, начала работу над альтернативной системой инициализации под названием Upstart в середине 2000-х. Upstart дебютировала в Ubuntu 6.10 «Edgy Eft», заменив SysVinit, но окочательно новая система иницализации была интегрирована в дистрибутив только к выходу Ubuntu 9.10 «Karmic Koala». Затем на Upstart обратили внимание компании Google и Red Hat, интегрировав ее в свои продукты. Так, Upstart начала использоваться в ChromeOS и Red Hat Enterprise Linux 6. На новую систему инициализации даже планировал перейти Debian.

Upstart оказалась эффективней чем SysVinit благодаря событийно-ориентированной архитектуре. Системные сервисы стало возможным запускать и останавливать на основе событий, а не уровней запуска (runlevels), указанных в скриптах инициализации. Данный подход предполагал генерацию событий при запуске или остановке системных сервисов, что позволило организовать привязку к ним других сервисов. Таким образом, для определения последовательности запуска сервисов и оценки возможности их выполнения в параллельном режиме был взят на вооружение метод учета зависимостей. Работа в тандеме с ядром, которое также стало развиваться в сторону событийно-ориентированной архитектуры, благодаря чему появилась возможность асинхронной загрузки драйверов, заметно сократила время от нажатия кнопки включения до полной готовности всей системы.

Недостатки SysVinit мотивировали разработчиков Upstart приступить к созданию альтернативной системы инициализации, а достоинства launchd из Mac OS X и SMF из Solaris послужили основным источником ценных идей, которые помогли в решении поставленной задачи. Однако, по воле судьбы или случайному стечению обстоятельств, Upstart оказалась всего лишь трамплином для другой, более совершенной системы инициализации. Так, компания Red Hat, при участии разработчиков из Novell, IBM, Intel и Nokia, поставила перед собой цель создать систему инициализации, нацеленную на более интенсивную параллелизацию выполнения сервисов на этапе загрузки. Проект получил название systemd и отличался более радикальным подходом к решению некоторых задач. К примеру, если Upstart была совместима со скриптами инициализации SysVinit, то systemd предлагала для этих целей новый синтаксис и, таким образом, не была завязана ни на Bash, ни на любую другую оболочку. Тем не менее, на этам этапе все было хорошо. Волна критики накатила на проект немного позднее, когда стало очевидно, что акцент разработчиков немного сместился в сторону, отличную от первоначальных целей. Так, в один прекрасный момент проект под названием systemd стал позиционироваться не как «альтернативная система инициализации», а как «системный менеджер». Система инициализации в этом проекте стала одним из многочисленных компонентов, а весь проект стал нацелен на управление различными аспектами работы системы. Также стоит заметить, что немалая доля критики свалилась на systemd из-за того, что лидером проекта является не кто иной, как сам Леннарт Поттеринг (Lennart Poettering), в прошлом разработчик звукового сервера PulseAudio, который в начале своего пути не отличался стабильностью работы (в основном из-за аудиодрайверов, а не ошибок в коде PulseAudio), что и является причиной ненависти как к проекту, так и к его автору.

Появление Devuan

Наконец, я подобрался к основным мотивам, которые заставили разработчиков Devuan форкнуть Debian с целью его альтернативного развития. В конце 2013-го – начале 2014-го Debian в очередной раз вернулся к актуальной для себя задаче – переходу на более современную систему инициализации. В качестве кандидатов рассматривались Upstart и systemd, и по результатам голосования победила последняя. Следом за Debian пошла Ubuntu. Стоит заметить, что выбор стоял между системой инициализации и системным менеджером, одним из компонентов которого являлась система инициализации. По итогам интеграции systemd в Debian дистрибутив не только перешел на новую систему инициализации, но и оказался сильно завязанным на системном менеджере, который был призван управлять всеми аспектами работы системы. В итоге, systemd был поставлен в один ряд с ядром и стандартной библиотекой языка C, для которых в дистрибутиве не предусмотрены альтернативы. Jessie стал первым выпуском Debian, который не мог функционировать без systemd. Поэтом группа разработчиков Veteran Unix Admins, несогласная с этой политикой, выпустила в рамках проекта Devuan свободную от systemd версию Jessie. Для того чтобы этого добиться, разработчикам потребовалось внести изменение в 381 пакет. Так появился первый выпуск Devuan, позволивший пользователям Debian использовать или не использовать systemd в зависимости от их желания.

Заключение

Я написал эту статью в первую очередь для того, чтобы помочь нашим пользователям разобраться в причинах появления еще одного производного от Debian дистрибутива. При этом я не являюсь противником ни systemd, ни Леннарта Поттеринга, и остаюсь пользователем Debian (рабочая станция) и Ubuntu (ноутбук). Тем не менее, я считаю, что безальтернативная поставка systemd в крупнейших дистрибутивах является крайностью. В связи со всем этим я попытался сделать статью как можно более беспристрастной. Но теперь наконец я могу сказать, что я восхищаюсь разработчиками Devuan и ценю проделанную ими работу, и рад заявить, что CusDeb поддерживает этот дистрибутив.

CusDeb Beta 2

Рады сообщить о выходе CusDeb Beta 2. Главной особенностью новой версии стало использование Pieman в качестве бэкенда подсистемы сборки образов (раньше для этих целей использовался rpi23-gen-image). Pieman стал первым ключевым компонентом CusDeb, исходные тексты которого были опубликованы на GitHub. Также стоит отметить, что CusDeb Beta 2 предлагает кастомизировать Raspbian Stretch, Ubuntu Xenial и Ubuntu Artful для четырех моделей Raspberry Pi — с 1-ой по 3-ю, а также Raspberry Zero. Более того, Ubuntu Artful предлагается только в 64-битном варианте для Raspberry Pi 3. Поддержку 64-битных сборок наши пользователи просили уже давно.

Нам пришлось отказаться от ранее поддерживаемых Debian Jessie и Debian Stretch, которые нам достались от rpi23-gen-image, но в ближайшее время мы планируем вернуть поддержку Debian Stretch.

Также хотелось бы отметить и то, что в случае неудачной сборки теперь пользователю приходит email с прикрепленным логом сборки. Несмотря на то, что за все время существования CusDeb нашей команде удалось наладить предсказуемый процесс сборки, иногда все же возможны падения как по нашей вине, так и по вине самих дистрибутивов, которые мы предлагаем кастомизировать. Лог сборки, который мы отправляем в этих случаях, дает еще одну возможность сделать наш сервис лучше. Мы призываем наших пользователей анализировать причины падения сборок и заводить issue в проекте Pieman.