Skip to main content

Docker Compose Setup

Introduction

Docker Compose provides a straightforward way to deploy Grafana Loki and its dependencies in a local environment. This approach is perfect for development, testing, or small-scale deployments. In this guide, we'll walk through setting up a complete Grafana Loki stack using Docker Compose, which allows you to define and run multi-container Docker applications with a single configuration file.

Docker Compose simplifies the process of managing multiple interconnected services by:

  • Defining all services in a single YAML file
  • Managing networking between containers automatically
  • Providing volume management for persistent data
  • Enabling easy scaling and updates to your deployment

Prerequisites

Before getting started, ensure you have:

  • Docker installed on your system
  • Docker Compose installed (included with Docker Desktop for Windows/Mac)
  • Basic understanding of Docker concepts
  • At least 4GB of available RAM for the stack

Basic Docker Compose Setup for Loki

Let's start with a basic Docker Compose configuration that includes Grafana Loki, Promtail (for log collection), and Grafana (for visualization).

Create a new file named docker-compose.yml with the following content:

yaml
version: "3"

services:
loki:
image: grafana/loki:2.9.0
ports:
- "3100:3100"
command: -config.file=/etc/loki/local-config.yaml
volumes:
- loki-data:/loki

promtail:
image: grafana/promtail:2.9.0
volumes:
- /var/log:/var/log
- ./promtail-config.yaml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
depends_on:
- loki

grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
volumes:
- grafana-data:/var/lib/grafana
depends_on:
- loki

volumes:
loki-data:
grafana-data:

Now, let's create the Promtail configuration file. Create a new file named promtail-config.yaml:

yaml
server:
http_listen_port: 9080
grpc_listen_port: 0

positions:
filename: /tmp/positions.yaml

clients:
- url: http://loki:3100/loki/api/v1/push

scrape_configs:
- job_name: system
static_configs:
- targets:
- localhost
labels:
job: varlogs
__path__: /var/log/*log

Starting the Stack

With both files in place, you can start the stack using:

bash
docker-compose up -d

This command starts all three services in detached mode. You can now access:

Configuring Grafana to Use Loki

Once Grafana is running, you'll need to configure it to use Loki as a data source:

  1. Open Grafana in your browser at http://localhost:3000
  2. Navigate to Configuration > Data Sources
  3. Click "Add data source"
  4. Select "Loki" from the list
  5. Set the URL to http://loki:3100
  6. Click "Save & Test"

You should see a "Data source connected and labels found" success message.

Advanced Docker Compose Configuration

For production-like environments or more complex setups, you might want a more comprehensive configuration. The following example includes:

  • Loki configured in microservices mode
  • Persistent volumes for all components
  • Minio for object storage
  • More extensive configuration options
yaml
version: "3"

services:
# Loki components in microservices mode
loki-gateway:
image: nginx:alpine
ports:
- "3100:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- loki-query-frontend
- loki-distributor

loki-distributor:
image: grafana/loki:2.9.0
command: -config.file=/etc/loki/config.yaml -target=distributor
volumes:
- ./loki-microservices-config.yaml:/etc/loki/config.yaml
depends_on:
- minio

loki-ingester:
image: grafana/loki:2.9.0
command: -config.file=/etc/loki/config.yaml -target=ingester
volumes:
- ./loki-microservices-config.yaml:/etc/loki/config.yaml
- loki-ingester-data:/loki/data
depends_on:
- minio

loki-querier:
image: grafana/loki:2.9.0
command: -config.file=/etc/loki/config.yaml -target=querier
volumes:
- ./loki-microservices-config.yaml:/etc/loki/config.yaml
depends_on:
- loki-ingester
- minio

loki-query-frontend:
image: grafana/loki:2.9.0
command: -config.file=/etc/loki/config.yaml -target=query-frontend
volumes:
- ./loki-microservices-config.yaml:/etc/loki/config.yaml
depends_on:
- loki-querier

# Minio for object storage
minio:
image: minio/minio
ports:
- "9000:9000"
volumes:
- minio-data:/data
environment:
- MINIO_ACCESS_KEY=minioadmin
- MINIO_SECRET_KEY=minioadmin
command: server /data

# Create the required buckets in Minio
minio-setup:
image: minio/mc
depends_on:
- minio
entrypoint: >
/bin/sh -c "
/usr/bin/mc alias set minio http://minio:9000 minioadmin minioadmin;
/usr/bin/mc mb minio/loki-data;
exit 0;
"

# Promtail for log collection
promtail:
image: grafana/promtail:2.9.0
volumes:
- /var/log:/var/log
- ./promtail-config.yaml:/etc/promtail/config.yml
command: -config.file=/etc/promtail/config.yml
depends_on:
- loki-distributor

# Grafana for visualization
grafana:
image: grafana/grafana:latest
ports:
- "3000:3000"
environment:
- GF_AUTH_ANONYMOUS_ENABLED=true
- GF_AUTH_ANONYMOUS_ORG_ROLE=Admin
- GF_INSTALL_PLUGINS=grafana-piechart-panel
volumes:
- grafana-data:/var/lib/grafana
- ./grafana-datasources.yaml:/etc/grafana/provisioning/datasources/datasources.yaml
depends_on:
- loki-gateway

volumes:
loki-ingester-data:
minio-data:
grafana-data:

This advanced setup requires additional configuration files which are beyond the scope of this basic guide, but demonstrates how Docker Compose can scale from simple to complex deployments.

Understanding the Docker Compose File

Let's break down the key components of our Docker Compose configuration:

  1. version: Specifies the Docker Compose file format version.

  2. services: Defines the containers that make up your application.

    • loki: The main Loki service that stores and indexes logs
    • promtail: An agent that ships the contents of local logs to Loki
    • grafana: The visualization platform to query and display logs from Loki
  3. volumes: Defines persistent storage volumes that can be mounted into containers.

    • loki-data: Stores Loki's indexed data
    • grafana-data: Stores Grafana configurations and dashboards
  4. ports: Maps container ports to host ports.

    • 3100:3100: Exposes Loki's API on port 3100
    • 3000:3000: Exposes Grafana's web interface on port 3000
  5. depends_on: Specifies service dependencies and startup order.

Monitoring and Managing Your Deployment

Once your Loki stack is running, you can monitor and manage it using Docker Compose commands:

bash
# View logs from all services
docker-compose logs

# View logs from a specific service
docker-compose logs loki

# Follow logs in real-time
docker-compose logs -f

# Stop all services
docker-compose down

# Stop all services and remove volumes (caution: this deletes all data)
docker-compose down -v

# Restart a specific service
docker-compose restart promtail

Working with Loki

With the stack running, you can use Grafana to query logs stored in Loki using LogQL. Here's a simple query to get you started:

  1. In Grafana, go to Explore
  2. Select "Loki" as the data source
  3. Enter a LogQL query like: {job="varlogs"}
  4. Click "Run Query"

This will display all logs collected from your system's /var/log directory.

Scaling for Production

While Docker Compose is excellent for development and small deployments, for production environments you might want to consider:

  1. Using Kubernetes with Helm charts for better scalability and management
  2. Implementing a separate object storage solution like S3 or GCS
  3. Setting up proper authentication and TLS encryption
  4. Configuring appropriate resource limits and replicas

Troubleshooting Common Issues

Loki fails to start

If Loki fails to start, check:

  • If another application is using port 3100
  • If there are permission issues with the volume mounts
  • Log output using docker-compose logs loki

No logs appearing in Grafana

If you're not seeing logs in Grafana:

  • Verify Promtail is running with docker-compose ps
  • Check Promtail logs with docker-compose logs promtail
  • Ensure the Loki data source is configured correctly in Grafana
  • Verify your LogQL query matches the labels Promtail is sending

Out of memory errors

Loki can be memory-intensive. If you're experiencing OOM errors:

  • Increase Docker's allocated memory
  • Adjust Loki's configuration to use less memory
  • Consider using microservices mode for better resource distribution

Summary

Docker Compose provides a convenient way to deploy Grafana Loki along with its supporting services. In this guide, we've covered:

  • Setting up a basic Loki stack with Docker Compose
  • Configuring Grafana to visualize logs from Loki
  • Advanced deployment options for more complex setups
  • Monitoring and managing your deployment
  • Troubleshooting common issues

This approach is ideal for development, testing, and small production environments. As your log volume grows, you might want to consider more scalable deployment options like Kubernetes.

Additional Resources

To further your understanding of Docker Compose with Grafana Loki:

Exercises

  1. Modify the Promtail configuration to collect logs from a specific application.
  2. Add a second Promtail instance to collect logs from another host.
  3. Create a Grafana dashboard that displays error logs from your system.
  4. Configure Loki to use object storage instead of the local filesystem.
  5. Implement a log rotation policy to manage disk usage.

By working through these exercises, you'll gain practical experience with managing Loki deployments and integrating them into your observability stack.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)