A production-ready Docker Compose setup for running a multi-node OpenSearch cluster with SSL/TLS encryption, security plugins, and OpenSearch Dashboards.
- Multi-node cluster: Two-node OpenSearch cluster for high availability
- SSL/TLS encryption: Automatic certificate generation for secure communication
- Security plugin: Full security enabled with certificate-based authentication
- OpenSearch Dashboards: Web UI for cluster management and visualization
- One-time setup: Certificate generation runs automatically on first start
- Best practices: Follows OpenSearch and Docker Compose best practices
-
Copy the environment file:
cp example.env .env
-
Review and customize
.env(especially passwords):# Edit .env to change default passwords and other settings nano .env -
Start the cluster:
docker-compose up -d
-
Verify the cluster is running:
docker-compose ps
-
Access OpenSearch Dashboards:
- URL:
http://localhost:5601 - Default username:
admin - Default password:
admin(or whatever you set in.env)
- URL:
-
Access OpenSearch API:
curl -k -u admin:admin https://localhost:9200
- opensearch-setup: Generates SSL certificates on first run, then exits
- opensearch-node1: First OpenSearch node (master-eligible)
- opensearch-node2: Second OpenSearch node (master-eligible)
- opensearch-dashboards: Web UI for OpenSearch
All services run on a dedicated bridge network (opensearch-network) for isolation.
certs: Shared volume for SSL certificates (generated by opensearch-setup)opensearch-data1: Persistent data for node1opensearch-data2: Persistent data for node2
The opensearch-setup container runs only once when you first start the cluster:
- Checks if certificates already exist in the
certsvolume - If certificates exist, exits immediately (skips generation)
- If certificates don't exist:
- Generates a Root CA certificate
- Generates certificates for admin, node1, node2, and dashboards
- Sets proper file permissions
- Exits successfully
The container uses a healthcheck that verifies certificate existence. Once healthy, dependent services (opensearch-node1, opensearch-node2, opensearch-dashboards) start automatically.
Note: After the first run, the opensearch-setup container will be in "exited" state, which is expected behavior.
All variables have defaults, so the cluster will run with cp example.env .env without modification. However, you should change passwords before production use.
| Variable | Default | Description |
|---|---|---|
COMPOSE_PROJECT_NAME |
opensearch-cluster |
Docker Compose project name |
OPENSEARCH_VERSION |
latest |
OpenSearch image tag |
OPENSEARCH_DASHBOARDS_VERSION |
latest |
OpenSearch Dashboards image tag |
OPENSEARCH_CLUSTER_NAME |
opensearch-cluster |
Cluster name (must match across nodes) |
OPENSEARCH_INITIAL_ADMIN_PASSWORD |
admin |
CHANGE THIS - Initial admin password |
OPENSEARCH_USERNAME |
admin |
Dashboards username |
OPENSEARCH_PASSWORD |
admin |
CHANGE THIS - Dashboards password |
OPENSEARCH_JAVA_OPTS |
-Xms2g -Xmx2g |
Java heap size (50% of memory limit) |
OPENSEARCH_MEMORY_LIMIT |
4G |
Memory limit per node |
OPENSEARCH_CPU_LIMIT |
4.0 |
CPU limit per node |
CERT_ORGANIZATION |
OpenSearch |
Certificate organization name |
CERT_COUNTRY |
US |
Certificate country code |
CERT_STATE |
CA |
Certificate state/province |
CERT_LOCALITY |
San Francisco |
Certificate city/locality |
See example.env for all available variables with descriptions.
The certificates generated by opensearch-setup use Distinguished Names (DNs) in the format:
CN=<common-name>,O=<organization>,L=<locality>,ST=<state>,C=<country>
The opensearch-setup container automatically updates the DN values in the OpenSearch config files (opensearch-node1.yml and opensearch-node2.yml) to match the certificate subjects it generates. This ensures the DNs always stay in sync.
The DN values are configured in:
plugins.security.authcz.admin_dn: Admin certificate DNplugins.security.nodes_dn: Node certificate DNs
Default DN values (matching default certificate variables):
- Organization:
OpenSearch - Country:
US - State:
CA - Locality:
San Francisco
To customize certificate DNs, simply set the certificate environment variables in your .env file:
CERT_ORGANIZATION=MyCompany
CERT_COUNTRY=US
CERT_STATE=NY
CERT_LOCALITY=New YorkThe setup script will automatically:
- Generate certificates with these values
- Update the DN values in both
opensearch-node1.ymlandopensearch-node2.yml
Important: After changing certificate variables, you must:
- Remove the
certsvolume:docker-compose down -v - Restart to regenerate certificates and update config files:
docker-compose up -d
-
Change all default passwords:
OPENSEARCH_INITIAL_ADMIN_PASSWORDOPENSEARCH_PASSWORD
-
Use specific version tags instead of
latest:OPENSEARCH_VERSION=3.3.2OPENSEARCH_DASHBOARDS_VERSION=3.3.0
-
Customize certificate organization:
- Set
CERT_ORGANIZATIONto your organization name - Update DN values in config files accordingly
- Set
-
Review resource limits:
- Adjust
OPENSEARCH_MEMORY_LIMITandOPENSEARCH_CPU_LIMITbased on your hardware - Ensure
OPENSEARCH_JAVA_OPTSheap size is ~50% of memory limit
- Adjust
-
Network security:
- Consider using Docker secrets for passwords in production
- Restrict port exposure if not needed externally
- Use firewall rules to limit access
-
Regular updates:
- Keep OpenSearch and Dashboards versions up to date
- Review security advisories regularly
If certificates fail to generate:
- Check opensearch-setup logs:
docker-compose logs opensearch-setup - Ensure the container has write permissions to the certs volume
- Remove volumes and restart:
docker-compose down -v && docker-compose up -d
If nodes don't join the cluster:
- Check node logs:
docker-compose logs opensearch-node1 opensearch-node2 - Verify certificate DNs match between certificates and config files
- Ensure both nodes can communicate on the network
- Check discovery settings in node config files
If you can't authenticate:
- Verify passwords match in
.envand Dashboards config - Check that
OPENSEARCH_INITIAL_ADMIN_PASSWORDmatches what you're using - Review security plugin logs in node logs
If ports are already in use:
- Change port mappings in
.env:OPENSEARCH_PORT_1(default: 9200)OPENSEARCH_DASHBOARDS_PORT(default: 5601)
# All services
docker-compose logs -f
# Specific service
docker-compose logs -f opensearch-node1docker-compose down# WARNING: This deletes all data!
docker-compose down -v# Restart all services
docker-compose restart
# Recreate containers (useful after config changes)
docker-compose up -d --force-recreateSee LICENSE file for details.
This is a best-practice example. Feel free to fork and adapt for your needs.