├── Readme.md ├── Screenshot_Loki.png ├── Screenshot_Prometheus.png ├── config ├── loki.yaml ├── prometheus.yaml ├── promtail.yaml └── web-config.yaml └── grafana.yaml /Readme.md: -------------------------------------------------------------------------------- 1 | # Стек сервисов Grafana, Prometheus, Pushgateway, Loki и Promtail для Docker (swarm, compose) 2 | 3 | Логи собираются со всех контейнеров в кластере swarm без необходимости установки дополнительного ПО на ноды в кластере. 4 | Метрики собираются с exporter'ов, которые устанавливаются отдельно (при необходимости). 5 | Можно использовать также и на одной ноде (одной VM, одной машине) c docker compose. 6 | 7 | ## Быстрый старт 8 | 9 | * Для docker swarm (должен быть инициализирован swarm: `docker swarm init`) 10 | 11 | ``` 12 | git clone https://github.com/skl256/grafana_stack_for_docker.git && \ 13 | cd grafana_stack_for_docker && \ 14 | sudo mkdir -p /mnt/common_volume/swarm/grafana/config && \ 15 | sudo mkdir -p /mnt/common_volume/grafana/{grafana-config,grafana-data,prometheus-data,loki-data,promtail-data} && \ 16 | sudo chown -R $(id -u):$(id -g) {/mnt/common_volume/swarm/grafana/config,/mnt/common_volume/grafana} && \ 17 | touch /mnt/common_volume/grafana/grafana-config/grafana.ini && \ 18 | cp config/* /mnt/common_volume/swarm/grafana/config/ && \ 19 | docker stack deploy -c grafana.yaml grafana 20 | ``` 21 | 22 | * Для docker compose 23 | 24 | ``` 25 | git clone https://github.com/skl256/grafana_stack_for_docker.git && \ 26 | cd grafana_stack_for_docker && \ 27 | sudo mkdir -p /mnt/common_volume/swarm/grafana/config && \ 28 | sudo mkdir -p /mnt/common_volume/grafana/{grafana-config,grafana-data,prometheus-data,loki-data,promtail-data} && \ 29 | sudo chown -R $(id -u):$(id -g) {/mnt/common_volume/swarm/grafana/config,/mnt/common_volume/grafana} && \ 30 | touch /mnt/common_volume/grafana/grafana-config/grafana.ini && \ 31 | cp config/* /mnt/common_volume/swarm/grafana/config/ && \ 32 | mv grafana.yaml docker-compose.yaml && \ 33 | docker compose up -d 34 | ``` 35 | 36 | * Перейти в браузере по адресу http:// **IP адрес сервера, на котором запущен стек** :3000 (логин `admin` пароль `admin`) 37 | * Расширенные labels не будут работать до внесения изменений в `/etc/docker/daemon.json` 38 | 39 | ## Особенности конфигурации из примера 40 | 41 | * Конфигурация для использования в docker swarm. Если необходимо использовать просто с docker compose: 42 | * удалить или скорректировать параметры `deploy:` в `grafana.yaml`, переименовать `mv grafana.yaml docker-compose.yaml` 43 | * не использовать docker secrets, т.к. docker compose в настоящий момент не поддерживает secrets 44 | * В конфигурации используются bind volumes. Перед запуском необходимо: 45 | * В `grafana.yaml` скорректировать используемые в примере пути: `/mnt/common_volume/swarm/grafana/config` (файлы конфигураций) и `/mnt/common_volume/grafana` (файлы данных) на свои. 46 | * Для кластера (несколько нод): подразумевается, что `/mnt/common_volume` это общий том для нод в кластере. Если создать общий том для всех нод нет возможности, необходимо запускать все сервисы, кроме promtail, только на одной ноде, а для promtail создать bind volume на каждой ноде (это корректно, что для каждого экземпляра promtail будет свой volume). 47 | * Для запуска всего стека на одной оде (одной VM, одной машине) можно использовать любой удобный volume. 48 | * В любом случае необходимо **обязательно** создать пустые папки и файлы конфигурации (для последних - даже если они пустые, например `grafana.ini`). Команды для создания указаны в `grafana.yaml` в комментариях в секции `volume`. 49 | * В конфигурации `prometheus.yaml` указаны примеры сбора метрик с различных exporter'ов, для сбора метрик с них, последние необходимо установить и настроить (в противном случае, с отсутствующих не будут собираться метрики). 50 | 51 | ## Конфигурация отдельных сервисов 52 | 53 | ### Grafana 54 | 55 | Документация: 56 | 57 | * Образ `grafana/grafana-oss:10.2.2` 58 | * Порт `3000` 59 | * Для использования reserve proxy необходимо следовать руководству: 60 | * Вместо редактирования `grafana.ini` домен и url можно указать в environment variables `GF_SERVER_DOMAIN`, `GF_SERVER_ROOT_URL` 61 | * Рекомендуется использовать БД вместо хранения данных grafana в SQLite, прример конфигурации подключения к PostgreSQL указан в `grafana.yaml` 62 | * Для отправки скриншотов с dashboards вместе с алертами (поддерживаются не все мессенджеры), необходимо использовать grafana image renderer (в конфигурации из примера уже настроено всё необходимое) 63 | * Начальный логин `admin` пароль `admin` 64 | 65 | ### Grafana image renderer 66 | 67 | * Образ `grafana/grafana-image-renderer:3.9.0` 68 | * Установить timezone: например `TZ: "Europe/Moscow"` 69 | * В основном сервисе (grafana) установить подключение к grafana image renderer: 70 | 71 | ``` 72 | GF_RENDERING_SERVER_URL: "http://grafana-image-renderer:8081/render" 73 | GF_RENDERING_CALLBACK_URL: "http://grafana:3000/" 74 | GF_UNIFIED_ALERTING_SCREENSHOTS_CAPTURE: true 75 | GF_LOG_FILTERS: "rendering:debug" 76 | ``` 77 | 78 | ### Prometheus 79 | 80 | Документация: 81 | 82 | * Образ `prom/prometheus:v2.48.0` 83 | * Порт `9090` 84 | * Команда: `command: ["--config.file=/etc/prometheus/prometheus.yaml", "--web.config.file=/etc/prometheus/web-config.yaml", "--web.enable-lifecycle"]` (`web.enable-lifecycle` для перечитывания `web-config` "на лету") 85 | 86 | Пример `prometheus.yaml` (вместо `password` безопасно использовать `password_file` совместно с docker secrets) 87 | 88 | ``` 89 | global: 90 | scrape_interval: 15s 91 | 92 | scrape_configs: 93 | 94 | # node exporter (https://github.com/prometheus/node_exporter) 95 | - job_name: 'node' 96 | static_configs: 97 | - targets: ['192.168.100.2:9100', '192.168.100.4:9100', '192.168.100.6:9100'] # change 192.168.100.x to your nodes IPs 98 | basic_auth: 99 | username: 'admin' # change 100 | password: 'admin' # change # or use password_file instead (docker secrets) 101 | # password_file: '/run/secrets/node_exporter_password' 102 | ``` 103 | 104 | Пример `web-config.yaml` (используется для basic_auth) 105 | 106 | 107 | * В данном примере один `web-config.yaml` будет использоваться и для prometheus и для pushgateway 108 | * password_hash генерируется командой `htpasswd -nBC 10 "" | tr -d ':\n'` 109 | * Если htpasswd не установлен: для Debian, Ubuntu `sudo apt install apache2-utils` 110 | * для ОС использующих yum `sudo yum install -y httpd-tools` 111 | 112 | ``` 113 | basic_auth_users: 114 | admin: $2y$10$K7gXeAs0VbhjHMdlV1Hn0OlWcqIoK7P9s/dVKB3HoyYcLuscxSpXe # change "$2y$10..." to basic auth password_hash 115 | bobi: $2y$10$1sYkKxi49lGpFdlu7aDkTeWkzvkqaeCTb4PDBR/pNxeETO8N3shZS # you can add more users 116 | ``` 117 | 118 | * Время и максимальный объём хранимых логов можно настроить с помощь команд запуска `--storage.tsdb.retention.time=15d`, `--storage.tsdb.retention.size=0` (напр. `512MB`) 119 | * подробнее: 120 | 121 | ### Pushgateway 122 | 123 | * Образ `prom/pushgateway:v1.6.2` 124 | * Порт 9091 125 | * Команда: `command: ["--web.config.file=/etc/prometheus/web-config.yaml", "--web.enable-lifecycle"]` (`web.enable-lifecycle` для перечитывания `web-config` "на лету") 126 | 127 | В конфиг `prometheus.yaml` необходимо добавить в качестве target'а сервис pushgateway с `honor_labels: true` 128 | 129 | ``` 130 | # pushgateway 131 | - job_name: 'pushgateway' 132 | honor_labels: true 133 | static_configs: 134 | - targets: ['pushgateway:9091'] 135 | basic_auth: 136 | username: 'admin' # change 137 | password: 'admin' # change # or use password_file instead (docker secrets) 138 | # password_file: '/run/secrets/node_exporter_password' 139 | ``` 140 | 141 | ### Loki 142 | 143 | * Образ `grafana/loki:2.9.0` 144 | * Порт 3100 145 | * В примере порт закрыт, т.к. при использовании loki внутри docker обычно нет необходимости подключения к loki снаружи стека 146 | * При необходимости открыть порт: настроить авторизацию (например, средствами [nginx basic auth](https://docs.nginx.com/nginx/admin-guide/security-controls/configuring-http-basic-authentication/)) 147 | * Команда: `command: ["--config.file=/etc/loki/loki.yaml"]` 148 | 149 | Содержимое стандартного файла конфигурации находится в контейнере в `/etc/loki/local-config.yaml`. Стандартный файл переопределяется командой `--config.file=/etc/loki/loki.yaml` 150 | 151 | В стандартный файл можно добавить запрет отправки analytics: 152 | 153 | ``` 154 | analytics: 155 | reporting_enabled: false 156 | ``` 157 | 158 | Можно добавить настройку очистки старых логов (по умолчанию логи хранятся вечно): 159 | 160 | ``` 161 | limits_config: 162 | retention_period: 7d # days to delete old logs, you can change 163 | max_query_lookback: 7d # days to delete old logs, you can change 164 | 165 | chunk_store_config: 166 | max_look_back_period: 7d # days to delete old logs, you can change 167 | 168 | compactor: 169 | working_directory: /loki/retention 170 | shared_store: filesystem 171 | compaction_interval: 15m 172 | retention_enabled: true 173 | retention_delete_delay: 2h 174 | retention_delete_worker_count: 150 175 | ``` 176 | 177 | В конфигурации из примера переопределено значение `query_ingesters_within` для предотвращения проявления [grafana/loki/issues/6043](https://github.com/grafana/loki/issues/6043) 178 | 179 | ### Promtail 180 | 181 | * Образ `grafana/promtail:2.9.0` 182 | * Команда: `["--config.file=/etc/promtail/promtail.yaml", "--config.expand-env=true"]` 183 | * Сервис Promtail должен быть запущен по одному на каждой ноде, с контейнеров которой требуется собирать логи 184 | * При этом, файл `/var/promtail/positions_${HOST_HOSTNAME}.yaml` (хранит позиции чтения файлов) уникальный для каждой ноды (в примере это достигается подстановкой ${HOST_HOSTNAME} в имя файла, но если вы не используете общий том для всех нод, то можно не брать во внимание эту особенность. 185 | 186 | Пример `promtail.yaml` (за основу взят ) 187 | 188 | ``` 189 | server: 190 | http_listen_address: 0.0.0.0 191 | http_listen_port: 9080 192 | 193 | positions: 194 | filename: "/var/promtail/positions_${HOST_HOSTNAME}.yaml" # remove "_${HOST_HOSTNAME}" if you do not use docker swarm 195 | 196 | clients: 197 | - url: http://loki:3100/loki/api/v1/push 198 | 199 | scrape_configs: 200 | 201 | - job_name: containers 202 | static_configs: 203 | - targets: 204 | - localhost 205 | labels: 206 | job: containers_logs 207 | node_hostname: "${HOST_HOSTNAME}" # remove line if you do not use docker swarm 208 | __path__: /var/lib/docker/containers/*/*log 209 | 210 | pipeline_stages: 211 | - json: 212 | expressions: 213 | log: log 214 | stream: stream 215 | time: time 216 | tag: attrs.tag 217 | # docker compose 218 | compose_project: attrs."com.docker.compose.project" 219 | compose_service: attrs."com.docker.compose.service" 220 | # docker swarm 221 | stack_name: attrs."com.docker.stack.namespace" 222 | service_name: attrs."com.docker.swarm.service.name" 223 | service_id: attrs."com.docker.swarm.service.id" 224 | task_name: attrs."com.docker.swarm.task.name" 225 | task_id: attrs."com.docker.swarm.task.id" 226 | node_id: attrs."com.docker.swarm.node.id" 227 | - regex: 228 | expression: "^/var/lib/docker/containers/(?P.{12}).+/.+-json.log$" 229 | source: filename 230 | - timestamp: 231 | format: RFC3339Nano 232 | source: time 233 | - labels: 234 | stream: 235 | container_id: 236 | tag: 237 | # docker compose 238 | compose_project: 239 | compose_service: 240 | # docker swarm 241 | stack_name: 242 | service_name: 243 | service_id: 244 | task_name: 245 | task_id: 246 | node_id: 247 | - output: 248 | source: log 249 | ``` 250 | 251 | * В `promtail.yaml` можно использовать environment variables (например `custom_label: "${ENV}"`) для этого нужно передать дополнительно команду `-config.expand-env=true` 252 | * **Для корректной работы labels** необходимо внести в `/etc/docker/daemon.json` (на каждом хосте) настройку `log-driver` и `log-opts`: 253 | * После внесения изменений в `/etc/docker/daemon.json` необходимо перезапустить docker daemon (`sudo systemctl restart docker`) для ОС, использующих systemctl 254 | * Для изменения логирования необходимо также перезапустить контейнеры (для compose и обычных контейнеров), контейнеры swarm пересоздаются при перезапуске docker 255 | 256 | ``` 257 | { 258 | "metrics-addr":"0.0.0.0:9323", 259 | "log-driver": "json-file", 260 | "log-opts": { 261 | "labels-regex": "^.+" 262 | } 263 | } 264 | ``` -------------------------------------------------------------------------------- /Screenshot_Loki.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skl256/grafana_stack_for_docker/89b6a69a0d219a84f7959707a0544cfe47842288/Screenshot_Loki.png -------------------------------------------------------------------------------- /Screenshot_Prometheus.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skl256/grafana_stack_for_docker/89b6a69a0d219a84f7959707a0544cfe47842288/Screenshot_Prometheus.png -------------------------------------------------------------------------------- /config/loki.yaml: -------------------------------------------------------------------------------- 1 | auth_enabled: false 2 | 3 | server: 4 | http_listen_port: 3100 5 | 6 | common: 7 | path_prefix: /loki 8 | storage: 9 | filesystem: 10 | chunks_directory: /loki/chunks 11 | rules_directory: /loki/rules 12 | replication_factor: 1 13 | ring: 14 | kvstore: 15 | store: inmemory 16 | 17 | schema_config: 18 | configs: 19 | - from: 2020-10-24 20 | store: boltdb-shipper 21 | object_store: filesystem 22 | schema: v11 23 | index: 24 | prefix: index_ 25 | period: 24h 26 | 27 | limits_config: 28 | retention_period: 7d # days to delete old logs, you can change 29 | max_query_lookback: 7d # days to delete old logs, you can change 30 | 31 | ruler: 32 | alertmanager_url: http://localhost:9093 33 | 34 | analytics: 35 | reporting_enabled: false 36 | 37 | chunk_store_config: 38 | max_look_back_period: 7d # days to delete old logs, you can change 39 | 40 | compactor: 41 | working_directory: /loki/retention 42 | shared_store: filesystem 43 | compaction_interval: 15m 44 | retention_enabled: true 45 | retention_delete_delay: 2h 46 | retention_delete_worker_count: 150 47 | 48 | querier: 49 | query_ingesters_within: 2h # avoid https://github.com/grafana/loki/issues/6043 50 | -------------------------------------------------------------------------------- /config/prometheus.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | scrape_interval: 15s 3 | 4 | scrape_configs: 5 | 6 | # node exporter (https://github.com/prometheus/node_exporter) 7 | - job_name: 'node' 8 | static_configs: 9 | - targets: ['192.168.100.2:9100', '192.168.100.4:9100', '192.168.100.6:9100'] # change 192.168.100.x to your nodes IPs 10 | basic_auth: 11 | username: 'admin' # change 12 | password: 'admin' # change # or use password_file instead (docker secrets) 13 | # password_file: '/run/secrets/node_exporter_password' 14 | 15 | # docker daemon (https://docs.docker.com/config/daemon/prometheus/) 16 | - job_name: 'docker' 17 | static_configs: 18 | - targets: ['192.168.100.2:9323', '192.168.100.4:9323', '192.168.100.6:9323'] # change 192.168.100.x to your nodes IPs 19 | 20 | # pushgateway 21 | - job_name: 'pushgateway' 22 | honor_labels: true 23 | static_configs: 24 | - targets: ['pushgateway:9091'] 25 | basic_auth: 26 | username: 'admin' # change 27 | password: 'admin' # change # or use password_file instead (docker secrets) 28 | # password_file: '/run/secrets/node_exporter_password' 29 | 30 | # nginx exporter (https://github.com/nginxinc/nginx-prometheus-exporter) 31 | - job_name: 'nginx' 32 | static_configs: 33 | - targets: ['192.168.2.104:8080', '192.168.2.104:8080'] # change 192.168.100.x to your nodes IPs 34 | 35 | # postgres exporter (https://github.com/prometheus-community/postgres_exporter) 36 | - job_name: 'postgres' 37 | static_configs: 38 | - targets: ['192.168.100.4:9187'] # change 192.168.100.x to your nodes IPs 39 | -------------------------------------------------------------------------------- /config/promtail.yaml: -------------------------------------------------------------------------------- 1 | server: 2 | http_listen_address: 0.0.0.0 3 | http_listen_port: 9080 4 | 5 | positions: 6 | filename: "/var/promtail/positions_${HOST_HOSTNAME}.yaml" # remove "_${HOST_HOSTNAME}" if you do not use docker swarm 7 | 8 | clients: 9 | - url: http://loki:3100/loki/api/v1/push 10 | 11 | scrape_configs: 12 | 13 | - job_name: containers 14 | static_configs: 15 | - targets: 16 | - localhost 17 | labels: 18 | job: containers_logs 19 | node_hostname: "${HOST_HOSTNAME}" # remove line if you do not use docker swarm 20 | __path__: /var/lib/docker/containers/*/*log 21 | 22 | pipeline_stages: 23 | - json: 24 | expressions: 25 | log: log 26 | stream: stream 27 | time: time 28 | tag: attrs.tag 29 | # docker compose 30 | compose_project: attrs."com.docker.compose.project" 31 | compose_service: attrs."com.docker.compose.service" 32 | # docker swarm 33 | stack_name: attrs."com.docker.stack.namespace" 34 | service_name: attrs."com.docker.swarm.service.name" 35 | service_id: attrs."com.docker.swarm.service.id" 36 | task_name: attrs."com.docker.swarm.task.name" 37 | task_id: attrs."com.docker.swarm.task.id" 38 | node_id: attrs."com.docker.swarm.node.id" 39 | - regex: 40 | expression: "^/var/lib/docker/containers/(?P.{12}).+/.+-json.log$" 41 | source: filename 42 | - timestamp: 43 | format: RFC3339Nano 44 | source: time 45 | - labels: 46 | stream: 47 | container_id: 48 | tag: 49 | # docker compose 50 | compose_project: 51 | compose_service: 52 | # docker swarm 53 | stack_name: 54 | service_name: 55 | service_id: 56 | task_name: 57 | task_id: 58 | node_id: 59 | - output: 60 | source: log 61 | -------------------------------------------------------------------------------- /config/web-config.yaml: -------------------------------------------------------------------------------- 1 | basic_auth_users: 2 | admin: $2y$10$K7gXeAs0VbhjHMdlV1Hn0OlWcqIoK7P9s/dVKB3HoyYcLuscxSpXe # change "$2y$10..." to basic auth password hash 3 | bobi: $2y$10$1sYkKxi49lGpFdlu7aDkTeWkzvkqaeCTb4PDBR/pNxeETO8N3shZS # you can add more users 4 | -------------------------------------------------------------------------------- /grafana.yaml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | 5 | grafana: 6 | image: "grafana/grafana-oss:10.2.2" 7 | ports: 8 | - 3000:3000 9 | volumes: 10 | # touch /mnt/common_volume/grafana/grafana-config/grafana.ini; 11 | # mkdir -p /mnt/common_volume/grafana/{grafana-config,grafana-data}; 12 | - /mnt/common_volume/grafana/grafana-config:/etc/grafana 13 | - /mnt/common_volume/grafana/grafana-data:/var/lib/grafana 14 | user: "root" 15 | environment: 16 | # Uncomment GF_SERVER_DOMAIN, GF_SERVER_ROOT_URL for using reserve proxy 17 | #GF_SERVER_DOMAIN: "grafana.domain.example" # change "grafana.domain.example" to your domain 18 | #GF_SERVER_ROOT_URL: "https://grafana.domain.example/" # change "grafana.domain.example" to your domain 19 | GF_RENDERING_SERVER_URL: "http://grafana-image-renderer:8081/render" 20 | GF_RENDERING_CALLBACK_URL: "http://grafana:3000/" 21 | GF_UNIFIED_ALERTING_SCREENSHOTS_CAPTURE: "true" 22 | GF_LOG_FILTERS: "rendering:debug" 23 | # Uncomment for using PostgreSQL (recommended) instead SQLite 24 | #GF_DATABASE_TYPE: "postgres" 25 | #GF_DATABASE_HOST: "postgres:5432" # change "postgres:5432" to your PostgreSQL database host and port 26 | #GF_DATABASE_NAME: "postgres" # change "postgres" to your database name 27 | #GF_DATABASE_USER: "postgres" # change "postgres" to your database user name 28 | #GF_DATABASE_PASSWORD: "postgres" # change "postgres" to your database password # or use GF_DATABASE_PASSWORD 29 | #GF_DATABASE_PASSWORD__FILE: "/run/secrets/grafana_database_password" # for docker secrets # or use GF_DATABASE_PASSWORD 30 | #GF_DATABASE_SSL_MODE: "disable" 31 | # Uncomment for using docker secrets 32 | #secrets: 33 | # - grafana_database_password 34 | deploy: 35 | mode: replicated 36 | replicas: 1 37 | update_config: 38 | order: stop-first 39 | resources: 40 | limits: 41 | memory: 1024M 42 | 43 | grafana-image-renderer: 44 | image: "grafana/grafana-image-renderer:3.9.0" 45 | environment: 46 | TZ: "Europe/Moscow" # change to your timezone 47 | deploy: 48 | mode: replicated 49 | replicas: 1 50 | update_config: 51 | order: start-first 52 | resources: 53 | limits: 54 | memory: 1024M 55 | 56 | prometheus: 57 | image: "prom/prometheus:v2.48.0" 58 | ports: 59 | - 9090:9090 60 | volumes: 61 | # touch /mnt/common_volume/swarm/grafana/config/{prometheus.yaml,web-config.yaml}; 62 | # mkdir -p /mnt/common_volume/grafana/prometheus-data 63 | - /mnt/common_volume/swarm/grafana/config/prometheus.yaml:/etc/prometheus/prometheus.yaml:ro 64 | - /mnt/common_volume/swarm/grafana/config/web-config.yaml:/etc/prometheus/web-config.yaml:ro 65 | - /mnt/common_volume/grafana/prometheus-data:/prometheus 66 | user: "root" 67 | # Uncomment for using docker secrets 68 | #secrets: 69 | # - node_exporter_password 70 | # - grafana_prometheus_password 71 | command: 72 | - "--config.file=/etc/prometheus/prometheus.yaml" 73 | - "--web.config.file=/etc/prometheus/web-config.yaml" 74 | - "--storage.tsdb.retention.time=7d" 75 | deploy: 76 | mode: replicated 77 | replicas: 1 78 | update_config: 79 | order: stop-first 80 | resources: 81 | limits: 82 | memory: 1024M 83 | 84 | pushgateway: 85 | image: "prom/pushgateway:v1.6.2" 86 | ports: 87 | - 9091:9091 88 | volumes: 89 | - /mnt/common_volume/swarm/grafana/config/web-config.yaml:/etc/prometheus/web-config.yaml:ro 90 | command: 91 | - "--web.config.file=/etc/prometheus/web-config.yaml" 92 | deploy: 93 | mode: replicated 94 | replicas: 1 95 | update_config: 96 | order: start-first 97 | resources: 98 | limits: 99 | memory: 512M 100 | 101 | loki: 102 | image: "grafana/loki:2.9.0" 103 | # - "3100:3100" port closed because loki does not support basic auth 104 | volumes: 105 | # touch /mnt/common_volume/swarm/grafana/config/loki.yaml; 106 | # mkdir -p /mnt/common_volume/grafana/loki-data; 107 | - /mnt/common_volume/swarm/grafana/config/loki.yaml:/etc/loki/loki.yaml:ro 108 | - /mnt/common_volume/grafana/loki-data:/loki 109 | command: 110 | - "--config.file=/etc/loki/loki.yaml" 111 | user: "root" 112 | deploy: 113 | mode: replicated 114 | replicas: 1 115 | update_config: 116 | order: stop-first 117 | resources: 118 | limits: 119 | memory: 1024M 120 | 121 | promtail: 122 | image: "grafana/promtail:2.9.0" 123 | volumes: 124 | # touch /mnt/common_volume/swarm/grafana/config/promtail.yaml; 125 | # mkdir -p /mnt/common_volume/grafana/promtail-data; 126 | - /mnt/common_volume/swarm/grafana/config/promtail.yaml:/etc/promtail/promtail.yaml:ro 127 | - /mnt/common_volume/grafana/promtail-data:/var/promtail 128 | - /var/lib/docker/containers:/var/lib/docker/containers:ro 129 | - /var/log:/var/log:ro 130 | environment: 131 | HOST_HOSTNAME: "{{.Node.Hostname}}" 132 | command: 133 | - "--config.file=/etc/promtail/promtail.yaml" 134 | - "--config.expand-env=true" 135 | deploy: 136 | mode: global 137 | update_config: 138 | order: stop-first 139 | resources: 140 | limits: 141 | memory: 512M 142 | 143 | # Uncomment for using docker secrets 144 | # create docker secret first: docker secret create [OPTIONS] SECRET [file|-] 145 | # https://docs.docker.com/engine/reference/commandline/secret_create/ 146 | # if you create secret from stdin use Ctrl+D after input, do not use Enter 147 | #secrets: 148 | # grafana_database_password: 149 | # external: true 150 | # node_exporter_password: 151 | # external: true 152 | # grafana_prometheus_password: 153 | # external: true 154 | --------------------------------------------------------------------------------