DEV Community

Cover image for Stream Logs from Docker to Grafana Cloud with Alloy
Athreya aka Maneshwar
Athreya aka Maneshwar

Posted on • Edited on

Stream Logs from Docker to Grafana Cloud with Alloy

Hello, I'm Maneshwar. I'm building git-lrc, an AI code reviewer that runs on every commit. It is free, unlimited, and source-available on Github. Star Us to help devs discover the project. Do give it a try and share your feedback for improving the product.

Hello, I'm Maneshwar. I'm working on FreeDevTools online currently building **one place for all dev tools, cheat codes, and TLDRs* — a free, open-source hub where developers can quickly find and use tools without any hassle of searching all over the internet.

Setting up logging inside containers can be annoying — especially when logs vanish with the container or you have to mess with volume mounts just to see what's going on.

Here's how I made it super simple using Grafana Alloy to send logs from a Flask server running inside a Docker container to Grafana Cloud, without touching host volumes.

Quick Demo App: Flask Logger

Let's start w
ith a super basic Flask app that just logs requests:

# app.py
from flask import Flask
import logging

app = Flask(__name__)

logging.basicConfig(filename="liveapi.log", level=logging.INFO)

@app.route("/")
def hello():
    app.logger.info("GET / was hit")
    return "Hello, World!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=5000)
Enter fullscreen mode Exit fullscreen mode

This will create a liveapi.log file in the current working directory.

☁️ Set Up Grafana Cloud + Loki

  1. Go to Grafana Cloud.
  2. Sign up or log in.
  3. In the sidebar, go to Connections → Data sources.
  4. Search for Loki and set it up.
  5. Copy the Loki Push URL from the connection config. It'll look like:
https://<username>:<api-key>@logs-prod-000.grafana.net/api/prom/push
Enter fullscreen mode Exit fullscreen mode

You'll use this in Alloy later.

🐳 Dockerfile: Flask + Alloy Without Volume Mounts

Here's the Dockerfile that installs everything, writes logs, and sends them to Grafana Loki using Alloy:

FROM debian:bookworm-slim

RUN apt-get update && apt-get install -y \
    python3 python3-pip gpg wget curl gnupg ca-certificates systemctl \
    && rm -rf /var/lib/apt/lists/*

WORKDIR /app

COPY requirements.txt .
RUN pip3 install --no-cache-dir --break-system-packages -r requirements.txt

# Install Alloy
RUN mkdir -p /etc/apt/keyrings/ && \
    wget -q -O - https://apt.grafana.com/gpg.key | gpg --dearmor | tee /etc/apt/keyrings/grafana.gpg > /dev/null && \
    echo "deb [signed-by=/etc/apt/keyrings/grafana.gpg] https://apt.grafana.com stable main" > /etc/apt/sources.list.d/grafana.list && \
    apt-get update && apt-get install -y alloy && \
    rm -rf /var/lib/apt/lists/*

COPY . .

RUN mkdir -p /etc/alloy/ && cp config.alloy /etc/alloy/config.alloy

EXPOSE 5000

CMD systemctl restart alloy && python3 app.py
Enter fullscreen mode Exit fullscreen mode

No volume mounts. No host bind paths. Everything is self-contained inside the container.

⚙️ config.alloy (Log Pipeline for Alloy)

Create config.alloy in your repo:

local.file_match "local_files" {
  path_targets = [{ "__path__" = "/app/liveapi.log" }]
  sync_period = "5s"
}

loki.source.file "log_scrape" {
  targets       = local.file_match.local_files.targets
  forward_to    = [loki.process.filter_logs.receiver]
  tail_from_end = true
}

loki.process "filter_logs" {
  forward_to = [loki.write.grafana_loki.receiver]

  stage.static_labels {
    values = {
      job          = "liveapi"
      service_name = "liveapi"
    }
  }
}

loki.write "grafana_loki" {
  endpoint {
    url = "https://<your-username>:<your-api-key>@logs-prod-000.grafana.net/api/prom/push"
  }
}
Enter fullscreen mode Exit fullscreen mode

Change the endpoint to match your Grafana Loki Push URL.

Build & Run

Build the Docker image:

docker build -t flask-alloy .
Enter fullscreen mode Exit fullscreen mode

Run it:

docker run -p 5000:5000 flask-alloy
Enter fullscreen mode Exit fullscreen mode

Now visit http://localhost:5000 to trigger logs. Check Grafana Cloud’s Explore tab and query:

{job="liveapi"}
Enter fullscreen mode Exit fullscreen mode

Boom — your logs are in the cloud. 🎉

Any Better Way?

Let me know in the comments — is there a simpler or cooler way you’re pushing logs to Grafana Loki from containers? Would love to steal it.


I’ve been building
A collection of UI/UX-focused tools crafted to simplify workflows, save time, and reduce friction in searching tools/materials.

Any feedback or contributors are welcome!

It’s online, open-source, and ready for anyone to use.

👉 Check it out:

⭐ Star it on GitHub:

Let’s make it even better together.

git-lrc
*AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.*

Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.

⭐ Star it on GitHub:

GitHub logo HexmosTech / git-lrc

Free, Unlimited AI Code Reviews That Run on Commit

git-lrc logo

git-lrc

Free, Unlimited AI Code Reviews That Run on Commit


git-lrc - Free, unlimited AI code reviews that run on commit | Product Hunt

AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

See It In Action

See git-lrc catch serious security issues such as leaked credentials, expensive cloud operations, and sensitive material in log statements

git-lrc-intro-60s.mp4

Why

  • 🤖 AI agents silently break things. Code removed. Logic changed. Edge cases gone. You won't notice until production.
  • 🔍 Catch it before it ships. AI-powered inline comments show you exactly what changed and what looks wrong.
  • 🔁 Build a habit, ship better code. Regular review → fewer bugs → more robust code → better results in your team.
  • 🔗 Why git? Git is universal. Every editor, every IDE, every AI…




Top comments (2)

Collapse
 
nevodavid profile image
Nevo David

Amazing guide, and it's super simple to follow!

Collapse
 
lovestaco profile image
Athreya aka Maneshwar

Thanks @nevodavid :)