> 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/ocr/installation/installation_instructions.md).

# Service installation and deployment

## 1. Installation and deployment

The service is dockerized, and there is a Docker image in a Facephi repository. To download the image, you must log in as follows:

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

Download the image:

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

Where `#VERSION#` is the version number we want to download (e.g. `6.8.2`).

## 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:
  ocr-service:
    image: facephicorp.jfrog.io/docker-pro-fphi/facephi-ocr-service:#VERSION#
    container_name: facephi-ocr-service
    ports:
      - "6982:6982"
    environment:
      # Optional JWT protection
      # - FACEPHI_OCR_REST_AUTH_ENABLED=true
      # - FACEPHI_OCR_REST_AUTH_JWT_SECRET=shared-secret
      # - FACEPHI_OCR_REST_AUTH_ACCEPT_AUTHORIZATION_HEADER=true
      # - FACEPHI_OCR_REST_AUTH_ACCEPT_API_KEY_HEADER=false
      # - FACEPHI_OCR_REST_AUTH_API_KEY_HEADER_NAME=x-api-key
    volumes:
      - ~/facephi_ocr_license:/service/license
      - ~/facephi_ocr_configuration:/service/config
      - ~/facephi_ocr_logs:/service/logs
      - ~/facephi_ocr_custom_templates:/service/custom_templates
```

Note the volume that is mounted in the container. This volume is used to store the license file. The volume `facephi_ocr_configuration` is optional, but allows you to configure the service. See section `2.2 Service`. The volume `facephi_ocr_logs` is optional, but allows logs to be saved in local storage, preventing them from being lost when the Docker container stops. The volume `facephi_ocr_custom_templates` is optional, but allows custom document templates to be added. You can copy your custom templates into this folder and then configure the service to use them. See section `3.2 Service`.

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

```bash
docker compose up
```

## 3. License configuration

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

The license file could contain the following information:

```init
LICENSE_TYPE=         # License type, can be MACHINE, SHARED or LOCAL
LICENSE_BEHAVIOUR=    # License behaviour, can be ONLINE or OFFLINE
LICENSE_KEY=          # License key
LICENSE_ID=           # Product ID
LICENSE_DATA=         # Product data
LICENSE_URLS=         # Comma-separated license server URLs. Only needed if LICENSE_TYPE is LOCAL
LICENSE_PATH_OFFLINE= # Local file with data for offline activation. Only needed if LICENSE_TYPE=MACHINE and LICENSE_BEHAVIOUR=OFFLINE
```

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

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 |

Then, add the following URLs to your whitelist:

* <https://api.cryptlex.com:443>
* <https://api.eu.cryptlex.com:443>

## 4. Service configuration

The configuration file could contain the following default information:

```json
{
    "port": 6982,                     # Service port number.

    # The number of used by the REST service, 1 by default.
    # If the value is set to 0, the number of threads is autodetected.
    "number_of_threads": 1,

    "connection_timeout": 60,         # The lifetime of the connection without read or write.

    # Set the maximum number of requests that can be served through one keep-alive connection.
    # After the maximum number of requests are made, the connection is closed.
    # The default value of 0 means no limit.
    "keep_alive_request_number": 0,

    # The maximum size of the body allowed in the requests in Mb. The default value of 100 Mb.
    "client_max_body_size": 100,

    "logger_path": "./logs",         # Set the path to store log files.
    "logger_level": "trace",         # Possible values are [trace|debug|info|warning|error|critical|off].
    "logger_rotation": "daily",      # Possible values are [hourly|daily].
    "logger_max_files": 31,          # The default value of 0 means no limit.

    "auth_enabled": false,          # Enable 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": false,
    "auth_api_key_header_name": "x-api-key",

    # Folder containing the models, templates and other and resources.
    "config_path": "data",

    # Path to the folder that contains the templates.
    "templates_path": "data/templates",

    # Version of the document interpreter to use. 1 legacy version, 2 new version. By default, it is set to 1.
    "document_interpreter_version": 1,

    # By default, it is 0 (use legacy output format). If 1, use universal one.
    "document_interpreter_use_universal": 0,

    # The number of threads in the pool for processing document images in parallel.
    # By default, it is set to 2. If the value is set to 0, the number of threads is autodetected.
    "processor_threads_pool_size": 2,

    # The number of threads in the flow pool for processing inferences in parallel when executing the pipeline.
    "pipeline_threads_pool_size": 1,

    # The number of threads in the pool for creating interpreters in parallel.
    "global_threads_pool_size": 1,

    # Maximum number of threads used during inference. If 0, use as many threads as cores.
    "max_inference_threads": 0,

    # Number of OCR regions of interest that can be processed concurrently.
    "ocr_latin_batch_size": 1,

    # Multi service configuration
    "multi_service_base_url": "http://localhost", # Base URL of the remote multi service.
    "multi_service_api_key": "fake_key",          # API key for authenticating with the remote multi service.
    "multi_service_connection_timeout": 10000,    # Connection timeout in milliseconds for requests to the remote multi service.
    "multi_service_request_timeout": 60000,       # Request timeout in milliseconds for requests to the remote multi service.
    "multi_service_max_retries": 3,               # Maximum number of retries to the remote multi service.
    "multi_service_verify_ssl": true              # Whether to verify SSL certificates when connecting to the remote multi service.
}
```

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`.

All parameters are optional. If any parameter is not present, the default value will be used instead.

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

* `FACEPHI_OCR_REST_AUTH_ENABLED`
* `FACEPHI_OCR_REST_AUTH_JWT_SECRET`
* `FACEPHI_OCR_REST_AUTH_ACCEPT_AUTHORIZATION_HEADER`
* `FACEPHI_OCR_REST_AUTH_ACCEPT_API_KEY_HEADER`
* `FACEPHI_OCR_REST_AUTH_API_KEY_HEADER_NAME`

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

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

### 4.1. `document_interpreter_version`

There are two different interpreters available for processing identity documents and foreigner documents.

These interpreters differ in the following aspects:

* Supported countries
* Output format
* Available fields

#### Supported countries

Version 1:

* Argentina (ARG)
* Mexico (MEX)

Version 2 officially supports a wider set of countries, including:

* Argentina (ARG)
* Bolivia (BOL)
* Brazil (BRA)
* Canada (CAN)
* Chile (CHL)
* Colombia (COL)
* Costa Rica (CRI)
* Dominican Republic (DOM)
* Ecuador (ECU)
* El Salvador (SLV)
* Guatemala (GTM)
* Honduras (HND)
* Jordan (JOR)
* Mexico (MEX)
* Nicaragua (NIC)
* Nigeria (NGA)
* Panama (PAN)
* Paraguay (PRY): PRY I v3, PRY I v2
* Peru (PER): PER I v5, PER I v2
* South Africa (ZAF)
* South Korea (KOR)
* Spain (ESP)
* Uganda (UGA)
* Uruguay (URY)
* Vietnam (VNM)

#### Output format

Each version structures its output data differently.

Version 1 organizes the extracted data using the keys `front` and `back` to distinguish between the front and back of the document:

```json
{
    "back": {
        "Address": "REDACTED",
        ...
    },
    "front": {
        "DateOfBirth": "01/09/1972",
        ...
    }
}
```

Version 2, on the other hand, uses a nested structure under the key `reader`, with numeric identifiers to represent each side of the document (0 for the front and 1 for the back), along with more detailed path-type keys:

```json
{
    "reader": {
        "0/MRZ/DateOfBirth": "01/09/1972",
        ...
        "1/ML/Address": "Redacted",
        ...
    }
}
```

Version 2 also supports universal output (`document_interpreter_use_universal=1`)

#### Available fields

In addition to variations in the data structure, there may be differences in the fields themselves. Some fields may exist only in one format and, even if a field appears in all formats, its content may change.
