> For the complete documentation index, see [llms.txt](https://doc.ozforensics.com/oz-knowledge/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://doc.ozforensics.com/oz-knowledge/guides/administrator-guide/telemetry/echo-oz-telemetry-receiver/docker-compose.md).

# Docker Compose

Use this path if you run the full Oz API stack (api6) via Docker Compose. Echo is one of several services api6 brings up; this guide covers the Echo-specific parts of that process. It assumes you're already following api6's own README for the base stack – the steps below are the subset that matter for Echo.

Shared concepts (authentication, endpoints, configuration reference) can be found on the [parent page](/oz-knowledge/guides/administrator-guide/telemetry/echo-oz-telemetry-receiver.md).

### Prerequisites

* Docker Compose v2.20.3 or newer (the compose files use the include: key)
* The api6 release contents laid out in an install directory, e.g., `/opt/oz/api6`.
* All commands below must be run from that install directory – cross-file service discovery (nginx → Echo → Mongo) depends on every compose invocation sharing the same default network, which Compose derives from the working directory

{% stepper %}
{% step %}

### Make init scripts executable

```shellscript
API_DIR=/opt/oz/api6
find "$API_DIR/configs/" -name "*.sh" -exec chmod +x {} \;
```

{% endstep %}

{% step %}

### Generate the Oz API JWT keypair

Echo uses the **public** half of this keypair to verify tokens issued by the main API.

```shellscript
openssl ecparam -name secp384r1 -genkey -noout | openssl pkcs8 -topk8 -nocrypt \
  -out "$API_DIR/configs/api/keys/jwt/jwt.key"
openssl ec -in "$API_DIR/configs/api/keys/jwt/jwt.key" -pubout \
  -out "$API_DIR/configs/api/keys/jwt/jwt.pub"
```

{% endstep %}

{% step %}

### Generate Echo's own signing key

This one is separate from the API keypair above – it's only used for Echo's own login/refresh tokens.

```shellscript
openssl rand -base64 129 | tr -d '
' > "$API_DIR/configs/echo/keys/jwt.key"
```

{% endstep %}

{% step %}

### (Optional) Static Echo users/tokens

Edit these – empty by default:

* `configs/echo/service.toml` – comma-separated list of accounts allowed to call `GET /api/event_sessions`.
* `configs/echo/static_tokens.toml` – "email" = "token" pre-shared bearer tokens.
* `configs/echo/users.toml` – "email" = "password" login accounts.
  {% endstep %}

{% step %}

### Change default passwords before first run

At minimum, edit `configs/env/mongo.env` and set `MONGO_PASS` to something other than the shipped default – this is the credential Echo uses to reach its shared MongoDB.
{% endstep %}

{% step %}

### Start the core API, then Echo

```shellscript
cd "$API_DIR"
docker compose -f ./docker/docker-compose-api-local-local.yml up -d      # or -local-s3.yml for S3 storage
docker compose -f ./docker/docker-compose-echo-maxwell.yml up -d
```

This brings up three containers: api6-echo, api6-mongo (shared with Maxwell), and api6-maxwell.
{% endstep %}
{% endstepper %}

### How Echo is reached

Echo does **not** publish a host port in this setup. It's reverse-proxied through api6-nginx, controlled by two variables in `configs/env/nginx.env`:

```
ECHO_ENABLE="Yes"
ECHO_HOST="api6-echo"
```

To disable Echo, comment out both lines (confirm it with Oz Forensics support first, since it's treated as an essential component).

### Verification

Through Nginx, from outside:

```shellscript
curl https://<your-api-host>/api/event_sessions/... # via whatever path/port your nginx is configured with
```

Directly, from inside the Docker network (useful for a quick sanity check without going through nginx/TLS):

```shellscript
docker exec -it api6-echo curl -s http://localhost:8010/healthz
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## 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, and the optional `goal` query parameter:

```
GET https://doc.ozforensics.com/oz-knowledge/guides/administrator-guide/telemetry/echo-oz-telemetry-receiver/docker-compose.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

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.
