# Установка сервера P2

Версия сборки: 2026.4.0.29.

Сервер открывает презентации из папки в браузере. Человек входит по имени и общему паролю, видит список файлов,
правит вместе с другими (правка каждого сразу видна остальным) и сохраняет обратно в ту же папку. Внутри — то же
ядро на Rust, что и в настольном приложении.

## Что нужно

- Машина с Linux и Докером (x86_64).
- Папка с презентациями `.pptx`, в которую сервер может писать.
- Для доступа по сети — обратный прокси с HTTPS (nginx, Caddy). Сам сервер говорит обычным HTTP.

## Установка

```bash
gunzip -c P2-2026.4.0.29-server-docker.tar.gz | docker load
mkdir -p /srv/p2 && chown 1000:1000 /srv/p2   # сервер работает пользователем node (uid 1000)
cp *.pptx /srv/p2/
docker run -d --name p2 --restart unless-stopped \
  -p 8090:8090 -v /srv/p2:/data \
  p2-server:2026.4.0.29 --entry "<общий пароль>"
```

Откройте `http://<сервер>:8090/` — появится страница входа: имя и пароль. После входа видны презентации из папки.

Без `--entry` вход спрашивает только имя. Так можно в закрытой сети или на своей машине, но никогда в интернете.

## Проверка

```bash
curl -s http://127.0.0.1:8090/health
```

В ответе JSON с `"status":"ok"`. Докер делает эту проверку каждые 30 секунд (`docker ps` показывает `healthy`).

## Режим «хозяин»: файлы из вашей системы

С `--auth-url` / `--attach-url` сервер берёт презентации у вашей системы, а не из папки. Точка входа образа
включает режим папки (`--folder /data`), и вместе с адресами хозяина сервер откажется стартовать с ошибкой
«--folder и адреса внешнего хозяина вместе нельзя». Поэтому точку входа задают явно:

```bash
docker run -d --name p2 --restart unless-stopped -p 127.0.0.1:8093:8090 \
  --entrypoint node p2-server:2026.4.0.29 /app/slides-server.mjs \
  --host 0.0.0.0 --port 8090 --dist /app/dist --base-path /p2 \
  --auth-url https://ваша-система/v1/me \
  --attach-url 'https://ваша-система/v1/attachments/{id}/content' \
  --replace-url 'https://ваша-система/v1/attachments/{id}/replace'
```

## Под подпутём (`--base-path`)

Если сервер живёт не в корне домена (например, рядом с A4 и F1 на `/p2/`), здоровье отвечает по адресу
`/<подпуть>/health`, а встроенная проверка Докера спрашивает `/health` в корне и показывает `unhealthy`, хотя
сервер работает. Задайте проверку явно — так сделано в `docker-compose.yml` этого комплекта:

```bash
docker run ... --health-cmd 'node -e "fetch(process.argv[1]).then(r=>process.exit(r.ok?0:1),()=>process.exit(1))" http://127.0.0.1:8090/p2/health' \
  p2-server:2026.4.0.29 --base-path /p2 ...
```

## Режим WOPI

Чтобы использовать P2 как редактор презентаций у WOPI-хозяина, запустите тот же образ с отдельной точкой входа и
сохраните закрытый ключ подписи на постоянном томе. `--wopi` нельзя совмещать с `--folder`, `--entry` и адресами
режима «хозяин»:

```bash
mkdir -p /srv/p2 && chown 1000:1000 /srv/p2
docker run -d --name p2-wopi --restart unless-stopped \
  -p 8090:8090 -v /srv/p2:/data --entrypoint node p2-server:<версия> \
  /app/slides-server.mjs --wopi --host 0.0.0.0 --port 8090 --dist /app/dist \
  --public-url https://p2.example --proof-key-file /data/wopi-proof-key.pem
curl -fsS http://127.0.0.1:8090/hosting/discovery
```

P2 публикует открытый proof-key в discovery и подписывает им каждый запрос к хозяину. Файл
`wopi-proof-key.pem` создаётся с правами `0600`; не удаляйте его при обновлении, пока хозяин кэширует discovery.

## Доводы

| довод | что делает |
|---|---|
| `--entry <пароль>` | общий пароль для входа |
| `--max-cabins <число>` | сколько документов открыто одновременно (по умолчанию — по памяти машины) |
| `--idle-min <минуты>` | через сколько минут без работы документ закрывается (по умолчанию 30) |
| `--base-path <подпуть>` | подпуть за обратным прокси, например `/p2` |
| `--auth-url`, `--attach-url`, `--replace-url` | режим «хозяин»: файлы и пользователи берутся из вашей системы, как у A4 и F1 |
| `--wopi` | использовать WOPI-хозяина вместо папки `/data` |
| `--public-url <адрес>` | публичный адрес P2 в discovery (только WOPI) |
| `--proof-key-file <путь>` | постоянный закрытый ключ подписи запросов (только WOPI) |

Доводы передаются ТОЛЬКО через пробел: `--entry пароль`, а не `--entry=пароль`. Форму с `=` сервер отбрасывает
молча, и тогда он встаёт без пароля.

## Обратный прокси (nginx)

Совместная правка идёт через WebSocket, поэтому прокси обязан его пропускать:

```nginx
location / {
  proxy_pass http://127.0.0.1:8090;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
  proxy_set_header Host $host;
  client_max_body_size 100m;
}
```

## Что полезно знать

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

Свежие сборки и документация: https://tech.plantype.ru/
