├── down ├── bounce ├── up ├── bounce-swarmstack ├── up-swarmstack ├── local_bind_volume_dir └── README.md ├── docker-compose.yml ├── .gitignore ├── docker-compose-swarmstack.yml ├── loki-local-config.yaml └── README.md /down: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | docker stack rm loki 4 | -------------------------------------------------------------------------------- /bounce: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./down 4 | sleep 5 5 | ./up 6 | -------------------------------------------------------------------------------- /up: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | docker stack deploy -c docker-compose.yml loki 4 | -------------------------------------------------------------------------------- /bounce-swarmstack: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | ./down 4 | sleep 5 5 | ./up-swarmstack 6 | -------------------------------------------------------------------------------- /up-swarmstack: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | docker stack deploy -c docker-compose-swarmstack.yml loki 4 | -------------------------------------------------------------------------------- /local_bind_volume_dir/README.md: -------------------------------------------------------------------------------- 1 | This directory exists as "permanent" storage for your container, just in case you forget to edit the local_bind_volume_dir to another directory on your local Docker system towards the bottom of docker-compose.yml, or use persistent storage as with the swarmstack version. 2 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.4" 2 | 3 | configs: 4 | loki_config: 5 | file: ./loki-local-config.yaml 6 | 7 | services: 8 | loki: 9 | image: grafana/loki:v1.3.0 10 | command: -config.file=/etc/loki/loki-local-config.yaml 11 | configs: 12 | - source: loki_config 13 | target: /etc/loki/loki-local-config.yaml 14 | deploy: 15 | mode: replicated 16 | replicas: 1 17 | ports: 18 | - "3100:3100" 19 | volumes: 20 | - ./local_bind_volume_dir:/data/loki 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Icon must end with two \r 7 | Icon 8 | 9 | # Thumbnails 10 | ._* 11 | 12 | # Files that might appear in the root of a volume 13 | .DocumentRevisions-V100 14 | .fseventsd 15 | .Spotlight-V100 16 | .TemporaryItems 17 | .Trashes 18 | .VolumeIcon.icns 19 | .com.apple.timemachine.donotpresent 20 | 21 | # Directories potentially created on remote AFP share 22 | .AppleDB 23 | .AppleDesktop 24 | Network Trash Folder 25 | Temporary Items 26 | .apdisk 27 | -------------------------------------------------------------------------------- /docker-compose-swarmstack.yml: -------------------------------------------------------------------------------- 1 | version: "3.4" 2 | 3 | networks: 4 | default: 5 | external: 6 | name: swarmstack_net 7 | 8 | volumes: 9 | loki-data: 10 | driver: pxd 11 | driver_opts: 12 | repl: 2 13 | size: 40 14 | 15 | configs: 16 | loki_config: 17 | file: ./loki-local-config.yaml 18 | 19 | services: 20 | loki: 21 | image: grafana/loki:v1.3.0 22 | command: -config.file=/etc/loki/loki-local-config.yaml 23 | configs: 24 | - source: loki_config 25 | target: /etc/loki/loki-local-config.yaml 26 | deploy: 27 | labels: 28 | prometheus.enable: "true" 29 | prometheus.port: "3100" 30 | prometheus.path: "/metrics" 31 | mode: replicated 32 | placement: 33 | constraints: 34 | - node.Labels.storagegroup==RED 35 | replicas: 1 36 | ports: 37 | - "3100:3100" 38 | volumes: 39 | - loki-data:/data/loki 40 | -------------------------------------------------------------------------------- /loki-local-config.yaml: -------------------------------------------------------------------------------- 1 | auth_enabled: false 2 | 3 | server: 4 | http_listen_port: 3100 5 | 6 | ingester: 7 | lifecycler: 8 | address: 127.0.0.1 9 | ring: 10 | kvstore: 11 | store: inmemory 12 | replication_factor: 1 13 | chunk_idle_period: 15m 14 | 15 | schema_config: 16 | configs: 17 | - from: 2019-06-01 18 | store: boltdb 19 | object_store: filesystem 20 | schema: v9 21 | index: 22 | prefix: index_ 23 | period: 168h 24 | 25 | storage_config: 26 | boltdb: 27 | directory: /data/loki/index 28 | filesystem: 29 | directory: /data/loki/chunks 30 | 31 | limits_config: 32 | enforce_metric_name: false 33 | reject_old_samples: true 34 | reject_old_samples_max_age: 168h 35 | 36 | chunk_store_config: 37 | max_look_back_period: 0 38 | 39 | table_manager: 40 | chunk_tables_provisioning: 41 | inactive_read_throughput: 0 42 | inactive_write_throughput: 0 43 | provisioned_read_throughput: 0 44 | provisioned_write_throughput: 0 45 | index_tables_provisioning: 46 | inactive_read_throughput: 0 47 | inactive_write_throughput: 0 48 | provisioned_read_throughput: 0 49 | provisioned_write_throughput: 0 50 | retention_deletes_enabled: false 51 | retention_period: 0 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # swarmstack/loki 2 | 3 | Docker swarm compose file for Grafana Loki, like Prometheus but for logs. 4 | 5 | ## INSTALLATION 6 | 7 | On every Docker swarm node, first install Loki's Docker log driver plugin (it's important to install the plugin before modifying /etc/docker/daemon.json) 8 | 9 | ``` 10 | docker plugin install grafana/loki-docker-driver:latest --alias loki --grant-all-permissions 11 | ``` 12 | 13 | Next, add the following (at least the log-driver and log-opts below) to the file /etc/docker/daemon.json on each Docker swarm node: 14 | 15 | ``` 16 | { 17 | "debug" : false, 18 | "log-driver": "loki", 19 | "log-opts": { 20 | "loki-url": "http://127.0.0.1:3100/loki/api/v1/push" 21 | } 22 | } 23 | ``` 24 | 25 | Finally, restart the Docker daemon on each swarm node (draining nodes first if necessary) to pick up the logging change: 26 | 27 | ``` 28 | docker node ls 29 | docker node update --availability drain node1.fqdn 30 | systemctl restart docker 31 | docker node update --availability active node1.fqdn 32 | ``` 33 | 34 | ## USAGE 35 | 36 | ``` 37 | docker stack deploy -c docker-compose.yml loki 38 | ``` 39 | 40 | [swarmstack](https://github.com/swarmstack/swarmstack) users should use docker-compose-swarmstack.yml above instead. 41 | 42 | --- 43 | 44 | Log into Grafana as an administrator, and add a new Data Source (Configuration > Data Sources). You should only need to set the Name (Loki) and provide Grafana a URL to the Loki service. swarmstack users should set this to http://loki:3100 - otherwise change 'loki' to the IP or DNS of one of your Docker nodes. 45 | 46 | Logs from your container stdout and stderr will now get populated into Loki by the container stdout and stderr via the docker daemons running on each Docker swarm node. If you have a service running in a container which doesn't support writing it's output to stdout or stderr of the container (visible using "docker logs container_id" or "docker service logs service_id"), see [https://docs.docker.com/config/containers/logging/](https://docs.docker.com/config/containers/logging/) which explains what the official nginx container does by symbolically linking it's own access and error log files to the container's /dev/stdout and /dev/stderr files as one workaround. 47 | --------------------------------------------------------------------------------