Docker

Docker greatly simplifies the process of configuring and managing your OpenSearch clusters. You can pull official images from Docker Hub or Amazon Elastic Container Registry (Amazon ECR) and quickly deploy a cluster using Docker Compose and any of the sample Docker Compose files included in this guide. Experienced OpenSearch users can further customize their deployment by creating a custom Docker Compose file.

Docker containers are portable and will run on any compatible host that supports Docker (such as Linux, MacOS, or Windows). The portability of a Docker container offers flexibility over other installations methods, like RPM or a manual Tarball installation, which both require additional configuration after downloading and unpacking.

This guide assumes that you are comfortable working from the Linux command line interface (CLI). You should understand how to input commands, navigate between directories, and edit text files. For help with Docker or Docker Compose, refer to the official documentation on their websites.

Install Docker and Docker Compose

Visit Get Docker for guidance on installing and configuring Docker for your environment. If you are installing Docker Engine using the CLI, then Docker, by default, will not have any constraints on available host resources. Depending on your environment, you may wish to configure resource limits in Docker. See Runtime options with Memory, CPUs, and GPUs for information.

Docker Desktop users should set host memory utilization to a minimum of 4 GB by opening Docker Desktop and selecting SettingsResources.

Docker Compose is a utility that allows users to launch multiple containers with a single command. You pass a file to Docker Compose when you invoke it. Docker Compose reads those settings and starts the requested containers. Docker Compose is installed automatically with Docker Desktop, but users operating in a command line environment must install Docker Compose manually. You can find information about installing Docker Compose on the official Docker Compose GitHub page.

If you need to install Docker Compose manually and your host supports Python, you can use pip to install the Docker Compose package automatically.

Configure important host settings

Before installing OpenSearch using Docker, configure the following settings. These are the most important settings that can affect the performance of your services, but for additional information, see important system settings.

Linux settings

For a Linux environment, run the following commands:

  1. Disable memory paging and swapping performance on the host to improve performance.

    1. sudo swapoff -a
  2. Increase the number of memory maps available to OpenSearch.

    1. # Edit the sysctl config file
    2. sudo vi /etc/sysctl.conf
    3. # Add a line to define the desired value
    4. # or change the value if the key exists,
    5. # and then save your changes.
    6. vm.max_map_count=262144
    7. # Reload the kernel parameters using sysctl
    8. sudo sysctl -p
    9. # Verify that the change was applied by checking the value
    10. cat /proc/sys/vm/max_map_count

Windows settings

For Windows workloads using WSL through Docker Desktop, run the following commands in a terminal to set the vm.max_map_count:

  1. wsl -d docker-desktop
  2. sysctl -w vm.max_map_count=262144

Run OpenSearch in a Docker container

Official OpenSearch images are hosted on Docker Hub and Amazon ECR. If you want to inspect the images you can pull them individually using docker pull, such as in the following examples.

Docker Hub:

  1. docker pull opensearchproject/opensearch:2

copy

  1. docker pull opensearchproject/opensearch-dashboards:2

copy

Amazon ECR:

  1. docker pull public.ecr.aws/opensearchproject/opensearch:2

copy

  1. docker pull public.ecr.aws/opensearchproject/opensearch-dashboards:2

copy

To download a specific version of OpenSearch or OpenSearch Dashboards other than the latest available version, modify the image tag where it is referenced (either in the command line or in a Docker Compose file). For example, opensearchproject/opensearch:2.18.0 will pull OpenSearch version 2.18.0. To pull the latest version, use opensearchproject/opensearch:latest. Refer to the official image repositories for available versions.

Before continuing, you should verify that Docker is working correctly by deploying OpenSearch in a single container.

  1. Run the following command:

    1. # This command maps ports 9200 and 9600, sets the discovery type to "single-node" and requests the newest image of OpenSearch
    2. docker run -d -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" opensearchproject/opensearch:latest

    For OpenSearch 2.12 or greater, set a new custom admin password before installation using the following command:

    1. docker run -d -p 9200:9200 -p 9600:9600 -e "discovery.type=single-node" -e "OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password>" opensearchproject/opensearch:latest
  2. Send a request to port 9200. The default username and password are admin.

    1. curl https://localhost:9200 -ku admin:<custom-admin-password>

    copy

    • You should get a response that looks like this:

      1. {
      2. "name" : "a937e018cee5",
      3. "cluster_name" : "docker-cluster",
      4. "cluster_uuid" : "GLAjAG6bTeWErFUy_d-CLw",
      5. "version" : {
      6. "distribution" : "opensearch",
      7. "number" : <version>,
      8. "build_type" : <build-type>,
      9. "build_hash" : <build-hash>,
      10. "build_date" : <build-date>,
      11. "build_snapshot" : false,
      12. "lucene_version" : <lucene-version>,
      13. "minimum_wire_compatibility_version" : "7.10.0",
      14. "minimum_index_compatibility_version" : "7.0.0"
      15. },
      16. "tagline" : "The OpenSearch Project: https://opensearch.org/"
      17. }
  3. Before stopping the running container, display a list of all running containers and copy the container ID for the OpenSearch node you are testing. In the following example, the container ID is a937e018cee5:

    1. $ docker container ls
    2. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
    3. a937e018cee5 opensearchproject/opensearch:latest "./opensearch-docker…" 19 minutes ago Up 19 minutes 0.0.0.0:9200->9200/tcp, 9300/tcp, 0.0.0.0:9600->9600/tcp, 9650/tcp wonderful_boyd
  4. Stop the running container by passing the container ID to docker stop.

    1. docker stop <containerId>

    copy

Remember that docker container ls does not list stopped containers. If you would like to review stopped containers, use docker container ls -a. You can remove unneeded containers manually with docker container rm <containerId_1> <containerId_2> <containerId_3> [...] (pass all container IDs you wish to stop, separated by spaces), or if you want to remove all stopped containers, you can use the shorter command docker container prune.

Deploy an OpenSearch cluster using Docker Compose

Although it is technically possible to build an OpenSearch cluster by creating containers one command at a time, it is far easier to define your environment in a YAML file and let Docker Compose manage the cluster. The following section contains example YAML files that you can use to launch a predefined cluster with OpenSearch and OpenSearch Dashboards. These examples are useful for testing and development, but are not suitable for a production environment. If you don’t have prior experience using Docker Compose, you may wish to review the Docker Compose specification for guidance on syntax and formatting before making any changes to the dictionary structures in the examples.

The YAML file that defines the environment is referred to as a Docker Compose file. By default, docker-compose commands will first check your current directory for a file that matches any of the following names:

  • docker-compose.yml
  • docker-compose.yaml
  • compose.yml
  • compose.yaml

If none of those files exist in your current directory, the docker-compose command fails.

You can specify a custom file location and name when invoking docker-compose with the -f flag:

  1. # Use a relative or absolute path to the file.
  2. docker-compose -f /path/to/your-file.yml up

If this is your first time launching an OpenSearch cluster using Docker Compose, use the following example docker-compose.yml file. Save it in the home directory of your host and name it docker-compose.yml. This file creates a cluster that contains three containers: two containers running the OpenSearch service and a single container running OpenSearch Dashboards. These containers communicate over a bridge network called opensearch-net and use two volumes, one for each OpenSearch node. Because this file does not explicitly disable the demo security configuration, self-signed TLS certificates are installed and internal users with default names and passwords are created.

Setting a custom admin password

Starting with OpenSearch 2.12, a custom admin password is required to set up a demo security configuration. Do one of the following:

  • Before running docker-compose.yml, set a new custom admin password using the following command:

    1. export OPENSEARCH_INITIAL_ADMIN_PASSWORD=<custom-admin-password>

    copy

  • Create an .env file in the same folder as your docker-compose.yml file with the OPENSEARCH_INITIAL_ADMIN_PASSWORD and a strong password value.

Sample docker-compose.yml

  1. version: '3'
  2. services:
  3. opensearch-node1: # This is also the hostname of the container within the Docker network (i.e. https://opensearch-node1/)
  4. image: opensearchproject/opensearch:latest # Specifying the latest available image - modify if you want a specific version
  5. container_name: opensearch-node1
  6. environment:
  7. - cluster.name=opensearch-cluster # Name the cluster
  8. - node.name=opensearch-node1 # Name the node that will run in this container
  9. - discovery.seed_hosts=opensearch-node1,opensearch-node2 # Nodes to look for when discovering the cluster
  10. - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 # Nodes eligible to serve as cluster manager
  11. - bootstrap.memory_lock=true # Disable JVM heap memory swapping
  12. - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # Set min and max JVM heap sizes to at least 50% of system RAM
  13. - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD} # Sets the demo admin user password when using demo configuration, required for OpenSearch 2.12 and later
  14. ulimits:
  15. memlock:
  16. soft: -1 # Set memlock to unlimited (no soft or hard limit)
  17. hard: -1
  18. nofile:
  19. soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
  20. hard: 65536
  21. volumes:
  22. - opensearch-data1:/usr/share/opensearch/data # Creates volume called opensearch-data1 and mounts it to the container
  23. ports:
  24. - 9200:9200 # REST API
  25. - 9600:9600 # Performance Analyzer
  26. networks:
  27. - opensearch-net # All of the containers will join the same Docker bridge network
  28. opensearch-node2:
  29. image: opensearchproject/opensearch:latest # This should be the same image used for opensearch-node1 to avoid issues
  30. container_name: opensearch-node2
  31. environment:
  32. - cluster.name=opensearch-cluster
  33. - node.name=opensearch-node2
  34. - discovery.seed_hosts=opensearch-node1,opensearch-node2
  35. - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2
  36. - bootstrap.memory_lock=true
  37. - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m"
  38. - OPENSEARCH_INITIAL_ADMIN_PASSWORD=${OPENSEARCH_INITIAL_ADMIN_PASSWORD}
  39. ulimits:
  40. memlock:
  41. soft: -1
  42. hard: -1
  43. nofile:
  44. soft: 65536
  45. hard: 65536
  46. volumes:
  47. - opensearch-data2:/usr/share/opensearch/data
  48. networks:
  49. - opensearch-net
  50. opensearch-dashboards:
  51. image: opensearchproject/opensearch-dashboards:latest # Make sure the version of opensearch-dashboards matches the version of opensearch installed on other nodes
  52. container_name: opensearch-dashboards
  53. ports:
  54. - 5601:5601 # Map host port 5601 to container port 5601
  55. expose:
  56. - "5601" # Expose port 5601 for web access to OpenSearch Dashboards
  57. environment:
  58. OPENSEARCH_HOSTS: '["https://opensearch-node1:9200","https://opensearch-node2:9200"]' # Define the OpenSearch nodes that OpenSearch Dashboards will query
  59. networks:
  60. - opensearch-net
  61. volumes:
  62. opensearch-data1:
  63. opensearch-data2:
  64. networks:
  65. opensearch-net:

copy

If you override opensearch_dashboards.yml settings using environment variables in your compose file, use all uppercase letters and replace periods with underscores (for example, for opensearch.hosts, use OPENSEARCH_HOSTS). This behavior is inconsistent with overriding opensearch.yml settings, where the conversion is just a change to the assignment operator (for example, discovery.type: single-node in opensearch.yml is defined as discovery.type=single-node in docker-compose.yml).

From the home directory of your host (containing docker-compose.yml), create and start the containers in detached mode:

  1. docker-compose up -d

copy

Verify that the service containers started correctly:

  1. docker-compose ps

copy

If a container failed to start, you can review the service logs:

  1. # If you don't pass a service name, docker-compose will show you logs from all of the nodes
  2. docker-compose logs <serviceName>

copy

Verify access to OpenSearch Dashboards by connecting to http://localhost:5601 from a browser. The default username and password are admin. We do not recommend using this configuration on hosts that are accessible from the public internet until you have customized the security configuration of your deployment.

Remember that localhost cannot be accessed remotely. If you are deploying these containers to a remote host, then you will need to establish a network connection and replace localhost with the IP or DNS record corresponding to the host.

Stop the running containers in your cluster:

  1. docker-compose down

copy

docker-compose down will stop the running containers, but it will not remove the Docker volumes that exist on the host. If you don’t care about the contents of these volumes, use the -v option to delete all volumes, for example, docker-compose down -v.

Configure OpenSearch

Unlike the RPM distribution of OpenSearch, which requires a large amount of post-installation configuration, running OpenSearch clusters with Docker allows you to define the environment before the containers are even created. This is possible whether you use Docker or Docker Compose.

For example, take a look at the following command:

  1. docker run \
  2. -p 9200:9200 -p 9600:9600 \
  3. -e "discovery.type=single-node" \
  4. -v /path/to/custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml \
  5. opensearchproject/opensearch:latest

copy

By reviewing each part of the command, you can see that it:

  • Maps ports 9200 and 9600 (HOST_PORT:CONTAINER_PORT).
  • Sets discovery.type to single-node so that bootstrap checks don’t fail for this single-node deployment.
  • Uses the -v flag to pass a local file called custom-opensearch.yml to the container, replacing the opensearch.yml file included with the image.
  • Requests the opensearchproject/opensearch:latest image from Docker Hub.
  • Runs the container.

If you compare this command to the Sample docker-compose.yml file, you might notice some common settings, such as the port mappings and the image reference. The command, however, is only deploying a single container running OpenSearch and will not create a container for OpenSearch Dashboards. Furthermore, if you want to use custom TLS certificates, users, or roles, or define additional volumes and networks, then this “one-line” command rapidly grows to an impractical size. That is where the utility of Docker Compose becomes useful.

When you build your OpenSearch cluster with Docker Compose you might find it easier to pass custom configuration files from your host to the container, as opposed to enumerating every individual setting in docker-compose.yml. Similar to how the example docker run command mounted a volume from the host to the container using the -v flag, compose files can specify volumes to mount as a sub-option to the corresponding service. The following truncated YAML file demonstrates how to mount a file or directory to the container. Refer to the official Docker documentation on volumes for comprehensive information about volume usage and syntax.

  1. services:
  2. opensearch-node1:
  3. volumes:
  4. - opensearch-data1:/usr/share/opensearch/data
  5. - ./custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml
  6. opensearch-node2:
  7. volumes:
  8. - opensearch-data2:/usr/share/opensearch/data
  9. - ./custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml
  10. opensearch-dashboards:
  11. volumes:
  12. - ./custom-opensearch_dashboards.yml:/usr/share/opensearch-dashboards/config/opensearch_dashboards.yml

copy

Sample Docker Compose file for development

If you want to build your own compose file from an example, review the following sample docker-compose.yml file. This sample file creates two OpenSearch nodes and one OpenSearch Dashboards node with the Security plugin disabled. You can use this sample file as a starting point while reviewing Configuring basic security settings.

  1. version: '3'
  2. services:
  3. opensearch-node1:
  4. image: opensearchproject/opensearch:latest
  5. container_name: opensearch-node1
  6. environment:
  7. - cluster.name=opensearch-cluster # Name the cluster
  8. - node.name=opensearch-node1 # Name the node that will run in this container
  9. - discovery.seed_hosts=opensearch-node1,opensearch-node2 # Nodes to look for when discovering the cluster
  10. - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 # Nodes eligibile to serve as cluster manager
  11. - bootstrap.memory_lock=true # Disable JVM heap memory swapping
  12. - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # Set min and max JVM heap sizes to at least 50% of system RAM
  13. - "DISABLE_INSTALL_DEMO_CONFIG=true" # Prevents execution of bundled demo script which installs demo certificates and security configurations to OpenSearch
  14. - "DISABLE_SECURITY_PLUGIN=true" # Disables Security plugin
  15. ulimits:
  16. memlock:
  17. soft: -1 # Set memlock to unlimited (no soft or hard limit)
  18. hard: -1
  19. nofile:
  20. soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
  21. hard: 65536
  22. volumes:
  23. - opensearch-data1:/usr/share/opensearch/data # Creates volume called opensearch-data1 and mounts it to the container
  24. ports:
  25. - 9200:9200 # REST API
  26. - 9600:9600 # Performance Analyzer
  27. networks:
  28. - opensearch-net # All of the containers will join the same Docker bridge network
  29. opensearch-node2:
  30. image: opensearchproject/opensearch:latest
  31. container_name: opensearch-node2
  32. environment:
  33. - cluster.name=opensearch-cluster # Name the cluster
  34. - node.name=opensearch-node2 # Name the node that will run in this container
  35. - discovery.seed_hosts=opensearch-node1,opensearch-node2 # Nodes to look for when discovering the cluster
  36. - cluster.initial_cluster_manager_nodes=opensearch-node1,opensearch-node2 # Nodes eligibile to serve as cluster manager
  37. - bootstrap.memory_lock=true # Disable JVM heap memory swapping
  38. - "OPENSEARCH_JAVA_OPTS=-Xms512m -Xmx512m" # Set min and max JVM heap sizes to at least 50% of system RAM
  39. - "DISABLE_INSTALL_DEMO_CONFIG=true" # Prevents execution of bundled demo script which installs demo certificates and security configurations to OpenSearch
  40. - "DISABLE_SECURITY_PLUGIN=true" # Disables Security plugin
  41. ulimits:
  42. memlock:
  43. soft: -1 # Set memlock to unlimited (no soft or hard limit)
  44. hard: -1
  45. nofile:
  46. soft: 65536 # Maximum number of open files for the opensearch user - set to at least 65536
  47. hard: 65536
  48. volumes:
  49. - opensearch-data2:/usr/share/opensearch/data # Creates volume called opensearch-data2 and mounts it to the container
  50. networks:
  51. - opensearch-net # All of the containers will join the same Docker bridge network
  52. opensearch-dashboards:
  53. image: opensearchproject/opensearch-dashboards:latest
  54. container_name: opensearch-dashboards
  55. ports:
  56. - 5601:5601 # Map host port 5601 to container port 5601
  57. expose:
  58. - "5601" # Expose port 5601 for web access to OpenSearch Dashboards
  59. environment:
  60. - 'OPENSEARCH_HOSTS=["http://opensearch-node1:9200","http://opensearch-node2:9200"]'
  61. - "DISABLE_SECURITY_DASHBOARDS_PLUGIN=true" # disables security dashboards plugin in OpenSearch Dashboards
  62. networks:
  63. - opensearch-net
  64. volumes:
  65. opensearch-data1:
  66. opensearch-data2:
  67. networks:
  68. opensearch-net:

copy

Configuring basic security settings

Before making your OpenSearch cluster available to external hosts, it’s a good idea to review the deployment’s security configuration. You may recall from the first Sample docker-compose.yml file that, unless disabled by setting DISABLE_SECURITY_PLUGIN=true, a bundled script will apply a default demo security configuration to the nodes in the cluster. Because this configuration is used for demo purposes, the default usernames and passwords are known. For that reason, we recommend that you create your own security configuration files and use volumes to pass these files to the containers. For specific guidance on OpenSearch security settings, see Security configuration.

To use your own certificates in your configuration, add all of the necessary certificates to the volumes section of the compose file:

  1. volumes:
  2. - ./root-ca.pem:/usr/share/opensearch/config/root-ca.pem
  3. - ./admin.pem:/usr/share/opensearch/config/admin.pem
  4. - ./admin-key.pem:/usr/share/opensearch/config/admin-key.pem
  5. - ./node1.pem:/usr/share/opensearch/config/node1.pem
  6. - ./node1-key.pem:/usr/share/opensearch/config/node1-key.pem

copy

When you add TLS certificates to your OpenSearch nodes with Docker Compose volumes, you should also include a custom opensearch.yml file that defines those certificates. For example:

  1. volumes:
  2. - ./root-ca.pem:/usr/share/opensearch/config/root-ca.pem
  3. - ./admin.pem:/usr/share/opensearch/config/admin.pem
  4. - ./admin-key.pem:/usr/share/opensearch/config/admin-key.pem
  5. - ./node1.pem:/usr/share/opensearch/config/node1.pem
  6. - ./node1-key.pem:/usr/share/opensearch/config/node1-key.pem
  7. - ./custom-opensearch.yml:/usr/share/opensearch/config/opensearch.yml

copy

Remember that the certificates you specify in your compose file must be the same as the certificates defined in your custom opensearch.yml file. You should replace the root, admin, and node certificates with your own. For more information see Configure TLS certificates.

  1. plugins.security.ssl.transport.pemcert_filepath: node1.pem
  2. plugins.security.ssl.transport.pemkey_filepath: node1-key.pem
  3. plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
  4. plugins.security.ssl.http.pemcert_filepath: node1.pem
  5. plugins.security.ssl.http.pemkey_filepath: node1-key.pem
  6. plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
  7. plugins.security.authcz.admin_dn:
  8. - CN=admin,OU=SSL,O=Test,L=Test,C=DE

copy

After configuring security settings, your custom opensearch.yml file might look something like the following example, which adds TLS certificates and the distinguished name (DN) of the admin certificate, defines a few permissions, and enables verbose audit logging:

  1. plugins.security.ssl.transport.pemcert_filepath: node1.pem
  2. plugins.security.ssl.transport.pemkey_filepath: node1-key.pem
  3. plugins.security.ssl.transport.pemtrustedcas_filepath: root-ca.pem
  4. plugins.security.ssl.transport.enforce_hostname_verification: false
  5. plugins.security.ssl.http.enabled: true
  6. plugins.security.ssl.http.pemcert_filepath: node1.pem
  7. plugins.security.ssl.http.pemkey_filepath: node1-key.pem
  8. plugins.security.ssl.http.pemtrustedcas_filepath: root-ca.pem
  9. plugins.security.allow_default_init_securityindex: true
  10. plugins.security.authcz.admin_dn:
  11. - CN=A,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA
  12. plugins.security.nodes_dn:
  13. - 'CN=N,OU=UNIT,O=ORG,L=TORONTO,ST=ONTARIO,C=CA'
  14. plugins.security.audit.type: internal_opensearch
  15. plugins.security.enable_snapshot_restore_privilege: true
  16. plugins.security.check_snapshot_restore_write_privileges: true
  17. plugins.security.restapi.roles_enabled: ["all_access", "security_rest_api_access"]
  18. cluster.routing.allocation.disk.threshold_enabled: false
  19. opendistro_security.audit.config.disabled_rest_categories: NONE
  20. opendistro_security.audit.config.disabled_transport_categories: NONE

copy

For a full list of settings, see Security.

Use the same process to specify a Backend configuration in /usr/share/opensearch/config/opensearch-security/config.yml as well as new internal users, roles, mappings, action groups, and tenants in their respective YAML files.

After replacing the certificates and creating your own internal users, roles, mappings, action groups, and tenants, use Docker Compose to start the cluster:

  1. docker-compose up -d

copy

Working with plugins

To use the OpenSearch image with a custom plugin, you must first create a Dockerfile. Review the official Docker documentation for information about creating a Dockerfile.

  1. FROM opensearchproject/opensearch:latest
  2. RUN /usr/share/opensearch/bin/opensearch-plugin install --batch <pluginId>

Then run the following commands:

  1. # Build an image from a Dockerfile
  2. docker build --tag=opensearch-custom-plugin .
  3. # Start the container from the custom image
  4. docker run -p 9200:9200 -p 9600:9600 -v /usr/share/opensearch/data opensearch-custom-plugin

Alternatively, you might want to remove a plugin from an image before deploying it. This example Dockerfile removes the Security plugin:

  1. FROM opensearchproject/opensearch:latest
  2. RUN /usr/share/opensearch/bin/opensearch-plugin remove opensearch-security

copy

You can also use a Dockerfile to pass your own certificates for use with the Security plugin:

  1. FROM opensearchproject/opensearch:latest
  2. COPY --chown=opensearch:opensearch opensearch.yml /usr/share/opensearch/config/
  3. COPY --chown=opensearch:opensearch my-key-file.pem /usr/share/opensearch/config/
  4. COPY --chown=opensearch:opensearch my-certificate-chain.pem /usr/share/opensearch/config/
  5. COPY --chown=opensearch:opensearch my-root-cas.pem /usr/share/opensearch/config/

copy