# Deploying an Agent

To install the Agent from the archive you must:

1. Extract the archive
2. Configure the Agent
3. Start the Agent

***

## Extracting the archive

{% hint style="success" %}
**Installation link**

Link to archives can be found here: [**https://archive.lenses.io/lenses/6.0/agent/**](https://archive.lenses.io/lenses/6.0/agent/)
{% endhint %}

Extract the archive using the following command

{% code title="terminal" %}

```sh
tar -xvf lenses-agent-latest-linux64.tar.gz -C lenses
```

{% endcode %}

Inside the extract archive, you will find.

```
   lenses
   ├── lenses.conf       ← edited and renamed from .sample
   ├── logback.xml
   ├── logback-debug.xml
   ├── bin/
   ├── lib/
   ├── licences/
   ├── logs/             ← created when you run Lenses
   ├── plugins/
   ├── storage/          ← created when you run Lenses
   └── ui/
```

***

## &#x20;Configure the Agent

To configure the agents connection to Postgres and its provisioning file. See here in the [quickstart](/latest/devx/6.0/getting-started/quickstart.md#deploy-agent).

Once the agent files are configure you can continue to start the agent.&#x20;

{% hint style="info" %}
The configuration files are the same for docker and Linux, for docker we are simply mounting the files into the container.
{% endhint %}

### Provisioning

{% stepper %}
{% step %}

#### Configure HQ

To see be able to view and drilling to your Kafka environment, you need to connect the agent to HQ. You need to create an environment in HQ and copy the Agent Key into the **provisioning.yaml.**&#x20;

<figure><img src="/files/24wdM2UiwkXsZlwEYAG5" alt=""><figcaption><p>Create new environment and obtain Agent key</p></figcaption></figure>

{% tabs %}
{% tab title="TLS Enabled" %}
{% code title="provisioning.yaml" %}

```yaml
lensesHq:
  - name: lenses-hq
    version: 1
    tags: ['hq']
    configuration:
      server:
        value: [LENSES_HQ_URL]
      port:
        value: 10000
      agentKey:
        value: [LENSES_AGENT_KEY]
      sslEnabled:
        value: true
      sslTruststore:
        file: "hq-truststore.jks"
      sslTruststorePassword:
        value: ${LENSES_HQ_AGENT_TRUSTSTORE_PWD}
```

{% endcode %}
{% endtab %}

{% tab title="TLS Disabled" %}
{% code title="provisioning.yaml" %}

```yaml
lensesHq:
  - name: lenses-hq
    version: 1
    tags: ['hq']
    configuration:
      server:
        value: [LENSES_HQ_URL]
      port:
        value: 10000
      agentKey:
        value: ${LENSES_HQ_AGENT_KEY}
      sslEnabled:
        value: false
```

{% endcode %}
{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Agent key reference**

Agent key within provisioning.yaml can be referenced as a:

* environment variable shown in example above
* inline string
  {% endhint %}
  {% endstep %}

{% step %}

#### Configure Kafka Connection

{% hint style="info" %}
Bare in mind that each Agent connects to one Kafka cluster.
{% endhint %}

There are many Kafka flavours today in the market. Good news is that Lenses support all flavours of Kafka and we are trying hard to keep documention up to date.

In the following [link](/latest/devx/6.0/deployment/configuration/agent/automation/kafka.md) you can find provisioning examples for the most common Kafka flavours.&#x20;

#### Other connections

There are also provisioning examples for other components:

* [Schema Registry](/latest/devx/6.0/deployment/configuration/agent/automation/schema-registries.md)
* [Kafka Connect](/latest/devx/6.0/deployment/configuration/agent/automation/kafka-connect.md)
* [Zookeeper](/latest/devx/6.0/deployment/configuration/agent/automation/zookeeper.md)
* [AWS](/latest/devx/6.0/deployment/configuration/agent/automation/aws.md)
* [Alerts & Audit integrations](/latest/devx/6.0/deployment/configuration/agent/automation/alert-and-audit-integrations.md)
  {% endstep %}

{% step %}

#### Configure Database

{% hint style="warning" %}
Bare in mind that each Agent requires separate database. Two Agents sharing the same database can lead to racing condition issue.
{% endhint %}

Last step is to configure a database to which Agent will be connecting to.

#### Running Agent with Postgres database

{% code title="lenses-agent.conf" %}

```apacheconf
lenses.storage.postgres.host="dbname"
lenses.storage.postgres.database="agentdb"
lenses.storage.postgres.username="agentusername"
lenses.storage.postgres.password="changeme" 
lenses.storage.postgres.port="5432"
lenses.storage.postgres.schema="myschema"
```

{% endcode %}

#### Running Agent with H2 embedded database

{% hint style="warning" %}
Embedded database is not recommended to be used in Production or high load environments.
{% endhint %}

In order to run Agent with embedded database, your *lenses-agent.conf* **should not** carry any property starting with *lenses.storage.postgres.\*&#x20;*&#x20;
{% endstep %}
{% endstepper %}

***

## Provisioning example file

This provisioning file includes connections to:

* [x] Kafka Cluster&#x20;
* [x] Schema Registry
* [x] Kafka Connect
* [x] Lenses HQ

<details>

<summary>provisioning.yaml</summary>

{% code title="provisioning.yaml" %}

```yaml
lensesHq:
- configuration:
    agentKey:
      value: agent_key_*
    port:
      value: 10000
    server:
      value: current-lenses-hq.panoptes.svc.cluster.local
    sslEnabled:
      value: false
  name: lenses-hq
  tags:
  - hq
  version: 1
kafka:
- configuration:
    kafkaBootstrapServers:
      value:
      - PLAINTEXT://prod-1-kafka-bootstrap.kafka-prod.svc.cluster.local:9092
    metricsPort:
      value: 9999
    metricsType:
      value: JMX
    protocol:
      value: PLAINTEXT
  name: kafka
  tags:
  - prod
  - prod-1
  - us
  version: 1
confluentSchemaRegistry:
- configuration:
    schemaRegistryUrls:
      value:
      - http://schema-registry-prod.kafka-prod.svc.cluster.local:8081
  name: schema-registry
  tags:
  - prod
  - global
  version: 1
connect:
- configuration:
    workers:
      value:
      - http://prod-1-connect-connect.kafka-prod.svc.cluster.local:8083
  name: datalake-connect
  tags:
  - prod
  - us
  version: 1

```

{% endcode %}

</details>

***

## Starting the Agent

{% hint style="info" %}
**Provisioning file path**

If you configured provisioning.yaml make sure to place following property:

{% code title="lenses.conf" %}

```apacheconf
# Directory containing the provision.yaml files
lenses.provisioning.path=/my/dir
```

{% endcode %}
{% endhint %}

Start Lenses by running:

{% code title="terminal" %}

```bash
bin/lenses
```

{% endcode %}

or pass the location of the config file:

{% code title="terminal" %}

```sh
bin/lenses lenses-agent.conf
```

{% endcode %}

If you do not pass the location of *lenses-agent.conf*, the Agent will look for it inside the current (runtime) directory. If it does not exist, it will try its installation directory.

{% hint style="warning" %}
In case agent fails with error message that *security.conf* does not exist and is provided just run following command under lenses directory

```bash
touch security.conf
```

{% endhint %}

To stop Lenses, press `CTRL+C`.

***

## File permissions

Set the permissions of the **lenses-agent.conf** to be readable only by the lenses user.

```sh
chmod 0600 /path/to/lenses-agent.conf
chown [lenses-user]:root /path/to/lenses-agent.conf
```

The agent needs write access in 4-5 places in total:

1. `[RUNTIME DIRECTORY]`\
   When the Agent runs, it will create at least one directory under the directory it is run in:
   1. `[RUNTIME DIRECTORY]/logs`\
      Where logs are stored
   2. `[RUNTIME DIRECTORY]/logs/sql-kstream-state`\
      Where SQL processors (when In Process mode) store state. To change the location for the processors’ state directory, use `lenses.sql.state.dir` option.
   3. `[RUNTIME DIRECTORY]/storage`\
      Where the H2 embedded database is stored when PostgreSQL is not set. To change this directory, use the `lenses.storage.directory` option.
   4. `/run` (Global directory for temporary data at runtime)\
      Used for temporary files. If Lenses does not have permission to use it, it will fall back to `/tmp`.
   5. `/tmp` (Global temporary directory)\
      Used for temporary files (if access `/run` fails), and JNI shared libraries.&#x20;

{% hint style="warning" %}
Back-up this location for disaster recovery
{% endhint %}

***

## JNI libraries <a href="#jni" id="jni"></a>

The Agent and Kafka use two common Java libraries that take advantage of JNI and are extracted to **/tmp**.

You must either:

1. Mount /tmp without noexec
2. or set **org.xerial.snappy.tempdir** and **java.io.tmpdir** to a different location

<pre class="language-sh" data-full-width="false"><code class="lang-sh"><strong>LENSES_OPTS="-Dorg.xerial.snappy.tempdir=/path/to/exec/tmp -Djava.io.tmpdir=/path/to/exec/tmp"
</strong></code></pre>

***

## SystemD example <a href="#systemd-example" id="systemd-example"></a>

If your server uses systemd as a Service Manager, then manage the Agent  (start upon system boot, stop, restart). Below is a simple unit file that starts the Agent automatically on system boot.

<pre class="language-sh" data-full-width="false"><code class="lang-sh">[Unit]
Description=Run Agent service

[Service]
<strong>Restart=always
</strong>User=[LENSES-USER]
Group=[LENSES-GROUP]
LimitNOFILE=4096
WorkingDirectory=/opt/lenses
#Environment=LENSES_LOG4J_OPTS="-Dlogback.configurationFile=file:/etc/lenses/logback.xml"
ExecStart=/opt/lenses/bin/lenses /etc/lenses/lenses-agent.conf

[Install]
WantedBy=multi-user.target
</code></pre>

***

## Global Truststore <a href="#global-truststore" id="global-truststore"></a>

The Agent uses the default trust store (**cacerts**) of the system’s JRE (Java Runtime) installation. The trust store is used to verify remote servers on TLS connections, such as Kafka Brokers with an SSL protocol, JMX over TLS, and more. Whilst for some types of connections (e.g. Kafka Brokers) a separate keystore can be provided at the connection’s configuration, for some other connections (JMX over TLS) we always rely on the system trust store.

It is possible to set up a global custom trust store via the **LENSES\_OPTS** environment variable:

{% code fullWidth="false" %}

```bash
export LENSES_OPTS="-Djavax.net.ssl.trustStore=/path/to/truststore.jks -Djavax.net.ssl.trustStorePassword=changeit"
bin/lenses
```

{% endcode %}

***

## Hardware & OS <a href="#hardware--os" id="hardware--os"></a>

Run on any Linux server (review ulimits or container technology (docker/kubernetes). For RHEL 6.x and CentOS 6.x use docker.

Linux machines typically have a soft limit of 1024 open file descriptors. Check your current limit with the **`ulimit`** command:

```bash
ulimit -S -n     # soft limit
ulimit -H -n     # hard limit
```

Increase as a super-user the soft limit to 4096 with:

```bash
ulimit -S -n 4096
```

Use 8GB RAM /4 CPUs and 20GB disk space.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.lenses.io/latest/devx/6.0/deployment/installation/linux/agent.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
