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 являются двумя сторонами одной медали: для того чтобы ваш экземпляр платформы всегда оставался безопасным и находился в актуальном состоянии, вам необходимо самостоятельно следить за выходом обновлений и своевременно их устанавливать, не забывая перед этим делать резервные копии базы данных и т.д., но это необходимое условие для того, чтобы всегда держать все свои данные под контролем. Удачного хакинга и не забывайте, что с великой силой приходит великая ответственность.

Простая установка Nextcloud 13 на Raspberry Pi с помощью MMB

Установка Nextcloud 13 может отнять несколько часов даже у продвинутых пользователей Linux. Помимо Nextcloud, необходимо установить и настроить PHP 7 c расширениями, веб-сверер, а также систему управления базами данных. Опытные пользователи конечно не ставят всё это с нуля, а пользуются готовыми Docker-контейнерами. Мы подготовили всё необходимое для создания и запуска такого контейнера на вашем Raspberry Pi и делимся этим с вами.

Итак, запустите на своём Raspberry Pi минимальный образ Raspbian или Ubuntu и установите Git, Docker и Docker Compose:

sudo apt-get update
sudo apt-get install git docker-compose
curl -sSL https://get.docker.com | sh

Затем, клонируйте репозиторий MMB c GitHub:

cd ~
git clone https://github.com/tolstoyevsky/mmb.git
cd mmb

В MMB находятся два Docker-файла со всем необходимым для создания и запуска контейнеров с MariaDB и Nextcloud 13. Если не разбираетесь в Docker, то просто выполните следующие команды:

sudo ./mmb.sh mariadb armhf
sudo ./mmb.sh nextcloud armhf

Убедитесь, что порт 3306 не занят, затем запустите оба контейнера с помощью docker-compose:

cd mariadb
docker-compose up -d
cd ../nextcloud
docker-compose up -d

Теперь откройте в браузере http://[ip-адрес вашей Raspberry Pi в локальной сети]:8001/nc

Вы всё сделали правильно, если видите страницу создания учетной записи администратора Nextloud. Если что-то не получается, то пишите в комментариях, подскажем. Либо купите готовый образ Nextcloud 13 для Raspberry Pi с технической поддержкой от нашей команды.