# The start-local script disables TLS, the trial reverts to Basic, and two major lines ship together

> Elasticsearch is Elastic's distributed search and analytics engine, a Java codebase built with Gradle and published as both an 8.x maintenance line and a 9.x line. The setup instructions in this repository are the interesting part: a single curl pipe that starts Elasticsearch and Kibana in Docker, marked by the project itself as unsuitable for production, with HTTPS disabled and a trial license that reverts to a smaller tier after a month.

**elastic/elasticsearch** — Elasticsearch is a distributed, RESTful search and analytics engine and vector store for near-real-time full-text and vector search, logs, and metrics at scale.

- Repository: https://github.com/elastic/elasticsearch
- Website: https://www.elastic.co/products/elasticsearch
- Stars: 78,002 · Forks: 26,091
- Language: Java
- License: not declared
- Published: 2026-08-04 · Updated: 2026-08-18 · Language: en
- Canonical page: https://hysenlabs.com/projects/elastic-elasticsearch

## start-local is a curl pipe that the project marks as not for production

The entire local setup is one line, and it pipes a remote script straight into a shell:

```bash
curl -fsSL https://elastic.co/start-local | sh
```

The script creates an `elastic-start-local` folder with configuration files and starts Elasticsearch and Kibana through Docker. Elasticsearch answers on http://localhost:9200 and Kibana on http://localhost:5601. A random password is generated for the `elastic` user, printed at the end of installation and written into a `.env` file, and an API key is stored there as `ES_LOCAL_API_KEY`.

What this setup cannot do is be a deployment. The text carries a warning that the instructions are not for production deployments and that the setup is for local development and testing only, and a separate caution records that HTTPS is disabled, that Basic authentication is used, and that both services are reachable only through `localhost`. Three of the security properties you need in production are absent by design, and nothing in the command tells you that before you run it.

## The install brings up Kibana on 5601 whether you asked for it or not

The script starts two services, and the second one is a full interface rather than a debugging aid. You get Elasticsearch on 9200 and Kibana on 5601, which is the component that holds the developer console: you reach it through Kibana, then Management and Dev Tools, and from there you can post documents without touching curl at all.

That arrangement has a consequence for anyone who only wanted the search engine. The convenient way to explore a cluster is the console, and the console lives in the other container, so the interface you will use most is the one you did not install deliberately. Both come up in the same command and neither is separable from it without going back to the compose file yourself.

Connection details then split across two mechanisms, which is worth knowing before you script against it. The API key sits in `.env` as `ES_LOCAL_API_KEY` and is used as an `ApiKey` header, while the password is a separate value that you export yourself as `ES_LOCAL_PASSWORD` and pass with basic auth. Checking the cluster is two lines, sourcing the environment first:

```bash
source .env
curl $ES_LOCAL_URL -H "Authorization: ApiKey ${ES_LOCAL_API_KEY}"
```

Choosing between them is not cosmetic. The key is what the script generated for you; the password is what a client library expects when you hand it a username and password pair.

## The trial reverts to Basic, and the repository resolves no single license

The local setup ships with a one-month trial licence that includes all Elastic features. After the trial period the licence reverts to what the text calls Free and open - Basic. That is the whole licensing story in the setup instructions, and it is a story about a clock rather than about a capability list.

The consequence is that what you evaluate is not what you run. A feature that works on day one can be absent on day thirty-one, with no code change on your side, and the only signal is the tier change. Anyone building an internal evaluation has to record which features were demonstrated under the trial, because that list is the list that has to be re-checked against Basic rather than a list of things already known to work.

The repository itself is not a clean answer either. The tree carries LICENSE.txt, NOTICE.txt and a licenses directory, while the repository metadata does not resolve a single licence name for the project. So neither the trial terms nor the source licensing can be read off this repository in one place, and both matter before a self-managed deployment.

## Two major lines shipped in the same week

The recent release list shows two tracks moving at once. Version v8.19.22 was published on 2026-09-23, and v9.5.4 and v9.4.7 were both published on 2026-09-15, the same day. The last push to the default branch was 2026-09-26, and the repository is not archived.

So an 8.x maintenance line and two separate 9.x patch levels all landed inside eight days, and they are not the same upgrade. v9.4.7 and v9.5.4 are different minor tracks, which means the choice between them is a decision rather than a matter of taking the newest number.

For a team picking a version, the tree explains why that choice is deliberate rather than incidental. There is a REST_API_COMPATIBILITY.md at the top level, a branches.json, a `.backportrc.json` for backports, renovate.json for dependency updates and updatecli-compose.yaml. The repository is structured for maintaining more than one supported line at a time, so the release pattern is a policy, not noise. It also means a client library pinned to one major line is not automatically compatible with the other.

## A PUT that creates the index turns a typo into an empty index

Indexing is where the behaviour surprises people. Sending a document to an index that does not exist creates it:

```
POST /customer/_doc/1
{
  "firstname": "Jennifer",
  "lastname": "Walters"
}
```

That request creates the `customer` index if it is missing, stores a document with the ID 1, and indexes the two fields. Creating an index explicitly works the same way, as a PUT with a Content-Type header and no body:

```bash
curl -u elastic:$ES_LOCAL_PASSWORD \
  -X PUT \
  http://localhost:9200/my-new-index \
  -H 'Content-Type: application/json'
```

The convenience is the hazard. A mistyped index name in a write path creates a second empty index rather than failing, and the mapping that gets created is one nobody designed, inferred from the first document that arrives. Timestamped data has a related wrinkle: for logs and metrics you are pointed at a data stream made up of multiple auto-generated backing indices, so the physical index names are not yours to choose and cannot be treated as stable identifiers.

## The setup instructions are replicated, and the source of truth is another repository

The local setup section carries a comment block explaining its own duplication. It states that the content is replicated in the Elasticsearch repo, names `run-elasticsearch-locally.asciidoc` as the other copy, instructs that both files be kept in sync, and then says that https://github.com/elastic/start-local is the source of truth. The content is written in AsciiDoc rather than Markdown, which is why the command blocks are delimited rather than fenced.

The practical effect is that the one procedure a new user is most likely to need exists in at least three places, and the copy most likely to change lives in a different repository entirely. A reader who finds a step wrong has no way to tell from this repository alone whether the copy here is stale or the copy elsewhere is.

The wrapper URLs follow the same pattern. Connection details are given as the fixed pair http://localhost:9200 and the `elastic` username, and the only documented way to change the backend host is the environment variables the frontend reads. Nothing in the setup section explains how to point a client at a remote cluster instead, so anyone moving past the local stack is reading the product documentation rather than this repository.

## This is a Gradle monorepo with a wrapper, not a clone and run

The repository layout is the build. There is a `gradlew` and `gradlew.bat` wrapper, `build.gradle`, `settings.gradle` and a `gradle` directory at the top, and then module trees: `modules`, `libs`, `plugins`, `client`, `distribution`, `server`, `benchmarks`, `qa`, `dev-tools` and an `x-pack` directory. Continuous integration lives in `.buildkite`, and the tree also carries TESTING.asciidoc, BUILDING.md, CONTRIBUTING.md, TRACING.md, a Vagrantfile and both AGENTS.md and CLAUDE.md.

No build command appears in the setup instructions, and this repository does not document one, so the place to look is BUILDING.md rather than any guess at a Gradle invocation. That is a reasonable arrangement for a project this size, but it does mean the cost of building from source is not visible from the front door.

The same applies to the API surface. A `rest-api-spec` directory at the top level is where the HTTP contract is defined, and REST_API_COMPATIBILITY.md tracks it across versions, which is the file to read before assuming a client from one line will talk to a cluster on another. For evaluation, none of this is needed. For anyone committing to the engine, it is the difference between a dependency with a release cadence and a repository with a build system.

## Conclusion

Elasticsearch suits a team evaluating search, vector search or log analytics who wants the real engine rather than a hosted trial, because the local stack is one command and the REST surface is plain HTTP. It does not suit anyone copying that command into production, since the project states outright that the setup is not for production deployments, HTTPS is off, and Kibana comes along whether or not you planned for it. Before anything else, work out which of the two major lines you are targeting, since an 8.19 patch and two 9.x patches were published in the same week, and check what your licence tier actually grants after the one-month trial ends, because features available during evaluation are not features you can plan a deployment around.

## FAQ

### Does Elasticsearch is free?

The local setup described here comes with a one-month trial licence that includes all Elastic features, and after the trial period the licence reverts to what the documentation calls Free and open - Basic. So the answer depends on which tier you are on and when, rather than being a flat yes or no. The repository itself ships LICENSE.txt, NOTICE.txt and a licenses directory, while its metadata does not resolve a single licence name.

### how to install elasticsearch

For local work, the documented path is a single command that pipes a script into a shell and starts Elasticsearch and Kibana in Docker, creating an elastic-start-local folder. Elasticsearch is then on http://localhost:9200 and Kibana on http://localhost:5601. A random password for the elastic user and an API key called ES_LOCAL_API_KEY are written to a .env file in that folder.

### how to install elasticsearch on windows

The prerequisites call for Docker Desktop, and on Microsoft Windows they also call for the Windows Subsystem for Linux. The local setup is then the same script as on other systems, running Elasticsearch on port 9200 and Kibana on port 5601, both bound to localhost with HTTPS disabled.

### how to use elasticsearch in python

Use the Python elasticsearch client with basic auth against the local endpoint. The connection details are the http://localhost:9200 endpoint, the username elastic, and the password held in the ES_LOCAL_PASSWORD environment variable, which the sample code reads with os.getenv and passes to the client as basic_auth. Calling client.info() is the check that the connection works.

### Is Elasticsearch SQL or NoSQL?

You index data by sending JSON objects, described as documents, through the REST APIs, and Elasticsearch stores and indexes them. For timestamped data such as logs and metrics you are pointed at a data stream made up of multiple auto-generated backing indices rather than a single index you name yourself. A new document is available immediately from any node in the cluster.

### how to use elasticsearch api key

The local setup generates an API key and stores it in the .env file as ES_LOCAL_API_KEY. You check the connection by sourcing that file and sending it as an ApiKey header, which is a different mechanism from the basic auth path that uses the elastic username and ES_LOCAL_PASSWORD. Use the key when a client wants an ApiKey credential and basic auth when it wants a username and password pair.

## Sources

- [Official documentation](https://www.elastic.co/products/elasticsearch)
- [Official README](https://github.com/elastic/elasticsearch#readme)
- [Project repository](https://github.com/elastic/elasticsearch)
- [Release notes](https://github.com/elastic/elasticsearch/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/elastic-elasticsearch
