# Deploy

```bash
cp portal/.env.example portal/.env
cp platform/.env.example platform/.env
cp gateway/.env.example gateway/.env
bash scripts/bootstrap.sh
bash scripts/install-services.sh
```

```bash
bash scripts/build-final.sh
php scripts/check-mysql-mariadb-contract.php
```

## Layout final suportado

No ambiente de desenvolvimento, o front door compartilhado é o serviço `shared-web`, que publica o **portal real** na raiz e o NVR em `/nvr` por meio do bridge público do portal.

- `PORTAL_PUBLIC_ROOT=/var/www/portal-principal/public`
- `NVR_LOCATION_PREFIX=/nvr`
- `INSTALL_ROOT=/var/www/portal-principal/public/nvr`

Os três parâmetros acima podem ser alterados antes da execução do instalador para acomodar caminhos como `/sistema/nvr` sem edição manual espalhada pelos arquivos de deploy.

## Serviços previstos

### Portal + NVR

- `shared-web`
- `php`
- `platform-queue.service`
- `platform-scheduler.service`
- `platform-scheduler.timer`
- `platform-queue.conf`
- `platform-scheduler.conf`
- `nvr-platform.target`
- `nvr-log-rotate.service`
- `nvr-log-rotate.timer`

### Gateway

- `gateway-bootstrap.service`
- `gateway-daemon.service`
- `gateway-local-web.service`
- `gateway-worker.service` (compatibilidade)
- `gateway-hdmi-kiosk.service`
- `gateway-daemon.conf`
- `gateway-local-web.conf`
- `gateway-worker.conf`
- `nvr-gateway.target`

### Grupo completo

- `nvr-stack.target`

## Proxy web compartilhado com o portal

- Nginx compartilhado do bundle: `deploy/docker/nginx/shared-portal.conf`
- Nginx dedicado do portal real: `deploy/docker/portal/default.conf`
- Nginx de produção do subpath: `deploy/nginx/platform-subpath.conf`
- Apache de produção: `platform/deploy/apache-alias.conf` ou `platform/deploy/apache-vhost.conf`
- Nginx dedicado do NVR: `deploy/nginx/platform.conf`

O instalador passa a renderizar os templates com os valores reais de `PORTAL_PUBLIC_ROOT`, `NVR_LOCATION_PREFIX` e `INSTALL_ROOT`.

## Scheduler, worker e processos persistentes

- HTTP do `platform`: `scripts/run-platform.sh` → `platform/scripts/boot-http.sh`
- fila do `platform`: `scripts/run-platform-queue.sh` → `platform/scripts/boot-queue.sh`
- scheduler do `platform`: `scripts/run-platform-scheduler.sh` → `platform/scripts/boot-scheduler.sh`
- daemon do gateway: `scripts/run-gateway.sh`
- web local do gateway: `scripts/run-gateway-web.sh`

Esses wrappers alinham Docker Compose, systemd e supervisor no mesmo contrato operacional.

## Logs, retenção e higiene 24x7

- logs de aplicação de `portal`, `platform` e `gateway` rodam com política própria em `scripts/rotate-logs.sh`;
- a rotação diária é instalada por `nvr-log-rotate.service` + `nvr-log-rotate.timer`, com fallback em `deploy/scheduler/nvr-log-rotate.cron`;
- stdout/stderr das unidades sob **supervisor** ficam limitados no próprio `*.conf` com `*_logfile_maxbytes` e `*_logfile_backups`;
- stdout/stderr das unidades sob **systemd** ficam em **journald**, com retenção/capacidade controladas por `deploy/systemd/journald-nvr-stack.conf`;
- a checagem operacional oficial desta política é `php scripts/check-log-rotation-policy.php`.

## Banco central oficial

- stack final padronizada em **MariaDB/MySQL**;
- contrato oficial do runtime: `DB_CONNECTION=mysql`, `DB_PORT=3306`, `DB_CHARSET=utf8mb4`, `DB_COLLATION=utf8mb4_unicode_ci` e `DB_SESSION_TIMEZONE=+00:00`;
- compatibilidade transitória com o portal principal: o runtime também lê `DB_CENTRAL_*` quando o ambiente compartilhado ainda usa a nomenclatura legada;
- `pdo_mysql`, cliente `mysql` e `mysqldump` compõem o baseline oficial de operação e recuperação.

## Contrato canônico da integração central

- chaves canônicas do portal/SSO central no NVR: `CENTRAL_APP_URL`, `CENTRAL_API_URL`, `CENTRAL_SHARED_SECRET`, `CENTRAL_PRODUCT_CODE`, `CENTRAL_TIMEOUT`, `CENTRAL_SSO_ENABLED`, `CENTRAL_INTROSPECTION_ENABLED`, `CENTRAL_SSO_ISSUER`, `CENTRAL_SSO_AUDIENCE`, `CENTRAL_SSO_TTL_SECONDS`, `CENTRAL_SSO_CLOCK_SKEW_SECONDS`, `CENTRAL_SSO_AUTO_PROVISION_TENANT`, `CENTRAL_SSO_AUTO_PROVISION_SITE`, `CENTRAL_SSO_SYNC_PLATFORM_ADMIN`;
- `CENTRAL_APP_URL` é a raiz oficial do portal/central; `CENTRAL_API_URL` é a base canônica da API e, quando omitida, pode ser derivada como `CENTRAL_APP_URL + /api`;
- aliases `SSO_CENTRAL_*` permanecem apenas como compatibilidade transitória e sempre perdem precedência para `CENTRAL_*` / `CENTRAL_SSO_*`;
- o contrato canônico do banco central permanece em `DB_*`; aliases `DB_CENTRAL_*` continuam apenas como compatibilidade transitória documentada.

## Assinatura de mídia entre /platform e /gateway

- configure o mesmo `NVR_MEDIA_SHARED_SECRET` em `platform/.env` e `gateway/.env`;
- mantenha `NVR_MEDIA_SIGNING_ALGORITHM=sha256` nas duas pontas;
- mantenha os mesmos valores de `NVR_MEDIA_URL_TTL_SECONDS`, `NVR_MEDIA_CLOCK_TOLERANCE_SECONDS` e `NVR_MEDIA_SIGNATURE_PAYLOAD_VERSION`;
- `php platform/scripts/deploy-preflight.php --runtime=install` valida divergência real entre `platform` e `gateway/.env` antes do deploy.

## Imagem PHP compartilhada e bootstrap oficial

- a imagem `deploy/docker/php/Dockerfile` agora materializa `pdo_mysql`, `pdo_sqlite`, `sqlite3`, `redis`, `mbstring`, `pcntl`, `opcache`, cliente `mysql` e `composer`;
- o serviço `php` do compose sobe pelo wrapper `scripts/run-shared-php.sh`, que materializa o vendor Laravel do `platform` antes de expor o front door do portal;
- `platform/scripts/boot-http.sh`, `boot-queue.sh`, `boot-scheduler.sh` e `migrate.sh` também fecham esse mesmo bootstrap, evitando drift entre HTTP, fila, scheduler e manutenção.
