ELK Stack — Installation Exercises
Practice Exercises — Installation
Test your installation and troubleshooting skills with these hands-on exercises.
Exercise 1 — Verify the Full Stack
Question: Write the curl commands to verify that Elasticsearch, Kibana, and Logstash are all running correctly. What response do you expect from each?
Show Solution
Elasticsearch:
$ curl -u elastic:changeme123 http://localhost:9200
Expected: JSON with "tagline" : "You Know, for Search" and version info.
Elasticsearch Cluster Health:
$ curl -u elastic:changeme123 http://localhost:9200/_cluster/health?pretty
Expected: JSON with "status" : "green" or "yellow".
Kibana:
$ curl -s http://localhost:5601/api/status | python3 -m json.tool | grep level
Expected: "level": "available"
Logstash:
$ curl -s http://localhost:9600 | python3 -m json.tool | grep status
Expected: "status": "green"
Filebeat (check indirectly via Elasticsearch indices):
$ curl -u elastic:changeme123 "http://localhost:9200/_cat/indices?v" | grep -E "filebeat|logs"
Expected: At least one index with document count > 0.
Exercise 2 — Change the Elasticsearch Cluster Name
Question: Using the Docker Compose setup, change the Elasticsearch cluster name from elk-learning to my-production-cluster. Verify the change took effect.
Show Solution
Step 1 — Edit the .env file:
$ nano ~/elk-stack/.env
Change:
CLUSTER_NAME=my-production-cluster
Step 2 — Restart Elasticsearch:
$ cd ~/elk-stack
$ docker compose down
$ docker compose up -d
Step 3 — Verify:
$ curl -u elastic:changeme123 http://localhost:9200 | python3 -m json.tool | grep cluster_name
Expected:
"cluster_name": "my-production-cluster"
Exercise 3 — Troubleshoot a Connection Issue
Question: After starting the Docker Compose stack, Kibana shows “Kibana server is not ready yet.” List all the troubleshooting steps you would follow.
Show Solution
Step 1 — Check if all containers are running:
$ docker compose ps
Look for any containers that are not in “Up” or “Up (healthy)” state.
Step 2 — Check Elasticsearch health (Kibana depends on it):
$ curl -u elastic:changeme123 http://localhost:9200/_cluster/health?pretty
If this fails, Elasticsearch is down — Kibana can’t connect.
Step 3 — Check Kibana logs:
$ docker compose logs -f kibana
Look for error messages like:
Unable to retrieve version information from Elasticsearch nodes— wrong URL or credentialsECONNREFUSED— Elasticsearch not reachablesecurity_exception— wrong username/password
Step 4 — Verify the kibana_system password:
$ curl -u kibana_system:changeme123 http://localhost:9200
If this returns 401, the password is wrong. Reset it:
$ curl -X POST -u elastic:changeme123 \
"http://localhost:9200/_security/user/kibana_system/_password" \
-H "Content-Type: application/json" \
-d '{"password": "changeme123"}'
Step 5 — Check Docker resource limits:
$ docker stats --no-stream
If Elasticsearch is using close to its memory limit, it may be crashing. Increase ES_MEM_LIMIT in .env.
Step 6 — Restart Kibana after fixes:
$ docker compose restart kibana
Exercise 4 — Add a New Log Source
Question: You have a custom application that writes JSON logs to /var/log/myapp/app.log. Modify the Filebeat configuration to collect these logs and add a field log_type: myapp. Show the configuration changes.
Show Solution
Step 1 — Update filebeat/filebeat.yml:
filebeat.inputs:
- type: filestream
id: sample-nginx
enabled: true
paths:
- /var/log/sample/access.log
fields:
log_type: nginx
fields_under_root: true
- type: filestream
id: myapp-logs
enabled: true
paths:
- /var/log/myapp/app.log
fields:
log_type: myapp
fields_under_root: true
parsers:
- ndjson:
target: ""
add_error_key: true
output.logstash:
hosts: ["logstash:5044"]
processors:
- add_host_metadata:
when.not.contains.tags: forwarded
- add_docker_metadata: ~
Step 2 — Mount the log directory in docker-compose.yml:
Add under the filebeat service volumes:
volumes:
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- ./sample-logs/:/var/log/sample/:ro
- /var/log/myapp/:/var/log/myapp/:ro
Step 3 — Restart Filebeat:
$ docker compose restart filebeat
Key points:
- Each
filestreaminput needs a uniqueid - The
ndjsonparser tells Filebeat the logs are JSON formatted fields_under_root: trueputs thelog_typefield at the root level (not nested underfields)
Exercise 5 — Monitor Docker Container Logs
Question: Configure Filebeat to collect logs from all Docker containers running on the host (not just static log files). Show the Filebeat input configuration.
Show Solution
Option 1 — Using Docker container paths:
filebeat.inputs:
- type: container
paths:
- /var/lib/docker/containers/*/*.log
processors:
- add_docker_metadata:
host: "unix:///var/run/docker.sock"
output.elasticsearch:
hosts: ["http://elasticsearch:9200"]
username: "elastic"
password: "changeme123"
Option 2 — Using Filebeat autodiscover:
filebeat.autodiscover:
providers:
- type: docker
hints.enabled: true
output.elasticsearch:
hosts: ["http://elasticsearch:9200"]
username: "elastic"
password: "changeme123"
Docker Compose volumes needed:
volumes:
- ./filebeat/filebeat.yml:/usr/share/filebeat/filebeat.yml:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
Key points:
- Docker writes container logs to
/var/lib/docker/containers/<container-id>/<container-id>-json.log - The
add_docker_metadataprocessor enriches events with container name, image, and labels - Autodiscover dynamically detects new containers — no configuration changes needed when containers start/stop
- The Docker socket (
/var/run/docker.sock) is required for metadata enrichment
What’s Next?
Great work! You now have the entire ELK Stack running and understand how to:
- ✅ Install Elasticsearch, Kibana, Logstash, and Filebeat
- ✅ Use Docker Compose for quick setup
- ✅ Troubleshoot common installation issues
- ✅ Configure multiple log sources
Next up: Chapter 3 — Elasticsearch Fundamentals — where you’ll learn about indices, documents, mappings, and the REST API.