# Mouza vectorizer production deployment

The browser must continue to call the Laravel route. Laravel authenticates the
user and sends a private, authenticated request to this service. Never put the
service token in JavaScript or expose it in a Blade template.

## 1. Choose the server layout

The preferred layout is Docker on the same VPS as Laravel. In that case the
container is bound to `127.0.0.1:8091` and no subdomain is required.

If Laravel is on shared cPanel without Docker, deploy this container to a small
Linux VPS. Put an HTTPS reverse proxy in front of port 8091 and allow incoming
HTTPS only from the cPanel server's outbound IP. A subdomain such as
`vectorizer.example.com` is useful in this second layout, but browsers should
still never call it directly.

## 2. Create the shared token

Generate one token on a trusted machine:

```bash
openssl rand -hex 32
```

Use the same value in both places. Do not commit it.

Laravel production `.env`:

```dotenv
MOUZA_VECTORIZER_URL=http://127.0.0.1:8091
MOUZA_VECTORIZER_TIMEOUT=180
MOUZA_VECTORIZER_TOKEN=generated-token-here
```

Vectorizer server `services/mouza-vectorizer/.env`:

```dotenv
MOUZA_VECTORIZER_TOKEN=generated-token-here
MOUZA_MAX_UPLOAD_BYTES=31457280
```

After changing Laravel `.env`, rebuild its configuration cache:

```bash
php artisan config:clear
php artisan config:cache
```

## 3. Start the container

From the vectorizer directory:

```bash
docker compose up -d --build
docker compose ps
curl http://127.0.0.1:8091/health
```

The processing endpoint should reject missing credentials:

```bash
curl -i -X POST http://127.0.0.1:8091/v1/vectorize
```

An HTTP 401 response confirms that the endpoint is protected.

## 4. Separate-server reverse proxy

When the vectorizer is on another VPS, keep Docker bound to loopback and proxy
it through Nginx. Set `client_max_body_size` to at least 30 MB and the read
timeout above Laravel's 180-second service timeout. Example server block:

The ready-to-copy template is
[`deploy/nginx-vectorizer.conf.example`](deploy/nginx-vectorizer.conf.example).

```nginx
server {
    listen 443 ssl http2;
    server_name vectorizer.example.com;

    client_max_body_size 30m;

    location / {
        allow CPANEL_OUTBOUND_IP;
        deny all;

        proxy_pass http://127.0.0.1:8091;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 190s;
        proxy_send_timeout 190s;
    }
}
```

Install a valid TLS certificate, replace the placeholder IP, and set Laravel:

```dotenv
MOUZA_VECTORIZER_URL=https://vectorizer.example.com
```

Do not configure CORS; only Laravel communicates with this endpoint.

## 5. Enable GitHub deployment

The `Deploy Mouza vectorizer` workflow is opt-in. Create these GitHub Actions
secrets:

- `VECTORIZER_SSH_KEY`
- `VECTORIZER_KNOWN_HOSTS`
- `VECTORIZER_HOST`
- `VECTORIZER_USER`
- `VECTORIZER_PORT`
- `VECTORIZER_APP_PATH`

Create the target directory and its private `.env` before the first deployment.
Run the workflow manually once. When it succeeds, add the repository variable
`VECTORIZER_DEPLOY_ENABLED=true` to deploy service changes pushed to `main`.

## 6. Operational checks

- Keep at least 2 GB RAM available for large OpenCV/PDF operations.
- The container intentionally runs one Uvicorn worker to limit concurrent
  memory use.
- Monitor container restarts, response time, HTTP 5xx responses and disk space.
- Keep user review and map-scale calibration mandatory; vectorization topology
  does not prove cadastral or measurement accuracy.
