# Docker

A Docker container for NetObserv SNMP Trap is available on [Docker Hub](https://hub.docker.com/r/elastiflow/trap-collector). [docker-compose](https://docs.docker.com/compose/) is a good way to run the container. It allows for the various environment variables, used to configure the collector, to be easily managed in one place without having to enter them on the command line.

### docker-compose.yml

The following `docker-compose.yml` file provides a starting point that can be further customized for your environment and needs.

<pre data-overflow="wrap"><code>
services:
  # ElastiFlow NetObserv SNMP Trap
  trap-collector:
    image: elastiflow/trap-collector:<code class="expression">space.vars.current_version</code>
    container_name: trap-collector
    restart: 'unless-stopped'
    ports:
      - 162:162/udp
      # - 162:162/tcp # if you reconfigure trapcoll to use tcp instead, then this line will work.
    #volumes:
      # If you want more visibility or control of config specific to trap-collector, you will want to mount this directory.
      # You must ensure /var/lib/elastiflow/trapcoll directory is setup correctly on your host machine.
      # See below (from official docs site) for more details.
      # - /var/lib/elastiflow/trapcoll:/var/lib/elastiflow/trapcoll
    
      # If you want to customize the 'rules' for how trap-collector interprets traps and OIDs,
      # then 1) volume mount the the below path 2) download the 'snmp' repo to this location
      # on your host machine https://github.com/elastiflow/snmp/releases .
      # See below (from official docs site) for more details.
      # - /var/lib/elastiflow/snmp:/var/lib/elastiflow/snmp
    environment:
      ## Set EF_LICENSE_ACCEPTED true. This indicates you accept the EULA of trap-collector
      EF_LICENSE_ACCEPTED: ""
      ## EF_ACCOUNT_ID and EF_LICENSE_KEY will be provided by Elastiflow when you purchase a license.
      EF_ACCOUNT_ID: ""
      EF_LICENSE_KEY: ""

      #EF_LICENSE_TELEMETRY_HOSTS: ""
      
      #EF_API_BASIC_AUTH_ENABLE: "false"
      #EF_API_BASIC_AUTH_PASSWORD: ""
      #EF_API_BASIC_AUTH_USERNAME: ""
      #EF_API_IP: 0.0.0.0
      #EF_API_PORT: 8080
      #EF_API_TLS_CERT_FILEPATH: ""
      #EF_API_TLS_ENABLE: "false"
      #EF_API_TLS_KEY_FILEPATH: ""
      #EF_INSTANCE_NAME: default
      
      #EF_LOGGER_DEVELOPMENT_ENABLE: "false"
      #EF_LOGGER_ENCODING: json
      #EF_LOGGER_FILE_LOG_COMPRESS: ""
      #EF_LOGGER_FILE_LOG_ENABLE: "false"
      #EF_LOGGER_FILE_LOG_FILENAME: ""
      #EF_LOGGER_FILE_LOG_MAX_AGE: 0
      #EF_LOGGER_FILE_LOG_MAX_BACKUPS: 4
      #EF_LOGGER_FILE_LOG_MAX_SIZE: 100
      #EF_LOGGER_LEVEL: info
      
      #EF_INPUT_TRAP_ENABLE: "true"
      #EF_INPUT_TRAP_LISTENER_AUTHORITATIVE_ENGINE_ID: authoritative_engine_id
      #EF_INPUT_TRAP_LISTENER_CREDENTIALS_DIRECTORY_PATH: /etc/elastiflow/snmp/traps/credentials
      #EF_INPUT_TRAP_LISTENER_CREDENTIALS_SECURE_STORE_CREATE: "false"
      #EF_INPUT_TRAP_LISTENER_CREDENTIALS_SECURE_STORE_ENABLE: "false"
      #EF_INPUT_TRAP_LISTENER_CREDENTIALS_SECURE_STORE_PASSWORD: ""
      #EF_INPUT_TRAP_LISTENER_CREDENTIALS_SECURE_STORE_PRIVATE_KEY_FILE_PATH: /etc/elastiflow/snmp/traps/.age/key.age
      #EF_INPUT_TRAP_LISTENER_CREDENTIALS_SECURE_STORE_PUBLIC_KEY: ""
      #EF_INPUT_TRAP_LISTENER_CREDENTIALS_SECURE_STORE_PUBLIC_KEY_FILE_PATH: /etc/elastiflow/snmp/traps/.age/public-age-keys.txt
      #EF_INPUT_TRAP_LISTENER_CREDENTIALS_SECURE_STORE_TYPE: standard
      #EF_INPUT_TRAP_LISTENER_DEVICE_STORE_CHANGE_DETECTION_ENABLE: "true"
      #EF_INPUT_TRAP_LISTENER_DEVICE_STORE_PATH: /var/lib/elastiflow/trapcoll/devices.yml
      #EF_INPUT_TRAP_LISTENER_DEVICE_STORE_TTL: 30
      #EF_INPUT_TRAP_LISTENER_IP: 0.0.0.0
      #EF_INPUT_TRAP_LISTENER_NORMALIZER_POOL_SIZE: 3
      #EF_INPUT_TRAP_LISTENER_PORT: 162
      #EF_INPUT_TRAP_LISTENER_TRANSPORT: udp
      
      #EF_PROCESSOR_POOL_SIZE: 0
      #EF_PROCESSOR_TRAP_DSL_ENABLE: "true"
      #EF_PROCESSOR_TRAP_DSL_ENTERPRISE_FILE_PATH: /etc/elastiflow/snmp/traps/enterprises.yml
      #EF_PROCESSOR_TRAP_DSL_ENUM_DEFINITIONS_DIRECTORY_PATH: /etc/elastiflow/snmp/enums
      #EF_PROCESSOR_TRAP_DSL_GENERIC_FILE_PATH: /etc/elastiflow/snmp/traps/generic.yml
      #EF_PROCESSOR_TRAP_DSL_RULES_DIRECTORY_PATH: /etc/elastiflow/snmp/traps/rules
      
      # stdout
      #EF_OUTPUT_STDOUT_ALLOWED_RECORD_TYPES: as_path_hop,flow_option,flow,ifa_hop,telemetry,metric,log
      #EF_OUTPUT_STDOUT_ENABLE: "false"
      #EF_OUTPUT_STDOUT_FORMAT: json_pretty

      # monitor
      #EF_OUTPUT_MONITOR_ENABLE: "false"
      #EF_OUTPUT_MONITOR_INTERVAL: 300
      
      # Cribl
      #EF_OUTPUT_CRIBL_ADDRESSES: 127.0.0.1:10080
      #EF_OUTPUT_CRIBL_ALLOWED_RECORD_TYPES: as_path_hop,flow_option,flow,ifa_hop,telemetry,metric,log
      #EF_OUTPUT_CRIBL_BATCH_DEADLINE: 2000
      #EF_OUTPUT_CRIBL_BATCH_MAX_BYTES: 8388608
      #EF_OUTPUT_CRIBL_DROP_FIELDS: ""
      #EF_OUTPUT_CRIBL_ENABLE: "false"
      #EF_OUTPUT_CRIBL_TLS_CA_CERT_FILEPATH: ""
      #EF_OUTPUT_CRIBL_TLS_ENABLE: "true"
      #EF_OUTPUT_CRIBL_TLS_SKIP_VERIFICATION: "false"
      #EF_OUTPUT_CRIBL_TOKEN: ""
      
      # generic http
      #EF_OUTPUT_GENERIC_HTTP_ADDRESSES: 127.0.0.1:8888
      #EF_OUTPUT_GENERIC_HTTP_ALLOWED_RECORD_TYPES: as_path_hop,flow_option,flow,ifa_hop,telemetry,metric,log
      #EF_OUTPUT_GENERIC_HTTP_BATCH_DEADLINE: 2000
      #EF_OUTPUT_GENERIC_HTTP_BATCH_MAX_BYTES: 8388608
      #EF_OUTPUT_GENERIC_HTTP_DROP_FIELDS: ""
      #EF_OUTPUT_GENERIC_HTTP_ECS_ENABLE: "false"
      #EF_OUTPUT_GENERIC_HTTP_ENABLE: "false"
      #EF_OUTPUT_GENERIC_HTTP_PASSWORD: ""
      #EF_OUTPUT_GENERIC_HTTP_TIMESTAMP_SOURCE: collect
      #EF_OUTPUT_GENERIC_HTTP_TLS_CA_CERT_FILEPATH: ""
      #EF_OUTPUT_GENERIC_HTTP_TLS_ENABLE: "false"
      #EF_OUTPUT_GENERIC_HTTP_TLS_SKIP_VERIFICATION: "false"
      #EF_OUTPUT_GENERIC_HTTP_USERNAME: ""
      
      # Elasticsearch
      #EF_OUTPUT_ELASTICSEARCH_ADDRESSES: 127.0.0.1:9200
      #EF_OUTPUT_ELASTICSEARCH_ALLOWED_RECORD_TYPES: as_path_hop,flow_option,flow,ifa_hop,telemetry,metric,log
      #EF_OUTPUT_ELASTICSEARCH_API_KEY: ""
      #EF_OUTPUT_ELASTICSEARCH_BATCH_DEADLINE: 2000
      #EF_OUTPUT_ELASTICSEARCH_BATCH_MAX_BYTES: 8388608
      #EF_OUTPUT_ELASTICSEARCH_CLIENT_CA_CERT_FILEPATH: ""
      #EF_OUTPUT_ELASTICSEARCH_CLIENT_CERT_FILEPATH: ""
      #EF_OUTPUT_ELASTICSEARCH_CLIENT_KEY_FILEPATH: ""
      #EF_OUTPUT_ELASTICSEARCH_CLOUD_ID: ""
      #EF_OUTPUT_ELASTICSEARCH_DROP_FIELDS: ""
      #EF_OUTPUT_ELASTICSEARCH_ECS_ENABLE: "false"
      #EF_OUTPUT_ELASTICSEARCH_ENABLE: "false"
      #EF_OUTPUT_ELASTICSEARCH_INDEX_PERIOD: rollover
      #EF_OUTPUT_ELASTICSEARCH_INDEX_SUFFIX: ""
      #EF_OUTPUT_ELASTICSEARCH_INDEX_TEMPLATE_CODEC: best_compression
      #EF_OUTPUT_ELASTICSEARCH_INDEX_TEMPLATE_ENABLE: "true"
      #EF_OUTPUT_ELASTICSEARCH_INDEX_TEMPLATE_ILM_LIFECYCLE: elastiflow
      #EF_OUTPUT_ELASTICSEARCH_INDEX_TEMPLATE_OVERWRITE: "true"
      #EF_OUTPUT_ELASTICSEARCH_INDEX_TEMPLATE_PIPELINE_DEFAULT: _none
      #EF_OUTPUT_ELASTICSEARCH_INDEX_TEMPLATE_PIPELINE_FINAL: _none
      #EF_OUTPUT_ELASTICSEARCH_INDEX_TEMPLATE_REFRESH_INTERVAL: 10s
      #EF_OUTPUT_ELASTICSEARCH_INDEX_TEMPLATE_REPLICAS: 1
      #EF_OUTPUT_ELASTICSEARCH_INDEX_TEMPLATE_SHARDS: 3
      #EF_OUTPUT_ELASTICSEARCH_MAX_RETRIES: 3
      #EF_OUTPUT_ELASTICSEARCH_PASSWORD: changeme
      #EF_OUTPUT_ELASTICSEARCH_RETRY_BACKOFF: 1000
      #EF_OUTPUT_ELASTICSEARCH_RETRY_ENABLE: "true"
      #EF_OUTPUT_ELASTICSEARCH_RETRY_ON_TIMEOUT_ENABLE: "true"
      #EF_OUTPUT_ELASTICSEARCH_TIMESTAMP_SOURCE: collect
      #EF_OUTPUT_ELASTICSEARCH_TLS_CA_CERT_FILEPATH: ""
      #EF_OUTPUT_ELASTICSEARCH_TLS_ENABLE: "false"
      #EF_OUTPUT_ELASTICSEARCH_TLS_SKIP_VERIFICATION: "false"
      #EF_OUTPUT_ELASTICSEARCH_TSDS_ENABLE: "false"
      #EF_OUTPUT_ELASTICSEARCH_USERNAME: elastic
      
      # OpenSearch
      #EF_OUTPUT_OPENSEARCH_ADDRESSES: 127.0.0.1:9200
      #EF_OUTPUT_OPENSEARCH_ALLOWED_RECORD_TYPES: as_path_hop,flow_option,flow,ifa_hop,telemetry,metric,log
      #EF_OUTPUT_OPENSEARCH_AWS_ACCESS_KEY: ""
      #EF_OUTPUT_OPENSEARCH_AWS_REGION: ""
      #EF_OUTPUT_OPENSEARCH_AWS_SECRET_KEY: ""
      #EF_OUTPUT_OPENSEARCH_BATCH_DEADLINE: 2000
      #EF_OUTPUT_OPENSEARCH_BATCH_MAX_BYTES: 8388608
      #EF_OUTPUT_OPENSEARCH_CLIENT_CA_CERT_FILEPATH: ""
      #EF_OUTPUT_OPENSEARCH_CLIENT_CERT_FILEPATH: ""
      #EF_OUTPUT_OPENSEARCH_CLIENT_KEY_FILEPATH: ""
      #EF_OUTPUT_OPENSEARCH_DROP_FIELDS: ""
      #EF_OUTPUT_OPENSEARCH_ECS_ENABLE: "false"
      #EF_OUTPUT_OPENSEARCH_ENABLE: "false"
      #EF_OUTPUT_OPENSEARCH_INDEX_PERIOD: daily
      #EF_OUTPUT_OPENSEARCH_INDEX_SUFFIX: ""
      #EF_OUTPUT_OPENSEARCH_INDEX_TEMPLATE_CODEC: best_compression
      #EF_OUTPUT_OPENSEARCH_INDEX_TEMPLATE_ENABLE: "true"
      #EF_OUTPUT_OPENSEARCH_INDEX_TEMPLATE_ISM_POLICY: elastiflow
      #EF_OUTPUT_OPENSEARCH_INDEX_TEMPLATE_OVERWRITE: "true"
      #EF_OUTPUT_OPENSEARCH_INDEX_TEMPLATE_PIPELINE_DEFAULT: _none
      #EF_OUTPUT_OPENSEARCH_INDEX_TEMPLATE_PIPELINE_FINAL: _none
      #EF_OUTPUT_OPENSEARCH_INDEX_TEMPLATE_REFRESH_INTERVAL: 10s
      #EF_OUTPUT_OPENSEARCH_INDEX_TEMPLATE_REPLICAS: 1
      #EF_OUTPUT_OPENSEARCH_INDEX_TEMPLATE_SHARDS: 3
      #EF_OUTPUT_OPENSEARCH_MAX_RETRIES: 3
      #EF_OUTPUT_OPENSEARCH_PASSWORD: admin
      #EF_OUTPUT_OPENSEARCH_RETRY_BACKOFF: 1000
      #EF_OUTPUT_OPENSEARCH_RETRY_ENABLE: "true"
      #EF_OUTPUT_OPENSEARCH_RETRY_ON_TIMEOUT_ENABLE: "true"
      #EF_OUTPUT_OPENSEARCH_TIMESTAMP_SOURCE: collect
      #EF_OUTPUT_OPENSEARCH_TLS_CA_CERT_FILEPATH: ""
      #EF_OUTPUT_OPENSEARCH_TLS_ENABLE: "false"
      #EF_OUTPUT_OPENSEARCH_TLS_SKIP_VERIFICATION: "false"
      #EF_OUTPUT_OPENSEARCH_USERNAME: admin
      
      # Splunk
      #EF_OUTPUT_SPLUNK_HEC_ADDRESSES: 127.0.0.1:8088
      #EF_OUTPUT_SPLUNK_HEC_ALLOWED_RECORD_TYPES: as_path_hop,flow_option,flow,ifa_hop,telemetry,metric,log
      #EF_OUTPUT_SPLUNK_HEC_BATCH_DEADLINE: 2000
      #EF_OUTPUT_SPLUNK_HEC_BATCH_MAX_BYTES: 8388608
      #EF_OUTPUT_SPLUNK_HEC_CIM_ENABLE: "false"
      #EF_OUTPUT_SPLUNK_HEC_DROP_FIELDS: ""
      #EF_OUTPUT_SPLUNK_HEC_ENABLE: "false"
      #EF_OUTPUT_SPLUNK_HEC_TLS_CA_CERT_FILEPATH: ""
      #EF_OUTPUT_SPLUNK_HEC_TLS_ENABLE: "true"
      #EF_OUTPUT_SPLUNK_HEC_TLS_SKIP_VERIFICATION: "false"
      #EF_OUTPUT_SPLUNK_HEC_TOKEN: ""
      
      # Kafka
      #EF_OUTPUT_KAFKA_ALLOWED_RECORD_TYPES: as_path_hop,flow_option,flow,ifa_hop,telemetry,metric
      #EF_OUTPUT_KAFKA_BROKERS: 127.0.0.1:9092
      #EF_OUTPUT_KAFKA_CLIENT_ID: elastiflow-flowcoll
      #EF_OUTPUT_KAFKA_DROP_FIELDS: ""
      #EF_OUTPUT_KAFKA_ECS_ENABLE: "false"
      #EF_OUTPUT_KAFKA_ENABLE: "false"
      #EF_OUTPUT_KAFKA_FLAT_RECORD_ENABLE: "true"
      #EF_OUTPUT_KAFKA_PARTITION_KEY: flow.export.ip.addr
      #EF_OUTPUT_KAFKA_PRODUCER_COMPRESSION: 3
      #EF_OUTPUT_KAFKA_PRODUCER_COMPRESSION_LEVEL: -1000
      #EF_OUTPUT_KAFKA_PRODUCER_FLUSH_BYTES: 1000000
      #EF_OUTPUT_KAFKA_PRODUCER_FLUSH_FREQUENCY: 1000
      #EF_OUTPUT_KAFKA_PRODUCER_FLUSH_MAX_MESSAGES: 0
      #EF_OUTPUT_KAFKA_PRODUCER_FLUSH_MESSAGES: 1024
      #EF_OUTPUT_KAFKA_PRODUCER_MAX_MESSAGE_BYTES: 1000000
      #EF_OUTPUT_KAFKA_PRODUCER_REQUIRED_ACKS: 1
      #EF_OUTPUT_KAFKA_PRODUCER_RETRY_BACKOFF: 100
      #EF_OUTPUT_KAFKA_PRODUCER_RETRY_MAX: 3
      #EF_OUTPUT_KAFKA_PRODUCER_TIMEOUT: 10
      #EF_OUTPUT_KAFKA_RACK_ID: ""
      #EF_OUTPUT_KAFKA_RECORD_TYPE_TOPICS_ENABLE: "false"
      #EF_OUTPUT_KAFKA_SASL_ENABLE: "false"
      #EF_OUTPUT_KAFKA_SASL_PASSWORD: ""
      #EF_OUTPUT_KAFKA_SASL_USERNAME: ""
      #EF_OUTPUT_KAFKA_TIMEOUT: 30
      #EF_OUTPUT_KAFKA_TIMESTAMP_SOURCE: collect
      #EF_OUTPUT_KAFKA_TLS_CA_CERT_FILEPATH: ""
      #EF_OUTPUT_KAFKA_TLS_CERT_FILEPATH: ""
      #EF_OUTPUT_KAFKA_TLS_ENABLE: "false"
      #EF_OUTPUT_KAFKA_TLS_KEY_FILEPATH: ""
      #EF_OUTPUT_KAFKA_TLS_SKIP_VERIFICATION: "false"
      #EF_OUTPUT_KAFKA_TOPIC: elastiflow-flow-codex
      #EF_OUTPUT_KAFKA_TOPIC_VERSION: 1.0
      #EF_OUTPUT_KAFKA_VERSION: 1.0.0
</code></pre>

#### Image

The name of the currently released image is elastiflow/trap-collector:{constants.version}.

#### Restart

`restart` is set to `unless-stopped` so that the collector will restart automatically if it fails for some reason.

#### Ports

This compose file assumes you need to listen to port 162, and that you will be running Docker using sudo to allow Docker to mount to the privileged port 162. If your context is different, or you configured trap-collector differently, you should adjust the compose contents as needed.

#### Volumes

There are a few scenarios where you will want to mount volumes in the compose file. The container can work without any volume mounting, but you also will not be able to persist any configuration files that way.

{% hint style="info" %}
It is also possible to build a new container, adding additional files as needed. This may the best choice if running the container in a dynamically orchestrated environment (e.g. running in Kubernetes). However for an instance dedicated to a specific host, using bind mounted volumes can be very convenient.
{% endhint %}

**Mounting /var/lib/elastiflow/trapcoll**

The `/var/lib/elastiflow/trapcoll` path can be mounted for a couple of reasons.

1. the [devices.yml](/trapcoll/configuration/receiving-traps/devices.md) file is used to store information about devices that have sent traps to the collector. That will be automatically created by the container when it starts, and will reside at `/var/lib/elastiflow/trapcoll/devices.yml`.
2. If you anticipate devices sending v3 traps, you will need to provide the collector with the necessary credentials. This can be done by mounting your credentials configurations (see [credentials.yml](https://github.com/elastiflow/snmp/tree/main/traps/credentials) for a template) to `/etc/elastiflow/snmp/traps/credentials` in the container. More information regarding v3 trap credentials can be found [here](/trapcoll/configuration/receiving-traps/credentials.md)

Make sure, on your host machine, /var/lib/elastiflow/trapcoll is owned by a user named 'ElastiFlow' since that is the user which the container will use. For example:

```bash
sudo mkdir -p /var/lib/elastiflow/trapcoll
sudo chown -R elastiflow /var/lib/elastiflow
```

**Mounting /var/lib/elastiflow/snmp**

If you want to customize the 'rules' for how trap-collector interprets traps and OIDs, then

1. volume mount the the below `/var/lib/elastiflow/snmp`
2. download the latest release of the ['snmp' repo](https://github.com/elastiflow/snmp/releases) to that location on your host machine.

Now you can add additional folders or files inside /var/lib/elastiflow/snmp on your host machine, and you'll have more customizable control over how trap-collector interprets traps.

#### Environment variables

NetObserv SNMP Trap is configured using environment variables.

For a complete reference of all configuration options please refer to the [Configuration Reference](/trapcoll/configuration.md).

At minimum, you will need to set the following license related variables. NetObserv SNMP Trap requires a license to run at all.

* EF\_LICENSE\_ACCEPTED should be set to "true". This indicates you accept the EULA of trap-collector.
* EF\_ACCOUNT\_ID and EF\_LICENSE\_KEY will be provided by ElastiFlow when you purchase a license.

#### Running the Container

After completing configuration of the collector in the `docker-compose.yml` file, you can start the container using one of the below commands.

{% hint style="info" %}
For many linux environments, you might have to run sudo to run Docker compose.
{% endhint %}

From within the same path as the `docker-compose.yml` file:

```
docker-compose up -d
```

To view the logs:

```
docker logs -f trap-collector
```

To stop the container:

```
docker-compose down
```


---

# 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.elastiflow.com/trapcoll/installation/install_docker.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.
