This setup demonstrates a complete logging pipeline using Docker Compose with:
- Example Node.js application (generates logs to stdout)
- Fluent Bit (log collector and forwarder)
- OpenSearch (search and analytics engine)
- OpenSearch Dashboards (visualization UI)
If you need help, please feel free to contact us here.
It helps you to:
- Quick Setup Opensearch so that you can explore the tool in a mini-production like environment
- Understand the architecture required to ingest logs into Opensearch from an app container
For a more visual walkthrough, you can read the article: Quick Start Guide to OpenSearch Log Ingestion.
- Docker and Docker Compose installed
- At least 4GB of available RAM (OpenSearch requires memory)
- Ports available: 3000, 5601, 9200, 24224
.
├── docker-compose.yml
├── app/
│ ├── index.js
│ └── package.json
└── fluent-bit/
├── fluent-bit.conf
└── parsers.conf
cd app
npm install
cd ..docker-compose up -dThis will start:
- OpenSearch on port 9200
- OpenSearch Dashboards on port 5601
- Fluent Bit on port 24224
- Example app on port 3000
# Check all containers are up
docker-compose ps
# Check OpenSearch health
curl http://localhost:9200/_cluster/health?pretty
# View Fluent Bit logs
docker-compose logs -f fluent-bitPress Ctrl+C twice to exit logs view.
# View example app logs
docker-compose logs -f example-appPress Ctrl+C twice to exit logs view.
The example app exposes several endpoints:
# Generate INFO logs
curl http://localhost:3000/
# Generate ERROR logs
curl http://localhost:3000/error
# Generate WARNING logs
curl http://localhost:3000/warnYou can use these endpoints to create more errors or warnings to test out OpenSearch.
The app also generates periodic logs every 5 seconds automatically.
- Open your browser and go to: http://localhost:5601
- Wait for OpenSearch Dashboards to initialize (may take 1-2 minutes)
- Click on "Hamburger menu" (☰) → Dashboard Management → Index Pattern.
- Click "Create index pattern"
- Enter index pattern:
app-logs-* - Click "Next step"
- Select time field:
@timestamp - Click "Create index pattern"
This process tells Dashboards which indices to query and how to interpret their fields. It's just a UI configuration layer - it doesn't move or store data, just defines what to search and which field is the timestamp.
OpenSearch node app has already indexed the logs.
- Click on "Hamburger menu" (☰) → Discover
- You should see your application logs appearing in real-time
- You can filter by fields like:
level(info, error, warn, debug)messageservicemethod(for HTTP requests)
- Try searching for keywords like
debug,infoandwarn.
# Stop all services
docker-compose down
# Stop and remove volumes (deletes all logs)
docker-compose down -vExample App (stdout)
↓
Fluent Bit (collector)
↓
OpenSearch (storage)
↓
Dashboards (visualization)
- Example App: Writes JSON-formatted logs to stdout
- Fluent Bit:
- Receives logs via Forward protocol (Docker logging driver)
- Parses JSON logs
- Forwards to OpenSearch with Logstash format
- OpenSearch: Indexes logs for searching and analysis
- Dashboards: Provides UI for querying and visualizing logs
Fluent Bit (fluent-bit.conf):
- INPUT: Listens on port 24224 for log forwarding
- FILTER: Parses JSON logs from Docker
- OUTPUT: Sends to OpenSearch with daily indices (app-logs-YYYY.MM.DD)
Docker Logging:
- Example app uses
fluentdlogging driver - Sends all stdout/stderr to Fluent Bit
OpenSearch:
- Security disabled for simplicity (don't use in production!)
- Single-node setup
- Stores data in Docker volume
For production use, you should:
- Enable OpenSearch security (TLS, authentication)
- Use proper resource limits in docker-compose.yml
- Configure log retention policies (Index Lifecycle Management)
- Set up multi-node OpenSearch cluster for high availability
- Use secrets management for credentials
- Configure proper log rotation in Fluent Bit
- Add monitoring for the logging pipeline itself
- Secure Fluent Bit with TLS when forwarding logs
-
Check Fluent Bit is receiving logs:
docker-compose logs fluent-bit
-
Check if indices are being created:
curl http://localhost:9200/_cat/indices?v -
Restart the example app:
docker-compose restart example-app
Wait 1-2 minutes after starting services. OpenSearch Dashboards needs time to initialize.
On Linux, you may need to increase vm.max_map_count:
sudo sysctl -w vm.max_map_count=262144To make it permanent, add to /etc/sysctl.conf:
vm.max_map_count=262144
Edit app/index.js to change the log structure:
console.log(JSON.stringify({
timestamp: new Date().toISOString(),
level: 'info',
// Add your custom fields here
customField: 'value'
}));Edit fluent-bit/fluent-bit.conf to add more input sources:
[INPUT]
Name tail
Path /var/log/*.log
Parser jsonYou can create index templates to control mappings and settings:
curl -X PUT "http://localhost:9200/_index_template/app-logs-template" \
-H 'Content-Type: application/json' \
-d '{
"index_patterns": ["app-logs-*"],
"template": {
"settings": {
"number_of_shards": 1,
"number_of_replicas": 0
}
}
}'