# Start a search engine (Docker)

This documentation details how you can start, and host, your own [smart contract search engine](https://github.com/second-state/smart-contract-search-engine) using [Docker](https://www.docker.com/). If you would like to build from scratch from a fresh Ubuntu install, please refer to [this document](/smart-contracts-search-engine/start-a-search-engine.md).

## Prerequisite

We start from a fresh install of Ubuntu 18.04. You should first follow [the instructions here to install Docker](https://www.digitalocean.com/community/tutorials/how-to-install-and-use-docker-on-ubuntu-18-04).

Next install the Python pip and AWS CLI utilities as follows. The AWS CLI is required to access AWS ElasticSearch services.

```bash
$ sudo apt update
$ sudo apt install python-pip
$ sudo apt install awscli
```

## ElasticSearch

We use the AWS ElasticSearch services to run the search engine. You should [create a new ES cluster here](https://console.aws.amazon.com/es/home). For now, a single machine development cluster would suffice. In the Access Policy section, please select IAM users. You will need [an IAM user already set up](https://console.aws.amazon.com/iam/home?#/users) to access AWS ES services. Here is an example.

```
arn:aws:iam::522901590065:user/secondstatesearch
```

Once the ElasticSearch service is up and running, you should have an ES endpoint like the following.

```
search-smart-contract-search-engine-3paomceha6u4qzchkmbgsjdcqa.us-east-1.es.amazonaws.com
```

## Docker

Now, go back to the Ubuntu 18.04 machine.

### AWS credentials

Configure AWS CLI to access the ElasticSearch engine.

```bash
$ aws configure
```

It requires four pieces of information. The access keys are found in the [IAM user console](https://console.aws.amazon.com/iam/home?#/users) for the user you configured to access the ElasticSearch engine you just created.

```
AWS Access Key ID [None]: [IAM user console]
AWS Secret Access Key [None]: [IAM user console]
Default region name [None]: [Region for ES instance. eg us-east-1]
Default output format [None]: json
```

After configuration, AWS config and credentials are placed in `~/.aws/`.

### Configure search engine

Next, get the source code for the search engine.

```bash
$ git clone https://github.com/second-state/smart-contract-search-engine.git
$ cd smart-contract-search-engine
```

Fill in the following configuration options.

* `ServerName` in apache config `config/site.conf`. This could be your public IP address for now.
* `blockchain`, `elasticsearch` , and the initial ABI configs in `python/config.ini`.
* `publicIp` in `js/secondStateJS.js`. This could be your IP address for now.
* Check [here](https://github.com/second-state/whitepapers/tree/2d68282b29af48f62e2075a36bd229f10fe51aa3/smart-contracts-search-engine/start-a-search-engine/README.md#javascript) for details about configurations.

### Build Docker image

```bash
$ docker build -f docker/Dockerfile -t search-engine .
```

### Run Docker container

```bash
$ docker run -d -it --rm -p 80:80 -v $HOME/.aws:/root/.aws search-engine
```

{% hint style="info" %}
If the above command failed because the host port 80 is already taken, try the following command `sudo apachectl stop` to stop the host apache server.
{% endhint %}

Now you can visit `http://<your_host>` to check your smart contract search engine. Be patient, as it may take hours before the results show up on that page.

## Upload more ABIs

Your search engine is started with a single ABI to index from the `config.ini` file. You can add more ABIs to the index by executing the following script from inside the Docker instance.

You can find the `container_id` for your docker instance on your host OS, by running

```bash
$ docker container ls
```

Next, logging into your docker container using the `container_id`

```bash
$ docker exec -it container_id bash
```

Once logged, in the `/app` directory, create a file `upload_abi.py` like the following.

```python
import re
import json
import time
import requests
from harvest import Harvest

harvester = Harvest()

abiUrl1 = "http://A_raw_text_file_which_contains_only_an_abi's_text"
abiData1 = requests.get(abiUrl1).content
abiData1JSON = json.loads(abiData1)
theDeterministicHash1 = harvester.shaAnAbi(abiData1JSON)
cleanedAndOrderedAbiText1 = harvester.cleanAndConvertAbiToText(abiData1JSON)

data1 = {}
data1['indexInProgress'] = "false"
data1['epochOfLastUpdate'] = int(time.time())
data1['abi'] = cleanedAndOrderedAbiText1
harvester.es.index(index=harvester.abiIndex, id=theDeterministicHash1, body=data1)
```

Then run

```bash
$ python3.6 upload_abi.py
```

Also once all of this is done, please just exit docker and give it a reboot.

```bash
$ docker restart container_id
```


---

# 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.secondstate.io/smart-contracts-search-engine/start-a-search-engine-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.
