Skip to content

Commit 81466ae

Browse files
committed
Add Docker Compose setup for NGINX Prometheus Exporter
- Add docker-compose.yml with nginx-exporter, nginx, app, prometheus, and grafana services - Add docker-compose.test.yml for minimal testing setup - Configure NGINX with stub_status endpoint on port 8081 - Add sample web application with custom HTML content - Configure Prometheus to scrape nginx-exporter metrics - Add Grafana with pre-configured datasources and dashboards - Set up proper networking and service dependencies - Use examples/docker-compose/ directory structure for all configuration files
1 parent af1f3a6 commit 81466ae

File tree

9 files changed

+1041
-0
lines changed

9 files changed

+1041
-0
lines changed

docker-compose.test.yml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
version: '3.8'
2+
3+
services:
4+
# Sample web application
5+
app:
6+
image: nginx:alpine
7+
container_name: sample-app
8+
volumes:
9+
- ./docker/app/nginx.conf:/etc/nginx/nginx.conf
10+
- ./docker/app/html:/usr/share/nginx/html
11+
ports:
12+
- "8080:80"
13+
networks:
14+
- nginx-monitoring
15+
restart: unless-stopped
16+
17+
# NGINX with stub_status enabled
18+
nginx:
19+
image: nginx:alpine
20+
container_name: nginx-server
21+
depends_on:
22+
- app
23+
volumes:
24+
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
25+
- ./docker/nginx/conf.d:/etc/nginx/conf.d
26+
ports:
27+
- "80:80"
28+
- "8081:8081" # stub_status port
29+
networks:
30+
- nginx-monitoring
31+
restart: unless-stopped
32+
33+
# NGINX Prometheus Exporter
34+
nginx-exporter:
35+
image: nginx/nginx-prometheus-exporter:latest
36+
container_name: nginx-prometheus-exporter
37+
depends_on:
38+
- nginx
39+
command:
40+
- --nginx.scrape-uri=http://nginx:8081/stub_status
41+
- --web.listen-address=0.0.0.0:9113
42+
ports:
43+
- "9113:9113"
44+
networks:
45+
- nginx-monitoring
46+
restart: unless-stopped
47+
48+
networks:
49+
nginx-monitoring:
50+
driver: bridge

docker-compose.yml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
services:
2+
# Sample web application
3+
app:
4+
image: nginx:alpine
5+
container_name: sample-app
6+
volumes:
7+
- ./examples/docker-compose/app/nginx.conf:/etc/nginx/nginx.conf
8+
- ./examples/docker-compose/app/html:/usr/share/nginx/html
9+
ports:
10+
- "8080:80"
11+
networks:
12+
- nginx-monitoring
13+
restart: unless-stopped
14+
15+
# NGINX with stub_status enabled
16+
nginx:
17+
image: nginx:alpine
18+
container_name: nginx-server
19+
depends_on:
20+
- app
21+
volumes:
22+
- ./examples/docker-compose/nginx/nginx.conf:/etc/nginx/nginx.conf
23+
- ./examples/docker-compose/nginx/conf.d:/etc/nginx/conf.d
24+
ports:
25+
- "80:80"
26+
- "8081:8081" # stub_status port
27+
networks:
28+
- nginx-monitoring
29+
restart: unless-stopped
30+
31+
# NGINX Prometheus Exporter
32+
nginx-exporter:
33+
image: nginx/nginx-prometheus-exporter:latest
34+
container_name: nginx-prometheus-exporter
35+
depends_on:
36+
- nginx
37+
command:
38+
- --nginx.scrape-uri=http://nginx:8081/stub_status
39+
- --web.listen-address=0.0.0.0:9113
40+
ports:
41+
- "9113:9113"
42+
networks:
43+
- nginx-monitoring
44+
restart: unless-stopped
45+
46+
# Prometheus
47+
prometheus:
48+
image: prom/prometheus:latest
49+
container_name: prometheus
50+
depends_on:
51+
- nginx-exporter
52+
volumes:
53+
- ./examples/docker-compose/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
54+
- prometheus_data:/prometheus
55+
ports:
56+
- "9090:9090"
57+
networks:
58+
- nginx-monitoring
59+
restart: unless-stopped
60+
command:
61+
- --config.file=/etc/prometheus/prometheus.yml
62+
- --storage.tsdb.path=/prometheus
63+
- --web.console.libraries=/etc/prometheus/console_libraries
64+
- --web.console.templates=/etc/prometheus/consoles
65+
- --storage.tsdb.retention.time=200h
66+
- --web.enable-lifecycle
67+
68+
# Grafana
69+
grafana:
70+
image: grafana/grafana:latest
71+
container_name: grafana
72+
depends_on:
73+
- prometheus
74+
volumes:
75+
- grafana_data:/var/lib/grafana
76+
- ./examples/docker-compose/grafana/provisioning:/etc/grafana/provisioning
77+
- ./examples/docker-compose/grafana/dashboards:/var/lib/grafana/dashboards
78+
ports:
79+
- "3000:3000"
80+
networks:
81+
- nginx-monitoring
82+
restart: unless-stopped
83+
environment:
84+
- GF_SECURITY_ADMIN_PASSWORD=admin123
85+
- GF_USERS_ALLOW_SIGN_UP=false
86+
87+
volumes:
88+
prometheus_data:
89+
grafana_data:
90+
91+
networks:
92+
nginx-monitoring:
93+
driver: bridge
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<title>NGINX Prometheus Exporter Demo</title>
7+
<style>
8+
body {
9+
font-family: Arial, sans-serif;
10+
max-width: 800px;
11+
margin: 0 auto;
12+
padding: 20px;
13+
line-height: 1.6;
14+
color: #333;
15+
}
16+
.header {
17+
text-align: center;
18+
background-color: #f4f4f4;
19+
padding: 20px;
20+
border-radius: 8px;
21+
margin-bottom: 20px;
22+
}
23+
.services {
24+
display: grid;
25+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
26+
gap: 20px;
27+
margin-top: 20px;
28+
}
29+
.service-card {
30+
background-color: #f9f9f9;
31+
padding: 20px;
32+
border-radius: 8px;
33+
border: 1px solid #ddd;
34+
}
35+
.service-card h3 {
36+
color: #0066cc;
37+
margin-top: 0;
38+
}
39+
.service-card a {
40+
color: #0066cc;
41+
text-decoration: none;
42+
}
43+
.service-card a:hover {
44+
text-decoration: underline;
45+
}
46+
.load-test {
47+
background-color: #e8f4f8;
48+
padding: 15px;
49+
border-radius: 5px;
50+
margin-top: 20px;
51+
}
52+
.load-test button {
53+
background-color: #0066cc;
54+
color: white;
55+
border: none;
56+
padding: 10px 20px;
57+
border-radius: 5px;
58+
cursor: pointer;
59+
margin-right: 10px;
60+
}
61+
.load-test button:hover {
62+
background-color: #0052a3;
63+
}
64+
.footer {
65+
text-align: center;
66+
margin-top: 40px;
67+
padding: 20px;
68+
background-color: #f4f4f4;
69+
border-radius: 8px;
70+
}
71+
</style>
72+
</head>
73+
<body>
74+
<div class="header">
75+
<h1>🔧 NGINX Prometheus Exporter Demo</h1>
76+
<p>This is a demo environment showcasing NGINX monitoring with Prometheus and Grafana</p>
77+
</div>
78+
79+
<div class="services">
80+
<div class="service-card">
81+
<h3>📊 Prometheus</h3>
82+
<p>Time-series database collecting metrics from NGINX</p>
83+
<a href="http://localhost:9090" target="_blank">Open Prometheus →</a>
84+
</div>
85+
86+
<div class="service-card">
87+
<h3>📈 Grafana</h3>
88+
<p>Visualization dashboard for NGINX metrics</p>
89+
<p><strong>Login:</strong> admin / admin123</p>
90+
<a href="http://localhost:3000" target="_blank">Open Grafana →</a>
91+
</div>
92+
93+
<div class="service-card">
94+
<h3>🔍 NGINX Exporter</h3>
95+
<p>Prometheus exporter for NGINX metrics</p>
96+
<a href="http://localhost:9113/metrics" target="_blank">View Metrics →</a>
97+
</div>
98+
99+
<div class="service-card">
100+
<h3>⚙️ NGINX Status</h3>
101+
<p>Raw NGINX stub_status information</p>
102+
<a href="http://localhost:8081/stub_status" target="_blank">View Status →</a>
103+
</div>
104+
</div>
105+
106+
<div class="load-test">
107+
<h3>🚀 Load Testing</h3>
108+
<p>Generate some traffic to see metrics in action:</p>
109+
<button onclick="sendRequests()">Send 100 Requests</button>
110+
<button onclick="sendSlowRequests()">Send Slow Requests</button>
111+
<button onclick="sendAPIRequests()">Send API Requests</button>
112+
<div id="results"></div>
113+
</div>
114+
115+
<div class="footer">
116+
<p>🐳 This demo is powered by Docker Compose</p>
117+
<p>Check the <a href="https://github.com/nginx/nginx-prometheus-exporter" target="_blank">NGINX Prometheus Exporter repository</a> for more information</p>
118+
</div>
119+
120+
<script>
121+
function sendRequests() {
122+
const results = document.getElementById('results');
123+
results.innerHTML = '<p>Sending 100 requests...</p>';
124+
125+
let completed = 0;
126+
for (let i = 0; i < 100; i++) {
127+
fetch('/?load-test=' + i)
128+
.then(() => {
129+
completed++;
130+
if (completed === 100) {
131+
results.innerHTML = '<p>✅ Completed 100 requests! Check Prometheus/Grafana for updated metrics.</p>';
132+
}
133+
})
134+
.catch(() => {
135+
completed++;
136+
if (completed === 100) {
137+
results.innerHTML = '<p>⚠️ Completed requests (some may have failed). Check metrics for details.</p>';
138+
}
139+
});
140+
}
141+
}
142+
143+
function sendSlowRequests() {
144+
const results = document.getElementById('results');
145+
results.innerHTML = '<p>Sending slow requests...</p>';
146+
147+
let completed = 0;
148+
for (let i = 0; i < 20; i++) {
149+
setTimeout(() => {
150+
fetch('/?slow-test=' + i)
151+
.then(() => {
152+
completed++;
153+
if (completed === 20) {
154+
results.innerHTML = '<p>✅ Completed 20 slow requests! Check response time metrics.</p>';
155+
}
156+
})
157+
.catch(() => {
158+
completed++;
159+
if (completed === 20) {
160+
results.innerHTML = '<p>⚠️ Completed slow requests (some may have failed).</p>';
161+
}
162+
});
163+
}, i * 100);
164+
}
165+
}
166+
167+
function sendAPIRequests() {
168+
const results = document.getElementById('results');
169+
results.innerHTML = '<p>Sending API requests...</p>';
170+
171+
let completed = 0;
172+
for (let i = 0; i < 50; i++) {
173+
fetch('/api/test' + i)
174+
.then(() => {
175+
completed++;
176+
if (completed === 50) {
177+
results.innerHTML = '<p>✅ Completed 50 API requests! Check metrics for API endpoint stats.</p>';
178+
}
179+
})
180+
.catch(() => {
181+
completed++;
182+
if (completed === 50) {
183+
results.innerHTML = '<p>⚠️ Completed API requests (some may have failed).</p>';
184+
}
185+
});
186+
}
187+
}
188+
</script>
189+
</body>
190+
</html>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
events {
2+
worker_connections 1024;
3+
}
4+
5+
http {
6+
include /etc/nginx/mime.types;
7+
default_type application/octet-stream;
8+
9+
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
10+
'$status $body_bytes_sent "$http_referer" '
11+
'"$http_user_agent" "$http_x_forwarded_for"';
12+
13+
access_log /var/log/nginx/access.log main;
14+
error_log /var/log/nginx/error.log;
15+
16+
sendfile on;
17+
tcp_nopush on;
18+
tcp_nodelay on;
19+
keepalive_timeout 65;
20+
types_hash_max_size 2048;
21+
22+
server {
23+
listen 80;
24+
server_name localhost;
25+
root /usr/share/nginx/html;
26+
index index.html;
27+
28+
location / {
29+
try_files $uri $uri/ =404;
30+
}
31+
32+
location /api/ {
33+
return 200 '{"status": "ok", "message": "API endpoint"}';
34+
add_header Content-Type application/json;
35+
}
36+
}
37+
}

0 commit comments

Comments
 (0)