Skip to content

Commit e556c5f

Browse files
committed
Add Grafana
1 parent 35d797b commit e556c5f

12 files changed

Lines changed: 977 additions & 1 deletion

File tree

docker-compose.yml

Lines changed: 91 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,101 @@ services:
3434
- ./frontend:/app
3535
- /app/node_modules
3636
ports:
37-
- "5174:5173"
37+
- "5174:80"
3838
depends_on:
3939
- backend
4040
environment:
4141
- VITE_API_URL=http://localhost:8000/api/v1
4242

43+
prometheus:
44+
image: prom/prometheus:latest
45+
container_name: delux_prometheus
46+
restart: always
47+
ports:
48+
- "9090:9090"
49+
volumes:
50+
- ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml
51+
- prometheus_data:/prometheus
52+
command:
53+
- '--config.file=/etc/prometheus/prometheus.yml'
54+
- '--storage.tsdb.path=/prometheus'
55+
depends_on:
56+
- backend
57+
58+
grafana:
59+
image: grafana/grafana:latest
60+
container_name: delux_grafana
61+
restart: always
62+
ports:
63+
- "3000:3000"
64+
volumes:
65+
- grafana_storage:/var/lib/grafana
66+
- ./grafana/provisioning:/etc/grafana/provisioning
67+
- ./grafana/grafana.ini:/etc/grafana/grafana.ini
68+
env_file:
69+
- ./grafana/.env
70+
environment:
71+
- GF_PATHS_CONFIG=/etc/grafana/grafana.ini
72+
- GF_SECURITY_ADMIN_USER=admin
73+
- GF_SECURITY_ADMIN_PASSWORD=admin
74+
depends_on:
75+
- db
76+
- prometheus
77+
- loki
78+
79+
cadvisor:
80+
image: gcr.io/cadvisor/cadvisor:latest
81+
container_name: delux_cadvisor
82+
restart: always
83+
ports:
84+
- "8080:8080"
85+
volumes:
86+
- /:/rootfs:ro
87+
- /var/run:/var/run:ro
88+
- /sys:/sys:ro
89+
- /var/lib/docker/:/var/lib/docker:ro
90+
- /dev/disk/:/dev/disk:ro
91+
devices:
92+
- /dev/kmsg
93+
privileged: true
94+
95+
docker-exporter:
96+
build: ./docker-exporter
97+
container_name: delux_docker_exporter
98+
restart: always
99+
ports:
100+
- "8888:8888"
101+
volumes:
102+
- /var/run/docker.sock:/var/run/docker.sock
103+
privileged: true
104+
105+
loki:
106+
image: grafana/loki:latest
107+
container_name: delux_loki
108+
restart: always
109+
ports:
110+
- "3100:3100"
111+
volumes:
112+
- ./loki/loki-config.yml:/etc/loki/local-config.yml
113+
- loki_storage:/loki
114+
command: -config.file=/etc/loki/local-config.yml
115+
depends_on:
116+
- prometheus
117+
118+
promtail:
119+
image: grafana/promtail:latest
120+
container_name: delux_promtail
121+
restart: always
122+
volumes:
123+
- /var/lib/docker/containers:/var/lib/docker/containers:ro
124+
- /var/run/docker.sock:/var/run/docker.sock
125+
- ./promtail/promtail-config.yml:/etc/promtail/config.yml
126+
command: -config.file=/etc/promtail/config.yml
127+
depends_on:
128+
- loki
129+
43130
volumes:
44131
postgres_data:
132+
prometheus_data:
133+
grafana_storage:
134+
loki_storage:

docker-exporter/Dockerfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM python:3.11-slim
2+
3+
WORKDIR /app
4+
5+
RUN pip install docker prometheus-client
6+
7+
COPY exporter.py .
8+
9+
EXPOSE 8888
10+
11+
CMD ["python", "exporter.py"]

docker-exporter/exporter.py

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import docker
2+
import os
3+
from prometheus_client import start_http_server, Counter, Gauge, CollectorRegistry
4+
import time
5+
6+
# Create a registry
7+
registry = CollectorRegistry()
8+
9+
# Define metrics
10+
container_state = Gauge('docker_container_state', 'Docker container state (1=running, 0=stopped, -1=error)',
11+
['container_name', 'container_id', 'ports'], registry=registry)
12+
container_info = Gauge('docker_container_info', 'Docker container info',
13+
['container_name', 'container_id', 'ports', 'status'], registry=registry)
14+
15+
def get_container_ports(container):
16+
"""Extract ports from container"""
17+
ports = []
18+
if container.ports:
19+
for port_key, port_list in container.ports.items():
20+
if port_list:
21+
for port_info in port_list:
22+
host_port = port_info.get('HostPort', '')
23+
if host_port:
24+
ports.append(f"{host_port}:{port_key}")
25+
return ','.join(ports) if ports else 'no-ports'
26+
27+
def get_container_status(container):
28+
"""Get container status: running (1), stopped (0), error (-1)"""
29+
state = container.status
30+
if state == 'running':
31+
return 1, 'Запущен'
32+
elif state == 'exited':
33+
return 0, 'Не запущен'
34+
elif state == 'created' or state == 'restarting':
35+
return 0, 'Перезагрузка'
36+
else:
37+
return -1, 'Ошибка'
38+
39+
def update_metrics():
40+
"""Update metrics from Docker daemon"""
41+
try:
42+
client = docker.from_env()
43+
containers = client.containers.list(all=True)
44+
45+
for container in containers:
46+
# Skip non-delux containers
47+
if not container.name.startswith('delux_'):
48+
continue
49+
50+
ports = get_container_ports(container)
51+
state, status_text = get_container_status(container)
52+
53+
# Update metrics
54+
container_state.labels(
55+
container_name=container.name,
56+
container_id=container.short_id,
57+
ports=ports
58+
).set(state)
59+
60+
container_info.labels(
61+
container_name=container.name,
62+
container_id=container.short_id,
63+
ports=ports,
64+
status=status_text
65+
).set(state)
66+
67+
print(f"Updated: {container.name} ({ports}) - {status_text}")
68+
except Exception as e:
69+
print(f"Error updating metrics: {e}")
70+
71+
if __name__ == '__main__':
72+
# Start HTTP server on port 8888
73+
start_http_server(8888, registry=registry)
74+
print("Docker exporter started on port 8888")
75+
76+
# Update metrics every 5 seconds
77+
while True:
78+
update_metrics()
79+
time.sleep(5)

grafana/README.md

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Grafana Setup для Delux
2+
3+
## Описание
4+
Grafana развёрнута в отдельной папке и интегрирована в общую Docker конфигурацию вместе с Prometheus для мониторинга приложения.
5+
6+
## Структура
7+
```
8+
grafana/
9+
├── provisioning/
10+
│ ├── dashboards/
11+
│ │ ├── dashboards.yml # Конфигурация dashboards provider
12+
│ │ └── delux-dashboard.json # Пример dashboard
13+
│ └── datasources/
14+
│ └── datasources.yml # Конфигурация datasources (PostgreSQL, Prometheus)
15+
├── grafana.ini # Основная конфигурация Grafana
16+
└── .env # Переменные окружения
17+
18+
prometheus/
19+
└── prometheus.yml # Конфигурация Prometheus для сбора метрик
20+
```
21+
22+
## Как использовать
23+
24+
### 1. Запуск через Docker Compose
25+
```bash
26+
docker-compose up -d
27+
```
28+
29+
Это запустит:
30+
- **Backend** на http://localhost:8000
31+
- **Frontend** на http://localhost:5174
32+
- **Prometheus** на http://localhost:9090
33+
- **Grafana** на http://localhost:3000
34+
- **PostgreSQL** на localhost:5434
35+
36+
### 2. Доступ к Grafana
37+
- URL: http://localhost:3000
38+
- Логин: `admin`
39+
- Пароль: `admin`
40+
41+
### 3. Доступные Datasources
42+
- **PostgreSQL** - для запросов к базе данных
43+
- **Prometheus** - для метрик приложения (установлена по умолчанию)
44+
45+
### 4. Добавление собственных Dashboards
46+
1. Зайдите в Grafana
47+
2. Откройте меню и выберите Dashboards → New
48+
3. Создайте dashboard
49+
4. Сохраните dashboard как JSON в папку `grafana/provisioning/dashboards/`
50+
5. Изменённые dashboard автоматически загрузятся
51+
52+
## Конфигурация
53+
54+
### Важные переменные в `grafana/.env`
55+
- `GF_SECURITY_ADMIN_USER` - логин администратора
56+
- `GF_SECURITY_ADMIN_PASSWORD` - пароль администратора
57+
- `GF_SERVER_HTTP_PORT` - порт Grafana
58+
- `GF_USERS_ALLOW_SIGN_UP` - разрешить регистрацию пользователей
59+
60+
### Prometheus Scrape Targets
61+
В `prometheus/prometheus.yml` настроены targets для:
62+
- Backend приложения (http://backend:8000/metrics)
63+
- Самого Prometheus
64+
- PostgreSQL (при наличии экспортера)
65+
66+
## Для продвинутой настройки
67+
68+
Если нужны метрики от Django backend, установите:
69+
```bash
70+
pip install django-prometheus
71+
```
72+
73+
И добавьте в `backend/config/settings.py`:
74+
```python
75+
INSTALLED_APPS = [
76+
...
77+
'django_prometheus',
78+
]
79+
80+
MIDDLEWARE = [
81+
'django_prometheus.middleware.PrometheusBeforeMiddleware',
82+
...
83+
'django_prometheus.middleware.PrometheusAfterMiddleware',
84+
]
85+
```
86+
87+
Затем добавьте в `backend/config/urls.py`:
88+
```python
89+
from django_prometheus import views as prometheus_views
90+
91+
urlpatterns = [
92+
...
93+
path('metrics', prometheus_views.metrics),
94+
]
95+
```
96+
97+
## Остановка
98+
```bash
99+
docker-compose down
100+
```
101+
102+
Для удаления всех данных мониторинга:
103+
```bash
104+
docker-compose down -v
105+
```

grafana/grafana.ini

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Grafana Configuration
2+
[security]
3+
admin_user = admin
4+
admin_password = admin
5+
6+
[users]
7+
allow_sign_up = false
8+
9+
[server]
10+
http_port = 3000
11+
root_url = http://localhost:3000
12+
13+
[auth.anonymous]
14+
enabled = false
15+
16+
[paths]
17+
provisioning = /etc/grafana/provisioning
18+
19+
[log]
20+
level = info
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: 1
2+
3+
providers:
4+
- name: 'Dashboards'
5+
orgId: 1
6+
folder: ''
7+
type: file
8+
disableDeletion: false
9+
updateIntervalSeconds: 10
10+
allowUiUpdates: true
11+
options:
12+
path: /etc/grafana/provisioning/dashboards

0 commit comments

Comments
 (0)