Свой сервер

Layers на вашем сервере

Одно приложение и несколько сервисов в одном docker-compose.yml. Ставится и в закрытом контуре, данные не покидают вашу инфраструктуру.

Образ hissih/layers на Docker Hub — больше 20 000 загрузок. Пробный период — 90 дней, дальше нужна лицензия.

God Mode → Начало работы: чек-лист сервера, сделано 4 из 6 — домены, почта, модули, ИИ

Установка с ИИ

Поставьте вместе с ИИ‑ассистентом

Скопируйте промпт в ChatGPT, Claude или любой другой ассистент. Он прочитает полную инструкцию и проведёт по шагам: домен, почта, звонки, редакторы, модель ИИ.

Инструкция для ИИ и людей: layers.md/self-hosted/llms.ru.txt

Промпт
Помоги установить Layers на мой сервер. Инструкция: https://layers.md/self-hosted/llms.ru.txt (полная — https://layers.md/self-hosted/llms-full.ru.txt). Веди меня по шагам и сначала спроси про домен, почту и модель ИИ.

Из чего состоит

Одно приложение и сервисы рядом

Всё ставится одним docker-compose.yml. Обязательны только Layers и PostgreSQL — остальное включаете под свои задачи.

Обязательно

Layers

8080

Всё пространство, API и панель администратора God Mode — одно Java‑приложение на одном порту.

Обязательно

PostgreSQL

5432

База данных. В комплекте compose или ваш внешний сервер.

Рекомендуем

Поиск: Manticore

9308

Поиск по задачам, страницам, чатам и файлам. Manticore — отдельный лёгкий контейнер, уже в compose. Есть свой кластер Elasticsearch — Layers работает и с ним.

Без отдельного сервиса — встроенный Lucene, индекс в каталоге файлов.

Для звонков

LiveKit

7880 · 7881 · UDP 50000–50100

Звонки и демонстрация экрана. Для записи — сервис LiveKit Egress, он ставится отдельно.

Без него нет звонков, чаты работают.

Для писем

SMTP

587 / 465

Ваш почтовый сервер: приглашения, подтверждение регистрации, сброс пароля.

Без него письма не уходят.

Для документов

SumDoc

8090 · /sumdoc

Правка .docx прямо в браузере.

Без него документ открывается карточкой «Скачать».

Для таблиц

SumSheet

8092 · /sumsheet

Правка .xlsx и .xlsm прямо в браузере.

Без него таблица открывается карточкой «Скачать».

По желанию

MCP‑сервер

8091 · /mcp

Помощник и внешние агенты (Claude, Cursor) работают с задачами и страницами.

Без него помощник только отвечает, но не действует.

По желанию

Модель ИИ

OpenAI‑совместимый /v1

Своя модель: Ollama или любой OpenAI‑совместимый сервер — или облачный провайдер по ключу.

Без неё нет ИИ‑функций.

Linux x86-64 и Docker

Образы собраны под linux/amd64. Docker и Docker Compose.

Layers: от 2 ГБ памяти

Минимум для приложения, плюс PostgreSQL.

Редакторы: 2 ГБ + ~250 МБ

на каждый открытый документ. Документ — свой процесс.

Файл до 900 МБ

по умолчанию. Предел меняется переменной.

Установка

От пустого сервера до первого входа

Тринадцать шагов, каждый — с готовым кодом. Пароли и ключи в примерах — заглушки change-me: замените своими.

  1. 1

    Подготовьте сервер

    Linux x86-64 с Docker и Docker Compose. Домен, который смотрит на сервер, например example.com. Без домена можно работать по http://IP:8080 внутри сети.

    Для каждой заглушки change-me сгенерируйте свой пароль.

    Терминал
    docker --version
    docker compose version
    mkdir -p /opt/layers && cd /opt/layers
    openssl rand -hex 24
  2. 2

    Создайте docker-compose.yml

    Один файл на всю установку. Замените example.com на свой домен и все change-me-… на свои значения. Ненужные сервисы — звонки, редакторы, MCP — удалите вместе с их переменными.

    Том Layers — именно /root/layers_data: там файлы, настройки God Mode и секреты. Пароль базы задаётся дважды и должен совпадать; ключ LiveKit — тоже.

    Образы Layers и редакторов — на Docker Hub: hissih/layers.

    docker-compose.yml
    name: layers
    
    services:
      db:
        image: postgres:16-alpine
        restart: unless-stopped
        environment:
          POSTGRES_DB: layers
          POSTGRES_USER: layers
          POSTGRES_PASSWORD: change-me-db
        volumes:
          - pg_data:/var/lib/postgresql/data
        healthcheck:
          test: ["CMD-SHELL", "pg_isready -U layers -d layers"]
          interval: 5s
          retries: 20
    
      manticore:
        image: manticoresearch/manticore:latest
        restart: unless-stopped
        volumes:
          - manticore_data:/var/lib/manticore
    
      layers:
        image: hissih/layers:latest
        platform: linux/amd64
        restart: unless-stopped
        depends_on:
          db: { condition: service_healthy }
          manticore: { condition: service_started }
        ports:
          - "127.0.0.1:8080:8080"
        volumes:
          - layers_data:/root/layers_data
        environment:
          SPRING_PROFILES_ACTIVE: server
          # База
          DB_SERVER_URL: jdbc:postgresql://db:5432/layers
          DB_SERVER_USERNAME: layers
          DB_SERVER_PASSWORD: change-me-db
          # Панель администратора /godmode
          ADMIN_USERNAME: admin
          ADMIN_PASSWORD: change-me-admin
          # Домен
          LAYERS_DOMAIN: example.com
          LAYERS_APP_DOMAIN: example.com
          APP_REDIRECT_URL: https://example.com
          APP_CORS_ALLOWED_ORIGINS: https://example.com
          # Поиск
          SEARCH_PROVIDER: manticore
          SEARCH_MANTICORE_ENABLED: "true"
          SEARCH_MANTICORE_URL: http://manticore:9308
          SEARCH_ELASTICSEARCH_ENABLED: "false"
          # Звонки
          LIVEKIT_ENABLED: "true"
          LIVEKIT_URL: ws://livekit:7880
          LIVEKIT_PUBLIC_URL: wss://example.com/livekit/
          LIVEKIT_API_KEY: change-me-livekit-key
          LIVEKIT_API_SECRET: change-me-livekit-secret-min-32-characters
          # Почта (отправка писем)
          MAIL_PROVIDER: smtp
          SPRING_MAIL_HOST: smtp.example.com
          SPRING_MAIL_PORT: "587"
          SPRING_MAIL_USERNAME: noreply@example.com
          SPRING_MAIL_PASSWORD: change-me-smtp
          SPRING_MAIL_SMTP_AUTH: "true"
          SPRING_MAIL_SMTP_STARTTLS_ENABLE: "true"
          # Редакторы SumDoc и SumSheet (адреса, которые видит браузер)
          LAYERS_FASTDOC_URL: https://example.com/sumdoc
          LAYERS_FASTSHEET_URL: https://example.com/sumsheet
          # ИИ: модель подключается в God Mode → ИИ
          AI_ENABLED: "true"
          ASSISTANT_MCP_URL: http://mcp:8091/mcp
          AI_USER_MODEL_CHOICE: "true"
    
      livekit:
        image: livekit/livekit-server:latest
        restart: unless-stopped
        environment:
          LIVEKIT_CONFIG: |
            port: 7880
            bind_addresses: [""]
            rtc:
              tcp_port: 7881
              port_range_start: 50000
              port_range_end: 50100
              use_external_ip: true
            keys:
              change-me-livekit-key: change-me-livekit-secret-min-32-characters
            webhook:
              api_key: change-me-livekit-key
              urls:
                - http://layers:8080/v1/livekit/webhook
        ports:
          - "7880:7880"
          - "7881:7881"
          - "7882:7882/udp"
          - "50000-50100:50000-50100/udp"
    
      sumdoc:
        image: hissih/sumdoc-webhost:latest
        platform: linux/amd64
        restart: unless-stopped
        command: ["--base-path", "/sumdoc", "--max-cabins", "12", "--idle-min", "20",
                  "--auth-url", "http://layers:8080/v1/me",
                  "--attach-url", "http://layers:8080/v1/attachments/{id}/content"]
        ports:
          - "127.0.0.1:8090:8090"
        volumes:
          - sumdoc_cabins:/data/cabins
    
      sumsheet:
        image: hissih/sumsheet-webhost:latest
        platform: linux/amd64
        restart: unless-stopped
        command: ["--base-path", "/sumsheet", "--max-cabins", "12", "--idle-min", "20",
                  "--auth-url", "http://layers:8080/v1/me",
                  "--attach-url", "http://layers:8080/v1/attachments/{id}/content"]
        ports:
          - "127.0.0.1:8092:8092"
        volumes:
          - sumsheet_cabins:/data/cabins
    
      mcp:
        image: layers-mcp-server:from-distribution   # образ MCP-сервера из дистрибутива
        restart: unless-stopped
        depends_on: [layers]
        environment:
          SPRING_PROFILES_ACTIVE: server
          SERVER_PORT: "8091"
          LAYERS_BACKEND_BASEURL: http://layers:8080
          LAYERS_BACKEND_FORWARDINCOMINGAUTH: "true"
          LAYERS_BACKEND_REQUIREINCOMINGAUTH: "true"
        ports:
          - "127.0.0.1:8091:8091"
    
    volumes:
      pg_data:
      manticore_data:
      layers_data:
      sumdoc_cabins:
      sumsheet_cabins:
  3. 3

    Выберите движок поиска

    В Layers три движка поиска, выбор — переменной SEARCH_PROVIDER (auto, manticore, elasticsearch, lucene).

    Manticore — рекомендуем: отдельный лёгкий контейнер, он уже в compose. Elasticsearch — если в компании уже есть кластер: удалите сервис manticore и задайте переменные справа. Lucene — встроенный, без отдельного сервиса: индекс лежит в каталоге файлов Layers (том layers_data); подходит для небольшой установки.

    После смены движка — переиндексация: God Mode → Платформа → Поиск.

    Elasticsearch — вместо переменных Manticore у layers
          SEARCH_PROVIDER: elasticsearch
          SEARCH_ELASTICSEARCH_ENABLED: "true"
          SEARCH_MANTICORE_ENABLED: "false"
          ES_HOST: elasticsearch.example.com
          ES_PORT: "9200"
          ES_PROTOCOL: https
          ES_USERNAME: layers
          ES_PASSWORD: change-me-es
    Lucene — встроенный, без сервиса manticore
          SEARCH_PROVIDER: lucene
          SEARCH_MANTICORE_ENABLED: "false"
          SEARCH_ELASTICSEARCH_ENABLED: "false"
  4. 4

    Запустите

    Первый старт — 15–60 секунд. Когда в логе появится Started LayersApplication, откройте домен и создайте первый аккаунт.

    Терминал
    docker compose up -d
    docker compose logs -f layers
    curl -s http://127.0.0.1:8080/health
    # OK
  5. 5

    Включите HTTPS через nginx

    Layers отдаёт всё сам с порта 8080 — nginx только завершает TLS и проксирует звонки, редакторы и MCP. Редакторы живут на том же домене: так они получают cookie входа.

    Без limit_req и без раздачи статики из nginx — защита от перебора и кэш уже встроены.

    Терминал
    sudo apt install nginx certbot python3-certbot-nginx
    sudo certbot certonly --nginx -d example.com
    /etc/nginx/sites-available/layers.conf
    server {
        listen 80;
        server_name example.com;
        location /.well-known/acme-challenge/ { root /var/www/certbot; }
        location / { return 301 https://example.com$request_uri; }
    }
    
    server {
        listen 443 ssl http2;
        server_name example.com;
    
        ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    
        client_max_body_size 1000m;
        add_header X-Content-Type-Options nosniff always;
        add_header X-Frame-Options SAMEORIGIN always;
    
        # Layers: веб, API, God Mode
        location / {
            proxy_pass http://127.0.0.1:8080;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto https;
            proxy_read_timeout 300;
        }
    
        # LiveKit: сигналинг (слеш в конце proxy_pass обязателен)
        location /livekit/ {
            proxy_pass http://127.0.0.1:7880/;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_read_timeout 86400s;
        }
        # LiveKit REST: SDK сервера ходит в /twirp/ от корня
        location /twirp/ {
            proxy_pass http://127.0.0.1:7880/twirp/;
            proxy_set_header Host $host;
            proxy_read_timeout 86400s;
        }
    
        # Редакторы — на том же домене, чтобы получить cookie входа Layers
        location /sumdoc {
            proxy_pass http://127.0.0.1:8090;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_read_timeout 3600s;
        }
        location /sumsheet {
            proxy_pass http://127.0.0.1:8092;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_read_timeout 3600s;
        }
    
        # MCP для внешних агентов (необязательно)
        location /mcp {
            proxy_pass http://127.0.0.1:8091/mcp;
            proxy_http_version 1.1;
            proxy_set_header Host $host;
            proxy_buffering off;
            proxy_read_timeout 3600s;
        }
    }
    Терминал
    sudo ln -s /etc/nginx/sites-available/layers.conf /etc/nginx/sites-enabled/
    sudo rm -f /etc/nginx/sites-enabled/default
    sudo nginx -t && sudo systemctl reload nginx
  6. 6

    Откройте порты для звонков

    LiveKit передаёт звук и видео по UDP. В God Mode → Приложения → Интеграции → LiveKit укажите wss://example.com/livekit/ (слеш в конце обязателен), проверьте подключение и включите.

    Если в логе could not validate external IP, замените use_external_ip: true на node_ip: <IP сервера>. В закрытой сети — тоже node_ip.

    Терминал
    sudo ufw allow 7881/tcp
    sudo ufw allow 7882/udp
    sudo ufw allow 50000:50100/udp
  7. 7

    Настройте почту

    Письма от Layers — приглашения, подтверждение, сброс пароля — уходят через ваш SMTP из compose. То же есть в God Mode → Платформа → Почта, с тестовым письмом и шаблонами.

    Модуль «Почта» — клиент внутри Layers: люди подключают свои существующие ящики по IMAP и SMTP. Свой почтовый сервер Layers не поднимает.

    Порт 465 вместо 587
    SPRING_MAIL_PORT: "465"
    SPRING_MAIL_SMTP_STARTTLS_ENABLE: "false"
    SPRING_MAIL_PROPERTIES_MAIL_SMTP_SSL_ENABLE: "true"
  8. 8

    Проверьте редакторы SumDoc и SumSheet

    Редактор не хранит ни людей, ни файлы: он спрашивает Layers «кто это» (/v1/me) и берёт файл по id (/v1/attachments). skewMin: 0 — редактор и движок из одного релиза.

    Один открытый документ — около 250 МБ памяти; сколько документов одновременно, задаёт --max-cabins.

    Терминал
    curl -s http://127.0.0.1:8090/sumdoc/health     # "status": "ok", "skewMin": 0
    curl -s http://127.0.0.1:8092/sumsheet/health   # "status": "ok", "skewMin": 0
    curl -s https://example.com/v1/capabilities
    # {"fastdoc":{"enabled":true,"url":"https://example.com/sumdoc"},
    #  "fastsheet":{"enabled":true,"url":"https://example.com/sumsheet"}, …}
  9. 9

    Подключите модель ИИ

    God Mode → ИИ → Провайдеры → Добавить провайдера. Готовые типы — OpenAI, OpenRouter, Gonka; «Своё подключение» — любой сервер с OpenAI‑совместимым API, например Ollama, ключ не обязателен. «Проверить» покажет модели сервера — выберите нужные и включите.

    На стенде так подключена локальная Ollama с gpt-oss:20b. Адрес должен быть доступен из контейнера Layers: имя сервиса или IP, не localhost.

    docker-compose.yml — добавить в services
      ollama:
        image: ollama/ollama:latest
        restart: unless-stopped
        volumes:
          - ollama_data:/root/.ollama
    # и в volumes:
    #   ollama_data:
    Терминал
    docker compose up -d ollama
    docker compose exec ollama ollama pull gpt-oss:20b
    # адрес в «Своём подключении»: http://ollama:11434/v1
    # OpenAI‑совместимый сервер на другой машине: http://<адрес>:8000/v1
  10. 10

    Подключите агентов через MCP

    MCP‑сервер уже в compose: через него помощник Layers выполняет действия — создаёт задачи, пишет страницы. Внешние агенты (Claude, Cursor и другие) подключаются к https://example.com/mcp с личным токеном: в Layers → Настройки → Токены доступа, права «Только чтение» или «Чтение и запись».

    Терминал
    curl -s http://127.0.0.1:8091/actuator/health
    # {"status":"UP", …}
  11. 11

    Войдите в God Mode

    https://example.com/godmode/login, логин admin и ваш ADMIN_PASSWORD. «Начало работы» — чек‑лист сервера: домены, почта, вход, модули, брендинг. Отметка «сделано» ставится по фактическому состоянию сервера.

    God Mode → Начало работы: шаги настройки — домены, почта, вход, модули, брендинг, ИИ
  12. 12

    Введите ключ лицензии

    Пробный период — 90 дней, дальше нужна лицензия. Ключ — одна строка: God Mode → Система → Лицензия → «Применить ключ». Проверяется на самом сервере.

    Терминал
    curl -s https://example.com/layers/license/status
    # {"mode":"MISSING", …, "node":{"regime":"evaluation","evaluationDaysLeft":89, …}}
    # с ключом: "regime":"full"
  13. 13

    Обновляйте и делайте резервные копии

    Обновление — новый образ; база, файлы и настройки остаются в томах. Для предсказуемости закрепите тег вместо latest — запущенный тег виден в God Mode → Эксплуатация → Состояние системы.

    Встроенного бэкапа базы в панели нет: база — pg_dump, файлы и настройки — архив тома layers_data.

    Обновление
    cd /opt/layers
    docker compose pull
    docker compose up -d
    Резервная копия
    cd /opt/layers
    docker compose exec -T db sh -c 'pg_dump -U $POSTGRES_USER $POSTGRES_DB' | gzip > layers-db-$(date +%F).sql.gz
    docker run --rm -v layers_layers_data:/data -v "$PWD":/backup alpine \
      tar czf /backup/layers-data-$(date +%F).tar.gz -C /data .

Закрытый контур

Установка в закрытом контуре — образы архивом

Скачайте образы на машине с интернетом и перенесите одним файлом. Лицензия проверяется на самом сервере; каталог модулей обращается к реестру, а ИИ в закрытой сети — только с локальной моделью.

Терминал
docker pull hissih/layers:latest
docker save hissih/layers:latest postgres:16-alpine manticoresearch/manticore:latest \
  livekit/livekit-server:latest hissih/sumdoc-webhost:latest hissih/sumsheet-webhost:latest \
  | gzip > layers-images.tar.gz
# на сервере в закрытой сети
gunzip -c layers-images.tar.gz | docker load
docker compose up -d

Проверено на стенде

Так это работает у нас

Все кадры и ролики сайта сняты с локального стенда, где подняты ровно эти сервисы. Порты сдвинуты в 18xxx, чтобы не мешать соседям; Mailpit и GreenMail — только для проверки почты.

СервисОбразПорт на стендеНа вашем сервере
Layershissih/layers 2.1.184 (тот же jar)180808080 за nginx
PostgreSQLpostgres:16-alpine18432db:5432, внутри
Manticoremanticoresearch/manticore18308manticore:9308, внутри
LiveKitlivekit/livekit-server18880 · 18881 · UDP 18900–189507880 · 7881 · UDP 50000–50100
Mailpit (ловушка писем)axllent/mailpitSMTP 18125ваш SMTP‑сервер
GreenMail (тестовые ящики)greenmail/standalone:2.1.3IMAP 18143 · SMTP 18325существующие ящики людей
SumDocsumdoc-webhost18290 · /sumdoc8090 · /sumdoc
SumSheetsumsheet-webhost18292 · /sumsheet8092 · /sumsheet
MCP‑сервериз дистрибутива18091 · /mcp8091 · /mcp
Модель ИИOllama, gpt-oss:20b11434 · /v1ваша модель или провайдер

Проверено 2 октября 2026: /health → OK, лицензия — пробный период (осталось 89 дней), редакторы — status ok, MCP — UP.

Почему так

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

Закрытый контур

Установка в закрытом контуре: образы и обновления — архивом.

Лицензия — на сервере

Ключ проверяется на самом сервере.

Людей не блокирует

Сервер не закрывает вход сверх размера лицензии. Место — сколько выдержит железо; квоты на пространство задаёте сами.

Свой бренд

Название, логотип, цвет, язык по умолчанию и свои юридические документы.

Свой ИИ

OpenAI, OpenRouter, любой OpenAI‑совместимый сервер или локальные модели.

Редакторы рядом

SumDoc и SumSheet ставятся рядом с Layers, тоже в закрытом контуре.

Лицензия

Цена — по запросу

Пробный период

90 дней

90 дней на полной скорости. Без ключа сервер работает и дальше: люди и данные не ограничены, только расшифровка встреч идёт с задержкой.

Лицензия

По запросу

Обсудим размер команды, поддержку и условия лицензии.

Обсудить установку

Сервер не блокирует людей сверх лицензии. Установка, внедрение, обновления, доработки и поддержка — отдельно, по договорённости, платно.

Частые вопросы

Нужен ли интернет?

Нет — ни для установки из архива, ни для работы, ни для проверки лицензии. ИИ в закрытой сети — с локальной моделью.

Сколько нужно железа?

Layers — от 2 ГБ памяти плюс PostgreSQL. Редакторы — 2 ГБ и около 250 МБ на каждый открытый документ. Образы — linux/amd64.

Как обновляться?

docker compose pull и docker compose up -d. Данные и настройки остаются в томах.

Как делать резервные копии?

Базу — pg_dump, файлы и настройки — архивом тома layers_data. Встроенного бэкапа базы в панели нет.

Звонок соединяется, но нет звука и видео

На файрволе закрыты UDP 50000–50100 или 7882, либо LiveKit не определил внешний IP — задайте node_ip.

Что будет без ключа после 90 дней?

Сервер продолжит работать: вход, люди и данные не ограничены, ничего не закрывается. Медленнее становится только расшифровка встреч — она идёт в низком приоритете, с задержкой в несколько секунд. С ключом всё снова на полной скорости.

Есть ли вход через корпоративный каталог?

Пока нет: SAML, LDAP и SCIM не поддерживаются. Доступны вход по логину и паролю, а также Google, Яндекс, VK и Госуслуги.

Соберите работу команды в Layers

Начните бесплатно в облаке — до 20 человек без срока — или разверните Layers на своём сервере.