> For the complete documentation index, see [llms.txt](https://docs.facephi.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.facephi.com/docs.facephi-en/sdks/backend-sdk/voice/installation/installation_instructions.md).

# Service installation and deployment

## 1. Installation and deployment

The service is containerized, and there is a Docker image in a Facephi repository.

```bash
docker login facephicorp.jfrog.io
user: username
pass: token
```

```bash
docker pull facephicorp.jfrog.io/docker-pro-fphi/facephi-voice-service:#VERSION#
```

Where `#VERSION#` is the specific version number you want to download (e.g. `3.0.0`).

## 2. docker-compose

One way to deploy the service is to create a file `docker-compose.yml` with the following content:

```yaml
version: '3.7'

services:
  voice-service:
    ports:
      - "6982:6982"
    volumes:
      - ~/facephi_voice_config:/service/config
      - ~/facephi_voice_config:/service/logs
    image: facephicorp.jfrog.io/docker-pro-fphi/facephi-voice-service:$VERSION
    container_name: facephi-voice-service
    environment:
      # Optional JWT protection
      # - FACEPHI_VOICE_REST_AUTH_ENABLED=true
      # - FACEPHI_VOICE_REST_AUTH_JWT_SECRET=shared-secret
      # - FACEPHI_VOICE_REST_AUTH_ACCEPT_AUTHORIZATION_HEADER=true
      # - FACEPHI_VOICE_REST_AUTH_ACCEPT_API_KEY_HEADER=true
      # - FACEPHI_VOICE_REST_AUTH_API_KEY_HEADER_NAME=x-api-key
```

Note the volumes that are mounted in the container. These volumes are used to store the service configuration and license files, and to write the logger output.

Run the following command, inside the folder where the docker-compose.yml file is located, to deploy the service:

```bash
    docker-compose up
```

## 3. Configuration

### 3.1 License and resources configuration

To use this service, you need to have a valid configuration file.

The configuration file could contain the following information:

```bash
CONFIG_DIR=             # Path to the configuration folder where the resources are located
LICENSE_TYPE=           # License type, can be MACHINE, SHARED or LOCAL
LICENSE_BEHAVIOUR=      # License behavior, can be ONLINE or OFFLINE
LICENSE_KEY=            # License key
LICENSE_ID=             # Product ID
LICENSE_DATA=           # Product data
LICENSE_URL=            # License server URL. Only necessary if LICENSE_TYPE is LOCAL
LICENSE_PATH_OFFLINE=   # Path to a local file with the data for offline activation. Only necessary if LICENSE_TYPE is MACHINE and LICENSE_BEHAVIOUR is OFFLINE
```

The configuration and license file can be passed as a parameter to the service. By default, the service will look for a file called `/service/config/config.cfg`. In the case of the Docker container, the configuration file could be located in a volume mounted at `/service/config`.

### 3.2 Service configuration

The configuration file could contain the following information:

```json
{
    "port": 6982,                   # Service port number.
    "number_of_threads": 1,         # Number of I/O threads, 1 by default; if the value is 0, the number of threads is the number of CPU cores.
    "connection_timeout": 60,       # Connection lifetime without reading or writing.
    "keep_alive_request_number": 0, # Sets the maximum number of requests that can be handled over the same keep-alive connection.
                                    # Once the maximum number of requests has been reached, the connection is closed.
                                    # The default value of 0 means unlimited.
    "client_max_body_size": 50,     # Maximum allowed request body size, in MB.
                                    # The default value is 100 MB.
    "logger_path" : "/service",     # Path to the log file.
    "logger_level" : "trace",       # Sets the log level. [trace|debug|info|warn|error|fatal|off]
    "logger_rotation" : "daily",    # Sets log rotation. [hourly|daily]
    "logger_max_files" : 31,        # Sets the maximum number of log files.
    "auth_enabled": false,          # Enables JWT protection for non-public endpoints.
    "auth_jwt_secret": "",         # Shared secret used to validate HS256 JWT tokens.
    "auth_accept_authorization_header": true,
    "auth_accept_api_key_header": true,
    "auth_api_key_header_name": "x-api-key"
}
```

The configuration file can be passed as a parameter to the service. By default, the service will look for a file called `/service/config/config.json`. In the case of the Docker container, the configuration file could be located in a volume mounted at `/service/config`.

JWT authentication is optional and disabled by default. The startup settings above can also be provided through environment variables with the prefix `FACEPHI_VOICE_REST_AUTH_`:

* `FACEPHI_VOICE_REST_AUTH_ENABLED`
* `FACEPHI_VOICE_REST_AUTH_JWT_SECRET`
* `FACEPHI_VOICE_REST_AUTH_ACCEPT_AUTHORIZATION_HEADER`
* `FACEPHI_VOICE_REST_AUTH_ACCEPT_API_KEY_HEADER`
* `FACEPHI_VOICE_REST_AUTH_API_KEY_HEADER_NAME`

When JWT is enabled, `GET /api/v1/version`, `GET /api/v1/health` and preflight requests `OPTIONS` remain public. The rest of the endpoints require a valid JWT via `Authorization: Bearer <jwt>` or the configured API key header.

JWT startup settings apply only when the service starts. `GET /api/v1/config` does not expose these fields and `POST /api/v1/config` rejects attempts to modify them.

### 3.3 Network configuration

To be able to connect to our license servers, you must add the following rules to your firewall rules:

| IP           | Port | Type   |
| ------------ | ---- | ------ |
| 52.223.22.71 | 443  | TCP/IP |
| 35.71.188.31 | 443  | TCP/IP |
| 75.2.113.112 | 443  | TCP/IP |
| 99.83.149.57 | 443  | TCP/IP |

Next, add the following `DNS` to your whitelist:

```bash
https://api.cryptlex.com:443
https://api.eu.cryptlex.com:443
```
