Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Offer Multiple Docker Images Based on Usage/Needs #2726

Open
ranzyblessings opened this issue Feb 14, 2025 · 15 comments
Open

Offer Multiple Docker Images Based on Usage/Needs #2726

ranzyblessings opened this issue Feb 14, 2025 · 15 comments
Labels
enhancement New feature or request proposal A proposal for new functionality.

Comments

@ranzyblessings
Copy link

ranzyblessings commented Feb 14, 2025

First, I’d like to commend the Alloy team for the excellent work on the project. The transition from Promtail to Alloy in one of my open-source projects has been seamless, and the overall experience has been outstanding.

During the migration, I encountered a challenge when setting up health checks for the Alloy container. The official Alloy base image currently lacks networking tools such as nc (Netcat), wget, or curl, which are essential for reliable network-based health checks.

Request:
Could you consider offering multiple Docker images, one full-featured and another more streamlined? This approach would allow users to manage base image size and vulnerability scanning, as is typical in CI/CD pipelines.

For example, a health check using wget could be configured as follows:

  alloy:
    image: 'grafana/alloy:v1.6.1'
    container_name: 'alloy'
    volumes:
      - ./config.alloy:/etc/alloy/config.alloy
      - ../logs/application.log:/var/log/application.log
    networks:
      - observability-network
    restart: unless-stopped
    healthcheck:
      test: [ "CMD", "wget", "-qO-", "http://localhost:12345/metrics" ]
      interval: 30s
      retries: 3
      timeout: 10s
      start_period: 5s
    depends_on:
      loki:
        condition: service_healthy

Currently, without these utilities, users need to extend the Alloy image with custom Dockerfiles, adding unnecessary complexity and overhead.

Use case

Offering multiple images would allow networking tools like nc, wget, or curl to be included in the base image, simplifying container health check configurations. Users would no longer need to extend the image with custom Dockerfiles. Providing these utilities natively would improve usability and align with best practices for containerized application monitoring.

@ranzyblessings ranzyblessings added the enhancement New feature or request label Feb 14, 2025
@ranzyblessings
Copy link
Author

Should the inclusion of nc, wget, orcurl align with the team's roadmap and strategic direction for Alloy, I would be glad to contribute and submit a pull request.

@mattdurham
Copy link
Collaborator

Ideally I would like to limit and reduce the scope of the docker file, to me this would widen it in a way that opens us to more CVEs and maintenance. We have long been trying to find a way to get to more of smaller base image but journalctl support has stopped that.

@ranzyblessings
Copy link
Author

ranzyblessings commented Feb 14, 2025

That makes sense. I understand your concerns about expanding the Docker file and the potential security risks. Given this, would making tools like wget or curl optional via build-time arguments or environment variables not align with the team's direction and the use of multi-stage builds? This approach would shift the responsibility of managing base image size and vulnerability scanning to users, as is typical in CI/CD pipelines.

For reference, here's a snippet to illustrate the alignment:

# Set build-time argument to conditionally install optional packages
ARG INSTALL_OPTIONAL_PACKAGES=false

# Conditionally install wget based on the build-time argument
RUN if [ "$INSTALL_OPTIONAL_PACKAGES" = "true" ]; then \
    apt-get update && apt-get install -y wget; \
    fi

# Set the environment variable (optional, can be used at runtime)
ENV INSTALL_OPTIONAL_PACKAGES=${INSTALL_OPTIONAL_PACKAGES}

@mattdurham
Copy link
Collaborator

We have thought about multiple docker images, maybe one more full featured and one more streamlined. This would have to become proposal but it is something that reasonably is on our roadmap.

@ranzyblessings
Copy link
Author

Perfect, sounds great! Would be happy to contribute if the issue would be great for newcomers. Thanks for the feedback!

@mattdurham
Copy link
Collaborator

Do you mind editing your original comment and title to say offer multiple docker images based on usage/needs and then use the healthcheck example for a reason. That way someone doesnt have to read all the comments to figure out whats going on.

@ranzyblessings ranzyblessings changed the title Request to Include nc, wget, or curl in the Official Alloy Base Image Offer Multiple Docker Images Based on Usage/Needs Feb 14, 2025
@ranzyblessings
Copy link
Author

Do you mind editing your original comment and title to say offer multiple docker images based on usage/needs and then use the healthcheck example for a reason. That way someone doesnt have to read all the comments to figure out whats going on.

Hello, @mattdurham,

I’ve made the suggested changes. Please let me know if everything looks good or if any further adjustments are needed.

@mattdurham
Copy link
Collaborator

Looks good thank you!

@sjparkinson
Copy link

This is helpful when running on AWS ECS which makes use of the Docker health check configuration.

In the ADOT AWS collector distribution it was solved by adding a ./healthcheck command, I guess to avoid including and maintaining wget etc.

@ranzyblessings
Copy link
Author

ranzyblessings commented Feb 18, 2025

Ah, cool! By using a custom health check script instead of relying on external tools like wget or curl, you reduce the image size and minimize security risks. The Go script is more comprehensive because it checks the HTTP status, ensuring the service is functioning properly, not just that a port is open. It’s also flexible (easily change the port or path) and includes port validation, making the health check more robust. This provides a secure, self-contained solution without additional dependencies.

You can implement this Go program in your Docker container's health check as follows:

services:
  alloy:
    image: 'grafana/alloy:v1.6.1'
    container_name: 'alloy'
    healthcheck:
      test: ["CMD", "./healthcheck", "-port", "12345"]  # The port can be omitted and will default to the default port.
      interval: 30s
      retries: 3
      timeout: 10s
      start_period: 5s

Important Notice:

While this solution specifically addresses health checks, offering multiple Docker images, such as a minimal version and a more feature-rich version, could still be a valid approach. For instance:

  • Smaller base images with fewer dependencies reduce the attack surface and enhance security.
  • Larger images with additional tools (like curl, wget, or nc) might be preferred for users needing a more versatile container with added functionality to simplify debugging or customization. For example, if the container is having trouble connecting to an external service, tools like curl can help check HTTP connectivity, while nc can verify if the required ports are open from within the container.

Since I don’t work at Grafana, we’ll need to wait for @mattdurham or the team to determine if this fits with their roadmap or if there are other considerations we haven’t anticipated. The solution definitely has great potential @sjparkinson .

@wildum wildum moved this from Incoming to Active in Alloy proposals Feb 24, 2025
@ptodev
Copy link
Collaborator

ptodev commented Feb 24, 2025

Providing these utilities natively would improve usability and align with best practices for containerized application monitoring.

Hi! I always thought that the best practice is to have as small of an image as possible? From a security point of view it's always better to include less things. As @mattdurham mentioned, for example it'd be great to switch from ubuntu to a smaller base image like alpine.

@ranzyblessings
Copy link
Author

The proposal for multiple Docker images, one minimal and another more feature-rich, balances security concerns with usability needs. A minimal image aligns with best practices by reducing the attack surface and minimizing vulnerabilities. However, in some operational contexts, such as debugging, troubleshooting, or certain CI/CD workflows, a more feature-complete image with essential networking tools (e.g., curl, wget, nc) can significantly improve efficiency.

Security vulnerability scanning (e.g., Trivy, Snyk, Grype) is standard practice in CI/CD pipelines, shifting the responsibility of managing image size and vulnerabilities to users. This approach aligns with industry standards, allowing teams to choose between a minimal image for security and performance or a more functional image when additional utilities are beneficial.

By providing both options, users can effectively manage trade-offs based on their specific needs.

Your concerns are valid. Ultimately, it comes down to use case, trade-offs, and responsibility.

@ptodev
Copy link
Collaborator

ptodev commented Feb 25, 2025

It could make sense if it's clearly defined what the new image is meant to be used for. I'm just worried that if we make a "debug" image then we'd start getting various requests to add utilities to it and it'd be hard to tell what should be added and what shouldn't be. From a maintenance point of view it's much simpler just to provide a minimal image.

@ranzyblessings
Copy link
Author

ranzyblessings commented Feb 25, 2025

This suggestion comes from my experience migrating from Promtail to Alloy in one of my open-source projects. It’s standard practice to offer both a full-featured image and a streamlined one. For example, the Paketo Buildpacks project provides both minimal and feature-rich image variants, such as paketobuildpacks/builder-jammy-base (minimal) and paketobuildpacks/builder-jammy-full:latest, which I use interchangeably based on the specific use case.

Just to clarify, I’m not involved in the decision-making process to dictate changes, but I wanted to share my feedback from a user’s perspective, not as a maintainer. If the majority of users do not require container health checks (which will be a significant issue for me when I shift to Kubernetes, since the container won’t be scheduled for auto restarts and could silently cause service disruptions) or additional utilities, and are satisfied with the current image, I’m fine with that—as long as it aligns with the team’s roadmap.

@ranzyblessings
Copy link
Author

ranzyblessings commented Feb 26, 2025

Just to help everyone understand—since the original issue has been edited—the story goes like this:

While migrating from Promtail to Alloy, I discovered that Alloy doesn’t have the capability to help define health checks, which are crucial for me. I primarily work with Kubernetes, where health checks are used for container probes.

I reached out like any user would, and @mattdurham suggested a cleaner approach: offering two images (one streamlined and one feature-rich). He also asked me to modify my original comment. I had no objections, as it made sense.

@sjparkinson then provided an alternative, referencing how AWS implemented a similar solution using a Go script. This is also a brilliant idea since it eliminates the need for additional networking tools.

Later, I confirmed and explained why having multiple images would make sense. Having spent most of my career as a Platform Engineer before transitioning to an Architect, I know that debugging often takes up most of an engineer's time. For example, Grafana supports multiple data sources, and in complex environments like on-premise infrastructure (as I experienced while working at a hosting company managing our own Linux servers), there are intricate DNS and firewall rules. When debugging, it’s essential to determine whether Grafana can connect to Prometheus, if ports are being blocked, or if DNS is misconfigured from within a container. Whether this applies to Alloy, I can’t say for sure—I haven't contributed to Alloy yet.

Having the necessary tools in the container makes it easier to diagnose issues with a single command—especially in production when something suddenly stops working and time is of the utmost importance.
The Issue:

As far as I’m concerned, all I need is a health check. How it’s implemented securely and optimally is not my concern—that’s the maintainers’ job.

Now, if I were part of the team, I wouldn’t be so courteous. I’d propose multiple images. Why? Because users will extend them anyway—so why not make that task easier and do it securely?

More importantly, we maintainers know the product inside and out, unlike the average user who installs what they need while juggling 100+ other tools. We can decide what goes into the product based on our tools and stack to provide a cleaner, more secure alternative. A team of 20-30 users will benefit from the expertise of 400+ maintainers and the broader community.

And trust me—when I extend the container and later discover a security issue, I’ll report it here, probably forgetting what I even installed in the first place.

The Real Issue:
Enable the feature to help define and add health checks in Alloy. How it’s done? Not my concern—nor do I care!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request proposal A proposal for new functionality.
Projects
Status: Active
Development

No branches or pull requests

4 participants