<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/medium-viy71lpa4" -->

---
title: Medium | daily.dev
description: Part 4 of a self-hosting series covers setting up a full observability stack (Prometheus, Grafana, Loki) on a resource-constrained 2 vCPU/8 GB VPS running K3s,...
canonical: https://daily.dev/posts/medium-viy71lpa4
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: Medium | daily.dev
og:description: Part 4 of a self-hosting series covers setting up a full observability stack (Prometheus, Grafana, Loki) on a resource-constrained 2 vCPU/8 GB VPS running K3s,...
og:url: https://daily.dev/posts/medium-viy71lpa4
og:image: https://api.daily.dev/og/posts/Viy71lpa4.png
og:image:alt: Medium
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Medium

**[Medium](https://daily.dev/sources/medium_js)** · 8 min read · 0 upvotes · 0 comments

## Summary

Part 4 of a self-hosting series covers setting up a full observability stack (Prometheus, Grafana, Loki) on a resource-constrained 2 vCPU/8 GB VPS running K3s, plus a GitHub Actions CI/CD pipeline. The post documents three Helm installation traps specific to K3s (admission webhook hangs, TLS misconfiguration, ResourceQuota conflicts), how to safely expose Grafana behind Traefik with basic auth, and five real pipeline failures with their fixes — including pnpm version conflicts, module-level SDK instantiation in Next.js, Docker build context issues in a monorepo, GitHub Container Registry permissions, and corrupted SSH secrets. A bonus debugging story explains a Next.js ISR caching bug caused by missing credentials at build time, fixed with a route-level revalidate export.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://medium.com/@a.deutou/self-hosting-like-a-pro-part-4-monitoring-with-prometheus-grafana-and-loki-plus-a-ci-cd-239b50949233>

## Questions this post answers

### Why does my kube-prometheus-stack Helm install hang on a pre-install job with a timed out waiting for the condition error?

The chart runs a pre-install job that generates TLS certificates for its admission webhooks, and on a single-node cluster this job can hang indefinitely, blocking the install. Since the webhooks are dispensable on a personal single-node cluster, disable them with --set prometheusOperator.admissionWebhooks.enabled=false, patch.enabled=false, and tls.enabled=false during helm install.

_daily.dev surfaces fixes like this for developers wiring up Prometheus on lightweight Kubernetes clusters._

### Why is my Next.js page stuck serving stale static content even though I set a revalidate option inside my fetch call?

Next.js only marks a page for incremental static regeneration if it observes an actual fetch call with a revalidate option during the build. If the fetch is guarded and skipped during build (for example, due to missing credentials), no fetch runs, so the page is treated as fully static and cached forever. Exporting revalidate at the route level (export const revalidate = 300) forces regeneration regardless of what happened at build time.

_Developers debugging frozen ISR pages in Next.js can find this kind of build-time gotcha through daily.dev._

### Why does my Grafana Helm chart deployment show zero pods with no error message on the Deployment?

A ResourceQuota requiring every container to declare CPU and memory limits can silently reject pods from third-party charts whose init containers (like init-chown-data) ship without resource declarations. The Deployment shows desired pods but zero current pods with no visible error; the actual quota rejection message only appears when running kubectl describe on the ReplicaSet, not the Deployment.

_daily.dev helps developers troubleshooting silent Kubernetes quota failures find this kind of debugging pattern._

## Similar posts on daily.dev

- [Production-Grade Kubernetes Monitoring with Prometheus, Grafana, and kube-state-metrics](https://daily.dev/posts/production-grade-kubernetes-monitoring-with-prometheus-grafana-and-kube-state-metrics-hdukjp3rk) · Medium · 2 upvotes · 0 comments
- [The Grafana trust problem](https://daily.dev/posts/the-grafana-trust-problem-rpyvryzcn) · Hacker News · 57 upvotes · 4 comments
- [Kubernetes Monitoring Tools: What Actually Works at Scale](https://daily.dev/posts/kubernetes-monitoring-tools-what-actually-works-at-scale-zdg0bbpod) · Last9 · 2 upvotes · 0 comments
- [K3s: A Better Way to Deploy a Docker App to a Linux Server](https://daily.dev/posts/k3s-a-better-way-to-deploy-a-docker-app-to-a-linux-server-p8llrvwh7) · Atomic Spin · 16 upvotes · 1 comments
- [Building a Zero-to-Hero Prometheus Dashboard for Kubernetes](https://daily.dev/posts/building-a-zero-to-hero-prometheus-dashboard-for-kubernetes-qhetrpyoj) · Medium · 0 upvotes · 0 comments

---

Tags: [#kubernetes](https://daily.dev/tags/kubernetes), [#cicd](https://daily.dev/tags/cicd), [#self-hosting](https://daily.dev/tags/self-hosting), [#grafana](https://daily.dev/tags/grafana), [#prometheus](https://daily.dev/tags/prometheus)

[View this post on daily.dev](https://daily.dev/posts/medium-viy71lpa4)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"Medium","url":"https://daily.dev/posts/medium-viy71lpa4","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/medium-viy71lpa4"},"datePublished":"2026-07-26T19:32:32.253Z","dateModified":"2026-09-14T06:26:34.080Z","description":"Part 4 of a self-hosting series covers setting up a full observability stack (Prometheus, Grafana, Loki) on a resource-constrained 2 vCPU/8 GB VPS running K3s,...","image":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/f0e399ed8b85a57afbfa0cdb1951cebf?_a=AQAEuop","thumbnailUrl":"https://media.daily.dev/image/upload/f_auto,q_auto/v1/posts/f0e399ed8b85a57afbfa0cdb1951cebf?_a=AQAEuop","isAccessibleForFree":true,"articleSection":"Medium","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"Medium","logo":"https://media.daily.dev/image/upload/t_logo,f_auto/v1/logos/medium","url":"https://daily.dev/sources/medium_js"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/medium-viy71lpa4","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"kubernetes,cicd,self-hosting,grafana,prometheus","timeRequired":"PT8M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"Medium","item":"https://daily.dev/sources/medium_js"},{"@type":"ListItem","position":3,"name":"Medium"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/medium-viy71lpa4#faq","mainEntity":[{"@type":"Question","name":"Why does my kube-prometheus-stack Helm install hang on a pre-install job with a timed out waiting for the condition error?","acceptedAnswer":{"@type":"Answer","text":"The chart runs a pre-install job that generates TLS certificates for its admission webhooks, and on a single-node cluster this job can hang indefinitely, blocking the install. Since the webhooks are dispensable on a personal single-node cluster, disable them with --set prometheusOperator.admissionWebhooks.enabled=false, patch.enabled=false, and tls.enabled=false during helm install. daily.dev surfaces fixes like this for developers wiring up Prometheus on lightweight Kubernetes clusters."}},{"@type":"Question","name":"Why is my Next.js page stuck serving stale static content even though I set a revalidate option inside my fetch call?","acceptedAnswer":{"@type":"Answer","text":"Next.js only marks a page for incremental static regeneration if it observes an actual fetch call with a revalidate option during the build. If the fetch is guarded and skipped during build (for example, due to missing credentials), no fetch runs, so the page is treated as fully static and cached forever. Exporting revalidate at the route level (export const revalidate = 300) forces regeneration regardless of what happened at build time. Developers debugging frozen ISR pages in Next.js can find this kind of build-time gotcha through daily.dev."}},{"@type":"Question","name":"Why does my Grafana Helm chart deployment show zero pods with no error message on the Deployment?","acceptedAnswer":{"@type":"Answer","text":"A ResourceQuota requiring every container to declare CPU and memory limits can silently reject pods from third-party charts whose init containers (like init-chown-data) ship without resource declarations. The Deployment shows desired pods but zero current pods with no visible error; the actual quota rejection message only appears when running kubectl describe on the ReplicaSet, not the Deployment. daily.dev helps developers troubleshooting silent Kubernetes quota failures find this kind of debugging pattern."}}]}
```

