Wazuh with Docker: Standalone Setup for Agents, Log Aggregation, Alerts, and Notifications
Wazuh with Docker: Standalone Setup for Agents, Log Aggregation, Alerts, and Notifications
Overview
This is a standalone Wazuh setup guide using Docker. It is designed for readers who want Wazuh as a dedicated SIEM/log platform whether they run a home lab, a cloud VM, or a small standalone environment.
This walkthrough covers:
- single-node Wazuh deployment with Docker
- Linux and Windows agent enrollment
- centralized log aggregation (agent logs and syslog sources)
- creating custom alert rules
- alert notifications via Slack and email
- operational checks and common troubleshooting
Architecture
Single-node Wazuh Docker deployment:
wazuh.manager: rule engine, decoders, agent manager, APIwazuh.indexer: indexed storage (OpenSearch)wazuh.dashboard: web interface
Core ports used:
| Port | Protocol | Purpose |
|---|---|---|
| 443 | TCP | Wazuh Dashboard |
| 1514 | TCP/UDP | Agent event channel |
| 1515 | TCP | Agent enrollment/auth |
| 514 | UDP (optional) | Syslog ingestion |
Ingestion Pipeline Diagram
flowchart LR
subgraph Sources[Ingestion Sources]
LNX[Linux Endpoints\nWazuh Agent]
WIN[Windows Endpoints\nWazuh Agent]
FW[OPNsense Firewall\nRemote Syslog]
SW[Switch/Router Logs\nSyslog]
APP[Servers/Apps\nCustom Logs]
end
subgraph WazuhStack[Wazuh Docker Stack]
MGR[wazuh.manager\nDecode + Correlate + Rules]
IDX[wazuh.indexer\nOpenSearch Storage]
DSH[wazuh.dashboard\nSearch + Visualize + Alert Triage]
end
subgraph Notify[Notification Targets]
SLK[Slack Webhook]
EMT[Email / SMTP]
SOAR[SOAR / Webhook Automation]
end
LNX -->|Agent Events\n1514 TCP/UDP| MGR
WIN -->|Agent Events\n1514 TCP/UDP| MGR
FW -->|Syslog\n514 UDP| MGR
SW -->|Syslog\n514 UDP| MGR
APP -->|Agent Log Collection\nor Syslog| MGR
MGR -->|Parsed Events + Alerts| IDX
IDX -->|Indexed Data| DSH
MGR -->|Rule Matches| DSH
MGR -->|High-Severity Alerts| SLK
MGR -->|Email Alerts| EMT
MGR -->|Optional Integration| SOAR
Data path summary:
- endpoints and network devices feed logs/events into
wazuh.manager - manager applies decoders and rule logic, then stores events in
wazuh.indexer wazuh.dashboardreads indexed data for search, dashboards, and investigations- alert integrations (Slack/email/webhook) are triggered from manager rule matches
Prerequisites
Minimum recommended host resources:
- 4 vCPU
- 8 GB RAM (16 GB preferred)
- 80 GB SSD (more if long log retention)
- Ubuntu 22.04/24.04 or Debian-based Linux with Docker support
Install Docker Engine and Compose plugin (official repo preferred):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sudo apt update
sudo apt install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) \
signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu \
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io \
docker-buildx-plugin docker-compose-plugin
Add current user to docker group and refresh session:
1
2
sudo usermod -aG docker $USER
newgrp docker
Verify:
1
2
docker --version
docker compose version
Set required kernel parameter for Wazuh Indexer/OpenSearch:
1
2
sudo sysctl -w vm.max_map_count=262144
echo "vm.max_map_count=262144" | sudo tee -a /etc/sysctl.conf
Step 1: Deploy Wazuh Docker Stack
Use the official single-node stack from the Wazuh Docker repository.
1
2
3
4
mkdir -p /opt/wazuh && cd /opt/wazuh
curl -sO https://raw.githubusercontent.com/wazuh/wazuh-docker/v4.9.0/single-node/docker-compose.yml
curl -sO https://raw.githubusercontent.com/wazuh/wazuh-docker/v4.9.0/single-node/generate-indexer-certs.yml
Generate certs required by indexer:
1
docker compose -f generate-indexer-certs.yml run --rm generator
Start stack:
1
docker compose up -d
Check status:
1
docker compose ps
Expected containers:
wazuh.managerwazuh.indexerwazuh.dashboard
Access dashboard:
- URL:
https://<wazuh-host-ip> - Default user:
admin - Default password:
SecretPassword
Change admin password immediately in Dashboard:
- Security -> Internal users -> admin -> Change password
Step 2: Agent Setup (Linux and Windows)
Linux agent setup
On Linux endpoint:
1
2
3
4
5
6
7
8
9
curl -s https://packages.wazuh.com/key/GPG-KEY-WAZUH | \
gpg --no-default-keyring --keyring gnupg-ring:/usr/share/keyrings/wazuh.gpg --import
chmod 644 /usr/share/keyrings/wazuh.gpg
echo "deb [signed-by=/usr/share/keyrings/wazuh.gpg] https://packages.wazuh.com/4.x/apt/ stable main" | \
sudo tee /etc/apt/sources.list.d/wazuh.list
sudo apt update
sudo apt install -y wazuh-agent
Configure manager address:
1
sudo nano /var/ossec/etc/ossec.conf
Ensure this block exists under <ossec_config>:
1
2
3
4
5
6
7
<client>
<server>
<address>WAZUH_MANAGER_IP</address>
<port>1514</port>
<protocol>tcp</protocol>
</server>
</client>
Start and enable agent:
1
2
sudo systemctl enable --now wazuh-agent
sudo systemctl status wazuh-agent --no-pager
Windows agent setup
- In Wazuh dashboard, open agent enrollment instructions for Windows.
- Download latest Wazuh agent MSI.
- Install with manager IP set to
WAZUH_MANAGER_IP. - Start service and verify in Services (
Wazuhrunning). - Confirm new agent appears in Dashboard -> Agents.
Step 3: Log Aggregation Sources
Wazuh can aggregate logs from multiple paths. Start with these three practical sources.
Source A: Wazuh agents (host logs)
By default, agents collect common OS logs and security events. You can extend watched files in endpoint ossec.conf using <localfile> entries.
Linux example for auth log:
1
2
3
4
<localfile>
<log_format>syslog</log_format>
<location>/var/log/auth.log</location>
</localfile>
Restart agent after changes.
Source B: Network device/syslog senders
If you want network appliance logs (firewalls, switches, routers), enable syslog reception on manager.
Edit manager config:
1
2
docker exec -it wazuh.manager bash
nano /var/ossec/etc/ossec.conf
Add this block under <ossec_config>:
1
2
3
4
5
6
7
<remote>
<connection>syslog</connection>
<port>514</port>
<protocol>udp</protocol>
<allowed-ips>0.0.0.0/0</allowed-ips>
<local_ip>0.0.0.0</local_ip>
</remote>
Exit container and restart manager:
1
docker restart wazuh.manager
Security recommendation: restrict allowed-ips to known source CIDRs, not 0.0.0.0/0, once validated.
Source C: Container/host logs
Use agent-based collection on Docker hosts for /var/lib/docker/containers/*/*.log or app log paths where needed.
Step 4: Create Custom Alerts (Rules)
Use local rules for environment-specific detections.
Edit local rules file inside manager:
1
2
docker exec -it wazuh.manager bash
nano /var/ossec/etc/rules/local_rules.xml
Example custom rule block:
1
2
3
4
5
6
7
8
9
10
11
12
13
<group name="local,custom,">
<rule id="100100" level="8">
<if_group>sshd</if_group>
<match>Failed password</match>
<description>Custom alert: SSH failed password detected</description>
</rule>
<rule id="100101" level="10">
<if_group>syslog</if_group>
<match>sudo:.*authentication failure</match>
<description>Custom alert: sudo authentication failure</description>
</rule>
</group>
Validate rule syntax:
1
/var/ossec/bin/wazuh-logtest
Restart manager after rule changes:
1
2
exit
docker restart wazuh.manager
Generate test events from Linux endpoint:
1
logger "sudo: authentication failure; test alert"
Confirm alerts in Dashboard -> Security events.
Step 5: Configure Notifications (Slack + Email)
Slack notifications
- Create Slack app at
https://api.slack.com/apps. - Enable Incoming Webhooks.
- Create webhook for channel (example:
#sec-alerts). - Copy webhook URL.
Configure Wazuh integration:
1
2
docker exec -it wazuh.manager bash
nano /var/ossec/etc/ossec.conf
Add under <ossec_config>:
1
2
3
4
5
6
<integration>
<name>slack</name>
<hook_url>https://hooks.slack.com/services/REPLACE/WITH/WEBHOOK</hook_url>
<level>10</level>
<alert_format>json</alert_format>
</integration>
Restart manager:
1
2
exit
docker restart wazuh.manager
Start with level 10 to avoid noise. Lower after tuning rules.
Email notifications
Enable Wazuh email settings in ossec.conf:
1
2
3
4
5
6
7
8
9
10
11
<global>
<email_notification>yes</email_notification>
<email_to>soc@example.com</email_to>
<email_from>wazuh@example.com</email_from>
<smtp_server>smtp.example.com</smtp_server>
<email_maxperhour>12</email_maxperhour>
</global>
<alerts>
<email_alert_level>10</email_alert_level>
</alerts>
Restart manager after changes.
Note: use app-passwords for providers like Gmail; avoid main account passwords.
Step 6: Alert Tuning Workflow
A reliable tuning cycle:
- Start with high severity only (
level >= 10) to avoid alert fatigue. - Observe noisy rules for 3-7 days.
- Add allowlists/suppression for known benign patterns.
- Lower notification threshold gradually (
9, then8) only after noise reduction. - Keep critical escalation channels (Slack/email) reserved for high-confidence alerts.
Step 7: Operational Validation Checklist
- Dashboard reachable over HTTPS
- All three containers healthy (
docker compose ps) - At least one Linux and one Windows agent connected
- Syslog sender events visible (if configured)
- Custom rule fires on test event
- Slack notification arrives for test high-severity alert
- Email alert arrives from SMTP test
- Manager config and local rules backed up
Backups and Persistence
For production-style reliability:
- Back up
/opt/wazuh/docker-compose.yml - Back up Wazuh persistent volumes regularly
- Back up manager config and local rules (
ossec.conf,local_rules.xml)
If you edit files inside containers, ensure your deployment uses persistent volumes so changes survive container recreation.
Common Issues and Fixes
- Dashboard unavailable after startup
- Check indexer health and cert generation logs.
- Verify host firewall allows 443.
- Agent not connecting
- Confirm manager IP/port in endpoint
ossec.conf. - Confirm network path to TCP 1514/1515.
- Confirm manager IP/port in endpoint
- No Slack alerts
- Validate webhook URL.
- Confirm alert level threshold is met.
- Check manager logs for integration errors.
- No email alerts
- Validate SMTP host/auth and TLS requirements.
- Confirm
email_notificationandemail_alert_levelblocks are active.
Key Takeaways
- Wazuh Docker single-node is a practical SIEM starting point for labs and small environments.
- Agent onboarding plus syslog intake gives strong baseline log aggregation quickly.
- Custom local rules should be built incrementally from real environment behavior.
- Notifications are most useful when severity thresholds are tuned to minimize noise.
Disclaimer: This guide is for educational and lab use. Security monitoring configurations should be reviewed against your organization policy, legal requirements, and data retention obligations before production deployment.