Как запустить сервис с собственным облаком?

Окончательно решил удалить всю доступную для удаления информацию со всех публичных облаков после прочтения книги «Linux в действии». Также отдаю себе отчет, что публичный облака имеют возможность мою информацию не удалять в случае моего желания ее удалить. Они могут только изменить флаг ее отображения для меня. Но мне важно было другое, что далее я не намерен передавать в корпорации практически всю мою информацию о себе и своих близких, а намерен ее дозировать насколько могу.

Какие начальные требования были:

  1. Возможность загрузки файлов в собственное облако и обратно.

  2. Возможность работы с календарем. Лично для меня это является одном из самых важных пунктов, так как я уже давно знаком с темой «Организация времени» и соответствующим инструментарием.

  3. Возможность работы с контактами. Также как и календарь - это необходимость для работы с людьми и свой сетью из них.

  4. Все возможности работы с облаком должны быть доступны со всех устройств.

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

VM

Для работы облака у меня развернута отдельная VM с backup. Концептуальную схему можно увидеть тут. Если говорить о работе с дискам, то она выглядит так:

!include plantuml/nextcloud_disks.plantuml

Если еще короче, то к серверу с Proxmox присоединены 2 диска с зеркалированием. На этих дисках стоит файловая система ZFS и там заведено несколько папок, которые проброшены в VMs и примонтированы как диски. Такая логическая организация дисков позволила манипудировать общими данными на нескольких VMs.

Общая конфигурация VM с условным наименованием «cloud»:

$ qm config ***
agent: 1
boot: order=scsi0;ide2;net0
cores: 3
cpu: x86-64-v2-AES
ide2: local:iso/ubuntu-24.04.1-live-server-amd64.iso,media=cdrom,size=2708862K
memory: 10000
meta: creation-qemu=9.0.2,ctime=1725665268
name: cloud
net0: virtio=BC:24:11:32:C8:AE,bridge=vmbr0,firewall=1
numa: 0
onboot: 1
ostype: l26
scsi0: main:vm-108-disk-2,iothread=1,size=350G
scsihw: virtio-scsi-single
smbios1: uuid=81fa01ed-5124-4e92-89d0-d51ba92b714b
sockets: 2
virtiofs0: documents,direct-io=1
virtiofs1: media,direct-io=1
virtiofs2: private_media,direct-io=1

docker-compose и запуск основных сервисов

Создаем необходимые папки и файлы:

mkdir nextcloud
cd nextcloud
touch {docker-compose.yml,.env}
mkdir {nextcloud,config_redis,app,db-data}

Задаем значения переменным через nano .env (переменные изменяем на свои):

NEXTCLOUD_PG_PASSWORD=123
EXTERNAL_URL=<domen>.duckdns.org
EMAIL=<your_user>@mail.ru

Редактируем docker-compose через nano docker-compose.yml:

services:
  db:
    image: postgres:13
    container_name: nextcloud-postgres
    shm_size: '2gb'
    volumes:
      - ./db-data:/var/lib/postgresql/data
      - /etc/localtime:/etc/localtime:ro
    environment:
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD=${NEXTCLOUD_PG_PASSWORD}
    env_file: ".env"
    restart: unless-stopped
    networks:
      - default
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U nextcloud"]
      interval: 10s
      timeout: 5s
      retries: 5

  app:
    image: nextcloud:latest
    container_name: nextcloud-app
    depends_on:
      db:
        condition: service_healthy
    volumes:
      - ./nextcloud:/var/www/html
      - ./app/config:/var/www/html/config
      - ./app/custom_apps:/var/www/html/custom_apps
      - ./app/data:/var/www/html/data
      - ./app/themes:/var/www/html/themes
      - /etc/localtime:/etc/localtime
      - /mnt/documents:/mnt/documents
      - /mnt/media:/mnt/media
      - /mnt/private_media:/mnt/private_media
    ports:
      - 80:80
      - 443:443
    environment:
      - POSTGRES_HOST=db
      - POSTGRES_DB=nextcloud
      - POSTGRES_USER=nextcloud
      - POSTGRES_PASSWORD=${NEXTCLOUD_PG_PASSWORD}
      - VIRTUAL_HOST=${EXTERNAL_URL}
      - OVERWRITECLIURL=https://test.${EXTERNAL_URL}
      - OVERWRITEPROTOCOL=https
      - LETSENCRYPT_HOST=${EXTERNAL_URL}
      - LETSENCRYPT_EMAIL=${EMAIL}
      - NEXTCLOUD_HOSTNAME='My cloud'
      - NEXTCLOUD_TRUSTED_DOMAINS=https://test.${EXTERNAL_URL}
      - REDIS_HOST=redis
      - PHP_MEMORY_LIMIT=4G
      - PHP_MAX_EXECUTION_TIME=600
      - PHP_UPLOAD_LIMIT=10G
      - APACHE_DISABLE_REWRITE_IP=1
    restart: unless-stopped
    env_file: ".env"
    networks:
      - default
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:80/status.php"]
      interval: 30s
      timeout: 10s
      retries: 3

  redis:
    image: redis:alpine
    container_name: nextcloud-redis
    volumes:
      - ./config_redis:/data
    restart: unless-stopped
    networks:
      - default

networks:
  default:
    name: nextcloud-network
    driver: bridge
    attachable: true

Переходим по адресу http://<your_ip>/ Вводим свои учетные данные. Правим конфиг через sudo nano app/config/config.php:

  'trusted_domains' =>
  array (
    0 => '192.168.0.125',
    1 => 'domain3.domain2.duckdns.org'
  ),

domain указываем свой, так ка входить будем через прокси-сервер. Сразу заменяем/вставляем через sudo nano app/config/config.php:

  'preview_max_x' => 512,
  'preview_max_y' => 512,
  'preview_max_memory' => 128,
  'preview_max_filesize_image' => 10,
  'preview_concurrency_new_requests' => 0,
  'preview_keep_versions' => 3,

Данное действие нам необходимо, чтобы уменьшить объем места под preview. Дополнительно проверяем, что наш кэш работает:

docker exec -it nextcloud-redis /bin/sh
redis-cli
KEYS *

Вывод примерно такой должен быть:

1) "e28776fbaa397fc10461d72569392a5c/JS-940e3025074010d569c05ad210e74680core-merged-template-prepend.js.deps"
 2) "e28776fbaa397fc10461d72569392a5c/app_api/ex_translation_providers/ex_translation_providers"
 3) "e28776fbaa397fc10461d72569392a5c/imagePath-940e3025074010d569c05ad210e74680-user_status-app-dark.svg"
 4) "e28776fbaa397fc10461d72569392a5c/imagePath-940e3025074010d569c05ad210e74680-firstrunwizard-apps/whiteboard.svg"
 5) "e28776fbaa397fc10461d72569392a5c/notificationspush_fair_use"
 6) "e28776fbaa397fc10461d72569392a5c/circles/getSharedWithqASwqfKaTFN5NENAq1ApWCLhUpXtT12#0#247cbd904627c22b5c92499e1533f03e"
 7) "e28776fbaa397fc10461d72569392a5c/theming-https://test.volokzhanin.duckdns.orgshouldReplaceIcons"
...

Устанавливаем приложения:

# Календарь
docker exec -it nextcloud-app php occ app:install calendar

Предварительный настройки закончены.

Дополнительные оптимизации

Запускаем по cron в VM через crontab -e:

# Nextcloud: eжедневное выполнение cron-задач
0 0 * * * docker exec --user www-data nextcloud_app php /var/www/html/cron.php

# Nextcloud: еженедельный ремонт
0 1 * * * echo "y" | docker exec -i nextcloud-app php occ preview:repair -v

# Nextcloud: еждневная очистка preview
0 2 * * * docker exec nextcloud-app php occ preview:cleanup

# Postges: eжедневное создание отсутствующих индексов
0 2 * * * docker exec nextcloud-app  su -s /bin/sh www-data -c "php occ db:add-missing-indices"

# Nextcloud: фоновая генерация preview
*/5 * * * * docker exec nextcloud-app php occ preview:pre-generate

# Nextcloud: удаление логов размером более 5GB
*/5 * * * * docker exec nextcloud-app find /var/www/html -type f -name 'nextcloud.log*' -size +5G -exec rm -v {} \;

# Postgres: eжедневное VACUUM ANALYZE
0 3 * * * docker exec -it nextcloud-postgres psql -U postgres -d nextcloud -c "VACUUM ANALYZE;"

# Nextcloud: ежедневное сканирование файлов
0 4 * * * docker exec nextcloud-app php occ files:scan --unscanned --all

# Postgres: еженедельная переиндексация
0 5 * * 0 docker exec nextcloud-postgres reindexdb -U nextcloud nextcloud

Смартфон

Через F-Droid устанавливаем.

  1. Nextcloud - просмотр файлов + поиск. Через данное приложение можно синхронизировать файлы, но я выбрал другое решение и о нем напишу в следующих статьях. Для взаимодействия с файлами часто использую файловый менеджер с коннектором к Nextcloud. Также возможно взаимодействовать с файлами через WebDAV.

  2. DAVx⁵ - для синхронизации календаря и контактов.

ПК

Выбираем версию ПО для взаимодействия с файлами. Для Arch Linux : sudo pacman -R nextcloud-client. Через данное приложение можно синхронизировать файлы, но я выбрал другое решение как и писал выше.

Интеграция с умным домом

Использую интеграцию CalDAV, чтобы в общем dashboard видеть события в календаре.

Итог

У нас есть стартовая платформа, которая закрыла все наши потребности. Также у нас появилось множество возможностей для расширения функционала.

Ссылки:

  1. Зачем нужен собственный сервер в 2025?

  2. Как установить Proxmox?

  3. Как установить Docker?

  4. Как запустить прокси-сервер для сервисов?

  5. Как запустить сервис по управлению умным домом?