---
title: "Compose the stack"
description: "Define the TLS-enabled Docker Compose project for the Elasticsearch connector tutorial."
---

# Compose the stack

> For the complete documentation index see: [llms.txt](https://aerospike.com/docs/llms.txt)
> 
> All documentation pages available in markdown.

::: caution
This stack is for local development only. The published ports are bound to `127.0.0.1`, but the Aerospike client port and Elasticsearch connector management endpoint remain unencrypted, and the Elasticsearch password is a documented development value. Do not remove the loopback bindings or use this password outside the tutorial. For longer-lived environments, mount credentials from a secret store. For supported TLS store formats, see [Connector settings](https://aerospike.com/docs/connectors/elasticsearch/configure/service#configuring-tls).
:::

Create `docker-compose.yml` in the project directory. This file mounts the `security/` directory into every container that needs certificates, exposes the Elasticsearch connector’s TLS port on 8443, and sets `ELASTIC_PASSWORD` on the Elasticsearch container.

docker-compose.yml

```yaml
name: aerospike-elastic-tls

services:

    aerospike:

        image: aerospike/aerospike-server-enterprise:8.1.1.0

        container_name: aerospike

        volumes:

            - ./aerospike.conf:/etc/aerospike/aerospike.template.conf:ro

            - ./features.conf:/etc/aerospike/features.conf:ro

            - ./security:/etc/aerospike/security:ro

        group_add:

            - "${HOST_GID}"

        healthcheck:

            test: ["CMD", "asinfo", "-v", "status"]

            interval: 5s

            timeout: 5s

            retries: 10

    elasticsearch:

        image: docker.elastic.co/elasticsearch/elasticsearch:9.5.0

        container_name: elasticsearch

        environment:

            - ELASTIC_PASSWORD=changeme-for-dev

            - ES_JAVA_OPTS=-Xms512m -Xmx512m

        volumes:

            - ./elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml:ro

            - ./security/ca.crt:/usr/share/elasticsearch/config/certs/ca.crt:ro

            - ./security/elasticsearch.local.crt:/usr/share/elasticsearch/config/certs/elasticsearch.local.crt:ro

            - ./security/elasticsearch.local.key:/usr/share/elasticsearch/config/certs/elasticsearch.local.key:ro

        group_add:

            - "${HOST_GID}"

        ports:

            - "127.0.0.1:9200:9200"

        healthcheck:

            test:

                [

                    "CMD-SHELL",

                    "curl -sf --cacert config/certs/ca.crt -u elastic:$$ELASTIC_PASSWORD https://localhost:9200/_cluster/health >/dev/null",

                ]

            interval: 5s

            timeout: 5s

            retries: 20

    aerospike-elasticsearch-outbound:

        image: aerospike/aerospike-elasticsearch-outbound:3.0.2

        container_name: aerospike-elasticsearch-outbound

        volumes:

            - ./aerospike-elasticsearch-outbound.yml:/etc/aerospike-elasticsearch-outbound/aerospike-elasticsearch-outbound.yml:ro

            - ./security:/etc/aerospike-elasticsearch-outbound/security:ro

        group_add:

            - "${HOST_GID}"

        ports:

            - "127.0.0.1:8443:8443"

            - "127.0.0.1:8902:8902"

        depends_on:

            aerospike:

                condition: service_healthy

            elasticsearch:

                condition: service_healthy

    aerospike-tools:

        image: aerospike/aerospike-tools:13.0.1

        container_name: aerospike-tools

        depends_on:

            aerospike:

                condition: service_healthy

        entrypoint: ["sleep", "infinity"]
```

Validate the Compose file:

Terminal

```bash
docker compose config --quiet
```

The command exits without output when the file is valid.

Elasticsearch reads the `ELASTIC_PASSWORD` environment variable on first boot to set the password for the built-in `elastic` user. The Elasticsearch connector reads the same value from `elastic-password.txt` when it authenticates to Elasticsearch. Keep the two values in sync before you start the stack. This Compose stack does not define a persistent Elasticsearch data volume. Changing either password while the container is running does not update the other value. To change the development password, update both values and recreate the Elasticsearch and Elasticsearch connector containers. Recreating Elasticsearch removes the tutorial data.

`aerospike.conf` is mounted at `/etc/aerospike/aerospike.template.conf` because the Aerospike image renders that file into `/etc/aerospike/aerospike.conf` at startup. Mounting to the template path gives the entrypoint the configuration it expects. The `aerospike-tools` container uses `entrypoint: ["sleep", "infinity"]` so it stays up for interactive `aql` and `asinfo` calls.

::: undefined
-   I’ve created docker-compose.yml for the TLS tutorial stack.
:::

[Previous  
Configure each service](https://aerospike.com/docs/connectors/elasticsearch/learn/secure-with-tls/step/2/part/0/service-configuration) [Next  
Start and verify](https://aerospike.com/docs/connectors/elasticsearch/learn/secure-with-tls/step/3/part/0/start-and-verify)