Nextcloud to aplikacja do synchronizacji i udostępniania plików typu open source, która oferuje bezpłatne, bezpieczne i łatwo dostępne przechowywanie plików w chmurze, a także szereg narzędzi rozszerzających jej zestaw funkcji. Jest bardzo podobny do popularnych Dropbox, iCloud i Google Drive, ale w przeciwieństwie do Dropbox, Nextcloud nie oferuje hostingu przechowywania plików poza siedzibą firmy.
W tym poście na blogu zamierzamy wdrożyć konfigurację o wysokiej dostępności dla naszej prywatnej infrastruktury „Dropbox” przy użyciu Nextcloud, GlusterFS, Percona XtraDB Cluster (MySQL Galera Cluster), ProxySQL z ClusterControl jako narzędzia automatyzacji do zarządzania i monitorowania baz danych oraz poziomów równoważenia obciążenia.
Uwaga:możesz również użyć klastra MariaDB, który korzysta z tej samej podstawowej biblioteki replikacji, co w klastrze Percona XtraDB. Z perspektywy równoważenia obciążenia ProxySQL zachowuje się podobnie do MaxScale, ponieważ może zrozumieć ruch SQL i ma szczegółową kontrolę nad sposobem kierowania ruchu.
Architektura bazy danych dla Nexcloud
W tym poście na blogu użyliśmy łącznie 6 węzłów.
- 2 x serwery proxy
- 3 x baza danych + serwery aplikacji
- 1 x serwer kontrolera (ClusterControl)
Poniższy diagram ilustruje naszą ostateczną konfigurację:
W przypadku klastra Percona XtraDB wymagane są co najmniej 3 węzły dla replikacja z wieloma wzorcami. Aplikacje Nextcloud są zlokalizowane w obrębie serwerów baz danych, dlatego GlusterFS musi być również skonfigurowany na tych hostach.
Warstwa równoważenia obciążenia składa się z 2 węzłów dla celów redundancji. Użyjemy ClusterControl do wdrożenia warstwy bazy danych i warstw równoważenia obciążenia. Wszystkie serwery działają na CentOS 7 z następującą definicją /etc/hosts na każdym węźle:
192.168.0.21 nextcloud1 db1
192.168.0.22 nextcloud2 db2
192.168.0.23 nextcloud3 db3
192.168.0.10 vip db
192.168.0.11 proxy1 lb1 proxysql1
192.168.0.12 proxy2 lb2 proxysql2
Zauważ, że GlusterFS i MySQL to bardzo intensywne procesy. Jeśli postępujesz zgodnie z tą konfiguracją (GlusterFS i MySQL znajdują się na jednym serwerze), upewnij się, że masz przyzwoitą specyfikację sprzętową dla serwerów.
Wdrożenie bazy danych Nextcloud
Zaczniemy od wdrożenia bazy danych dla naszego trzywęzłowego klastra Percona XtraDB przy użyciu ClusterControl. Zainstaluj ClusterControl, a następnie skonfiguruj bezhasłowe SSH we wszystkich węzłach, które będą zarządzane przez ClusterControl (3 PXC + 2 proxy). W węźle ClusterControl wykonaj:
$ whoami
root
$ ssh-copy-id 192.168.0.11
$ ssh-copy-id 192.168.0.12
$ ssh-copy-id 192.168.0.21
$ ssh-copy-id 192.168.0.22
$ ssh-copy-id 192.168.0.23
**Po wyświetleniu monitu wprowadź hasło roota dla odpowiedniego hosta.
Otwórz przeglądarkę internetową i przejdź do https://{ClusterControl-IP-address}/clustercontrol i utwórz superużytkownika. Następnie przejdź do Wdróż -> MySQL Galera. Postępuj zgodnie z instrukcjami kreatora wdrażania. W drugim etapie 'Define MySQL Servers' wybierz Percona XtraDB 5.7 i określ adres IP dla każdego węzła bazy danych. Upewnij się, że po wprowadzeniu szczegółów węzła bazy danych pojawi się zielony haczyk, jak pokazano poniżej:
Kliknij „Wdróż”, aby rozpocząć wdrażanie. Klaster bazy danych będzie gotowy za 15-20 minut. Możesz śledzić postęp wdrażania w Aktywność -> Zadania -> Utwórz klaster -> Pełne szczegóły zadania. Po wdrożeniu klaster pojawi się na liście w panelu Database Cluster.
Możemy teraz przejść do wdrożenia systemu równoważenia obciążenia bazy danych.
Wdrożenie systemu równoważenia obciążenia bazy danych Nextcloud
Zaleca się, aby Nextcloud działał w konfiguracji z jednym zapisem, w której zapisy będą przetwarzane przez jednego mastera na raz, a odczyty mogą być dystrybuowane do innych węzłów. Możemy użyć ProxySQL 2.0, aby osiągnąć tę konfigurację, ponieważ może on kierować zapytania zapisu do jednego mastera.
Aby wdrożyć ProxySQL, kliknij Cluster Actions> Add Load Balancer> ProxySQL> Wdróż ProxySQL. Wprowadź wymagane informacje, jak zaznaczono czerwonymi strzałkami:
Wypełnij wszystkie niezbędne szczegóły, jak zaznaczono strzałkami powyżej. Adres serwera to serwer lb1, 192.168.0.11. W dalszej części określamy hasło administratora ProxySQL i monitorujących użytkowników. Następnie uwzględnij wszystkie serwery MySQL w zestawie równoważenia obciążenia, a następnie wybierz „Nie” w sekcji Transakcje niejawne. Kliknij „Wdróż ProxySQL”, aby rozpocząć instalację.
Powtórz te same kroki, co powyżej dla dodatkowego modułu równoważenia obciążenia, lb2 (ale zmień „Adres serwera” na adres IP lb2). W przeciwnym razie nie mielibyśmy nadmiarowości w tej warstwie.
Nasze węzły ProxySQL są teraz zainstalowane i skonfigurowane z dwiema grupami hostów dla Galera Cluster. Jeden dla grupy jednego nadrzędnego (grupa hostów 10), gdzie wszystkie połączenia będą przekazywane do jednego węzła Galera (jest to przydatne, aby zapobiec zakleszczeniu wielu nadrzędnych) i grupy wielu nadrzędnych (grupa hostów 20) dla wszystkich obciążeń tylko do odczytu, które zostanie zbalansowany na wszystkich serwerach zaplecza MySQL.
Następnie musimy wdrożyć wirtualny adres IP, aby zapewnić pojedynczy punkt końcowy dla naszych węzłów ProxySQL, dzięki czemu aplikacja nie będzie musiała definiować dwóch różnych hostów ProxySQL. Zapewni to również możliwość automatycznego przełączania awaryjnego, ponieważ wirtualny adres IP zostanie przejęty przez zapasowy węzeł ProxySQL, jeśli coś pójdzie nie tak z podstawowym węzłem ProxySQL.
Przejdź do ClusterControl -> Zarządzaj -> Systemy równoważenia obciążenia -> Utrzymuj aktywność -> Wdróż utrzymuj aktywność. Wybierz "ProxySQL" jako typ równoważenia obciążenia i wybierz dwa różne serwery ProxySQL z listy rozwijanej. Następnie określ wirtualny adres IP oraz interfejs sieciowy, którego będzie nasłuchiwać, jak pokazano w poniższym przykładzie:
Po zakończeniu wdrażania na pasku podsumowania klastra powinny zostać wyświetlone następujące szczegóły:
Na koniec utwórz nową bazę danych dla naszej aplikacji, przechodząc do ClusterControl -> Zarządzaj -> Schematy i użytkownicy -> Utwórz bazę danych i podaj „nextcloud”. ClusterControl utworzy tę bazę danych na każdym węźle Galera. Nasz poziom systemu równoważenia obciążenia jest już gotowy.
Wdrożenie GlusterFS dla Nextcloud
Poniższe kroki należy wykonać na nextcloud1, nextcloud2, nextcloud3, chyba że określono inaczej.
Krok pierwszy
Zalecane jest posiadanie oddzielnego dla przechowywania GlusterFS, więc dodamy dodatkowy dysk w /dev/sdb i utworzymy nową partycję:
$ fdisk /dev/sdb
Postępuj zgodnie z instrukcjami kreatora tworzenia partycji fdisk, naciskając następujący klawisz:
n > p > Enter > Enter > Enter > w
Krok drugi
Sprawdź, czy /dev/sdb1 został utworzony:
$ fdisk -l /dev/sdb1
Disk /dev/sdb1: 8588 MB, 8588886016 bytes, 16775168 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Krok trzeci
Sformatuj partycję za pomocą XFS:
$ mkfs.xfs /dev/sdb1
Krok czwarty
Zamontuj partycję jako /storage/brick:
$ mkdir /glusterfs
$ mount /dev/sdb1 /glusterfs
Sprawdź, czy wszystkie węzły mają następujący układ:
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 40G 0 disk
└─sda1 8:1 0 40G 0 part /
sdb 8:16 0 8G 0 disk
└─sdb1 8:17 0 8G 0 part /glusterfs
Krok piąty
Utwórz podkatalog o nazwie brick w /glusterfs:
$ mkdir /glusterfs/brick
Krok szósty
W celu zapewnienia nadmiarowości aplikacji możemy użyć GlusterFS do replikacji plików między hostami. Najpierw zainstaluj repozytorium GlusterFS dla CentOS:
$ yum install centos-release-gluster -y
$ yum install epel-release -y
Krok siódmy
Zainstaluj serwer GlusterFS
$ yum install glusterfs-server -y
Krok ósmy
Włącz i uruchom demona gluster:
$ systemctl enable glusterd
$ systemctl start glusterd
Krok dziewiąty
W nextcloud1 sprawdź inne węzły:
(nextcloud1)$ gluster peer probe 192.168.0.22
(nextcloud1)$ gluster peer probe 192.168.0.23
Możesz zweryfikować status peera za pomocą następującego polecenia:
(nextcloud1)$ gluster peer status
Number of Peers: 2
Hostname: 192.168.0.22
Uuid: f9d2928a-6b64-455a-9e0e-654a1ebbc320
State: Peer in Cluster (Connected)
Hostname: 192.168.0.23
Uuid: 100b7778-459d-4c48-9ea8-bb8fe33d9493
State: Peer in Cluster (Connected)
Krok dziesiąty
W nextcloud1 utwórz zreplikowany wolumen w sondowanych węzłach:
(nextcloud1)$ gluster volume create rep-volume replica 3 192.168.0.21:/glusterfs/brick 192.168.0.22:/glusterfs/brick 192.168.0.23:/glusterfs/brick
volume create: rep-volume: success: please start the volume to access data
Krok jedenasty
Uruchom replikowany wolumen w nextcloud1:
(nextcloud1)$ gluster volume start rep-volume
volume start: rep-volume: success
Sprawdź, czy zreplikowany wolumen i procesy są w trybie online:
$ gluster volume status
Status of volume: rep-volume
Gluster process TCP Port RDMA Port Online Pid
------------------------------------------------------------------------------
Brick 192.168.0.21:/glusterfs/brick 49152 0 Y 32570
Brick 192.168.0.22:/glusterfs/brick 49152 0 Y 27175
Brick 192.168.0.23:/glusterfs/brick 49152 0 Y 25799
Self-heal Daemon on localhost N/A N/A Y 32591
Self-heal Daemon on 192.168.0.22 N/A N/A Y 27196
Self-heal Daemon on 192.168.0.23 N/A N/A Y 25820
Task Status of Volume rep-volume
------------------------------------------------------------------------------
There are no active volume tasks
Krok dwunasty
Zamontuj zreplikowany wolumin na /var/www/html. Utwórz katalog:
$ mkdir -p /var/www/html
Krok trzynasty
13) Dodaj następujący wiersz do /etc/fstab, aby umożliwić automatyczne montowanie:
/dev/sdb1 /glusterfs xfs defaults,defaults 0 0
localhost:/rep-volume /var/www/html glusterfs defaults,_netdev 0 0
Krok czternasty
Zamontuj GlusterFS do /var/www/html:
$ mount -a
I zweryfikuj za pomocą:
$ mount | grep gluster
/dev/sdb1 on /glusterfs type xfs (rw,relatime,seclabel,attr2,inode64,noquota)
localhost:/rep-volume on /var/www/html type fuse.glusterfs (rw,relatime,user_id=0,group_id=0,default_permissions,allow_other,max_read=131072)
Zreplikowany wolumin jest teraz gotowy i zamontowany w każdym węźle. Możemy teraz przystąpić do wdrażania aplikacji.
Wdrażanie aplikacji Nextcloud
Poniższe kroki należy wykonać na nextcloud1, nextcloud2 i nextcloud3, chyba że określono inaczej.
Nextcloud wymaga PHP 7.2 i nowszych, a w przypadku dystrybucji CentOS musimy włączyć wiele repozytoriów, takich jak EPEL i Remi, aby uprościć proces instalacji.
Krok pierwszy
Jeśli SELinux jest włączony, najpierw go wyłącz:
$ setenforce 0
$ sed -i 's/^SELINUX=.*/SELINUX=permissive/g' /etc/selinux/config
Możesz także uruchomić Nextcloud z włączonym SELinux, postępując zgodnie z tym przewodnikiem.
Krok drugi
Zainstaluj wymagania Nextcloud i włącz repozytorium Remi dla PHP 7.2:
$ yum install -y epel-release yum-utils unzip curl wget bash-completion policycoreutils-python mlocate bzip2
$ yum install -y http://rpms.remirepo.net/enterprise/remi-release-7.rpm
$ yum-config-manager --enable remi-php72
Krok trzeci
Zainstaluj zależności Nextcloud, głównie pakiety związane z Apache i PHP 7.2:
$ yum install -y httpd php72-php php72-php-gd php72-php-intl php72-php-mbstring php72-php-mysqlnd php72-php-opcache php72-php-pecl-redis php72-php-pecl-apcu php72-php-pecl-imagick php72-php-xml php72-php-pecl-zip
Krok czwarty
Włącz Apache i uruchom go:
$ systemctl enable httpd.service
$ systemctl start httpd.service
Krok piąty
Utwórz dowiązanie symboliczne dla PHP, aby używać binarnego PHP 7.2:
$ ln -sf /bin/php72 /bin/php
Krok szósty
Na nextcloud1, pobierz Nextcloud Server stąd i rozpakuj go:
$ wget https://download.nextcloud.com/server/releases/nextcloud-17.0.0.zip
$ unzip nextcloud*
Krok siódmy
W nextcloud1 skopiuj katalog do /var/www/html i przypisz poprawne prawo własności:
$ cp -Rf nextcloud /var/www/html
$ chown -Rf apache:apache /var/www/html
**Zauważ, że proces kopiowania do /var/www/html zajmie trochę czasu ze względu na replikację woluminu GlusterFS.
Krok ósmy
Zanim przejdziemy do otwarcia kreatora instalacji, musimy wyłączyć zmienną pxc_strict_mode na inną niż „ENFORCING” (wartość domyślna). Wynika to z faktu, że import bazy danych Nextcloud będzie zawierał wiele tabel bez zdefiniowanego klucza podstawowego, co nie jest zalecane do uruchamiania w Galera Cluster. Więcej szczegółów znajduje się w sekcji Strojenie poniżej.
Aby zmienić konfigurację za pomocą ClusterControl, po prostu przejdź do Zarządzaj -> Konfiguracje -> Zmień/Ustaw parametry:
Wybierz z listy wszystkie instancje bazy danych i wpisz:
- Grupa:MYSQLD
- Parametr:pxc_strict_mode
- Nowa wartość:DOPUSZCZALNA
ClusterControl automatycznie wykona niezbędne zmiany na każdym węźle bazy danych. Jeśli wartość można zmienić w czasie działania, będzie ona obowiązywać natychmiast. ClusterControl konfiguruje również wartość w pliku konfiguracyjnym MySQL, aby zapewnić trwałość. Powinieneś zobaczyć następujący wynik:
Krok dziewiąty
Teraz jesteśmy gotowi do skonfigurowania naszej instalacji Nextcloud. Otwórz przeglądarkę i przejdź do serwera HTTP nextcloud1 pod adresem http://192.168.0.21/nextcloud/, a zostanie wyświetlony następujący kreator konfiguracji:
Skonfiguruj sekcję „Pamięć i baza danych” z następującą wartością:
- Folder danych:/var/www/html/nextcloud/data
- Skonfiguruj bazę danych:MySQL/MariaDB
- Nazwa użytkownika:następna chmura
- Hasło:(hasło użytkownika nextcloud)
- Baza danych:następna chmura
- Host:192.168.0.10:6603 (Wirtualny adres IP z portem ProxySQL)
Kliknij „Zakończ konfigurację”, aby rozpocząć proces konfiguracji. Poczekaj, aż się zakończy, a zostaniesz przekierowany do pulpitu nawigacyjnego Nextcloud dla użytkownika „admin”. Instalacja została zakończona. Następna sekcja zawiera wskazówki dotyczące dostrajania, aby działały wydajnie z Galera Cluster.
Dostrajanie bazy danych Nextcloud
Klucz główny
Posiadanie klucza podstawowego w każdej tabeli ma kluczowe znaczenie dla replikacji zestawu zapisu Galera Cluster. W przypadku stosunkowo dużej tabeli bez klucza podstawowego duża transakcja aktualizacji lub usunięcia całkowicie zablokowałaby klaster na bardzo długi czas. Aby uniknąć dziwactwa i skrajnych przypadków, po prostu upewnij się, że wszystkie tabele korzystają z silnika pamięci masowej InnoDB z jawnym kluczem podstawowym (unikatowy klucz się nie liczy).
Domyślna instalacja Nextcloud utworzy kilka tabel pod określoną bazą danych, a niektóre z nich nie będą zgodne z tą regułą. Aby sprawdzić, czy tabele są kompatybilne z Galerą, możemy uruchomić następującą instrukcję:
mysql> SELECT DISTINCT CONCAT(t.table_schema,'.',t.table_name) as tbl, t.engine, IF(ISNULL(c.constraint_name),'NOPK','') AS nopk, IF(s.index_type = 'FULLTEXT','FULLTEXT','') as ftidx, IF(s.index_type = 'SPATIAL','SPATIAL','') as gisidx FROM information_schema.tables AS t LEFT JOIN information_schema.key_column_usage AS c ON (t.table_schema = c.constraint_schema AND t.table_name = c.table_name AND c.constraint_name = 'PRIMARY') LEFT JOIN information_schema.statistics AS s ON (t.table_schema = s.table_schema AND t.table_name = s.table_name AND s.index_type IN ('FULLTEXT','SPATIAL')) WHERE t.table_schema NOT IN ('information_schema','performance_schema','mysql') AND t.table_type = 'BASE TABLE' AND (t.engine <> 'InnoDB' OR c.constraint_name IS NULL OR s.index_type IN ('FULLTEXT','SPATIAL')) ORDER BY t.table_schema,t.table_name;
+---------------------------------------+--------+------+-------+--------+
| tbl | engine | nopk | ftidx | gisidx |
+---------------------------------------+--------+------+-------+--------+
| nextcloud.oc_collres_accesscache | InnoDB | NOPK | | |
| nextcloud.oc_collres_resources | InnoDB | NOPK | | |
| nextcloud.oc_comments_read_markers | InnoDB | NOPK | | |
| nextcloud.oc_federated_reshares | InnoDB | NOPK | | |
| nextcloud.oc_filecache_extended | InnoDB | NOPK | | |
| nextcloud.oc_notifications_pushtokens | InnoDB | NOPK | | |
| nextcloud.oc_systemtag_object_mapping | InnoDB | NOPK | | |
+---------------------------------------+--------+------+-------+--------+
Powyższe dane wyjściowe pokazują, że istnieje 7 tabel, które nie mają zdefiniowanego klucza podstawowego. Aby naprawić powyższe, po prostu dodaj klucz podstawowy z kolumną autoinkrementacji. Uruchom następujące polecenia na jednym z serwerów baz danych, na przykład nexcloud1:
(nextcloud1)$ mysql -uroot -p
mysql> ALTER TABLE nextcloud.oc_collres_accesscache ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_collres_resources ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_comments_read_markers ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_federated_reshares ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_filecache_extended ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_notifications_pushtokens ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
mysql> ALTER TABLE nextcloud.oc_systemtag_object_mapping ADD COLUMN `id` INT PRIMARY KEY AUTO_INCREMENT;
Po zastosowaniu powyższych modyfikacji, możemy ponownie skonfigurować pxc_strict_mode z powrotem do zalecanej wartości „WYMUSZENIE”. Powtórz krok 8 w sekcji „Wdrażanie aplikacji” z odpowiednią wartością.
PRZECZYTAJ POTWIERDZONY poziom izolacji
Zalecany poziom izolacji transakcji zgodnie z zaleceniami Nextcloud to użycie READ-COMMITTED, podczas gdy Galera Cluster ma domyślnie bardziej rygorystyczny poziom izolacji REPEATABLE-READ. Użycie READ-COMMITTED może uniknąć utraty danych w scenariuszach dużego obciążenia (np. używając klienta synchronizacji z wieloma klientami/użytkownikami i wieloma równoległymi operacjami).
Aby zmodyfikować poziom transakcji, przejdź do ClusterControl -> Zarządzaj -> Konfiguracje -> Zmień/ustaw parametr i określ:
Kliknij „Kontynuuj”, a ClusterControl natychmiast zastosuje zmiany w konfiguracji. Nie jest wymagane ponowne uruchomienie bazy danych.
Wieleinstancyjna następna chmura
Ponieważ wykonaliśmy instalację na nextcloud1 podczas uzyskiwania dostępu do adresu URL, ten adres IP jest automatycznie dodawany do zmiennej „trusted_domains” w Nextcloud. Gdy próbowałeś uzyskać dostęp do innych serwerów, na przykład serwera pomocniczego, http://192.168.0.22/nextcloud, zobaczysz błąd, że ten host nie jest autoryzowany i musi zostać dodany do zmiennej zaufanej_domeny.
Dlatego dodaj adres IP wszystkich hostów w tablicy "trusted_domain" wewnątrz /var/www/html/nextcloud/config/config.php, jak poniżej:
'trusted_domains' =>
array (
0 => '192.168.0.21',
1 => '192.168.0.22',
2 => '192.168.0.23'
),
Powyższa konfiguracja umożliwia użytkownikom dostęp do wszystkich trzech serwerów aplikacji za pośrednictwem następujących adresów URL:
- http://192.168.0.21/nextcloud (nextcloud1)
- http://192.168.0.22/nextcloud (nextcloud2)
- http://192.168.0.23/nextcloud (nextcloud3)
Uwaga:możesz dodać warstwę modułu równoważenia obciążenia do tych trzech wystąpień Nextcloud, aby osiągnąć wysoką dostępność dla warstwy aplikacji, używając odwrotnych serwerów proxy HTTP dostępnych na rynku, takich jak HAProxy lub nginx. To wykracza poza zakres tego wpisu na blogu.
Korzystanie z Redis do blokowania plików
Mechanizm transakcyjnego blokowania plików Nextcloud blokuje pliki, aby uniknąć uszkodzenia plików podczas normalnej pracy. Zaleca się zainstalowanie Redis, aby zadbać o blokowanie plików transakcyjnych (jest to domyślnie włączone), co odciąży klaster bazy danych od obsługi tego ciężkiego zadania.
Aby zainstalować Redis, po prostu:
$ yum install -y redis
$ systemctl enable redis.service
$ systemctl start redis.service
Dołącz następujące wiersze wewnątrz /var/www/html/nextcloud/config/config.php:
'filelocking.enabled' => true,
'memcache.locking' => '\OC\Memcache\Redis',
'redis' => array(
'host' => '192.168.0.21',
'port' => 6379,
'timeout' => 0.0,
),
Aby uzyskać więcej informacji, zapoznaj się z tą dokumentacją, Blokowanie plików transakcyjnych.
Wnioski
Nextcloud można skonfigurować tak, aby była skalowalną i wysoce dostępną usługą hostingu plików, spełniającą wymagania dotyczące udostępniania prywatnych plików. W tym blogu pokazaliśmy, w jaki sposób można wprowadzić nadmiarowość w warstwie Nextcloud, systemie plików i bazie danych.