Ctrl K
ComunidadGuías…

Dockerfile

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Unified host-agent image. One container, s6-supervised, bundles:
#
#   fan-controller         — adaptive Dell PowerEdge fan PID
#   node_exporter          — :9100  host CPU/mem/disk/net + textfile
#   cadvisor               — :8089  per-container metrics
#   ipmi_exporter          — :9290  chassis sensors
#   smartctl_exporter      — :9633  drive SMART
#   nvidia_gpu_exporter    — :9835  GPU temp/util/mem/power
#   vmagent                — push all of the above to central Prometheus
#                            (hardcoded remote_write URL, host label =
#                             kernel hostname). No per-host config; the
#                             dashboard is a pure receiver.
#
# Each sub-service probes its hardware on start and `sleep infinity` if
# absent — same image runs on Dell + non-Dell, GPU + headless, Debian +
# Unraid hosts with no per-host build.
#
# Base: Alpine (was Debian-slim through v0.2.0).
#   - The fan-controller is pure Go static (CGO_ENABLED=0); the upstream
#     exporter binaries are also Go-static. None require glibc.
#   - nvidia-smi IS injected glibc-linked by the NVIDIA Container
#     Runtime on GPU hosts. We install `gcompat` (musl→glibc shim) so
#     nvidia_gpu_exporter's nvidia-smi shellouts still work.
#   - Save ~60 MB on the base layer vs debian-slim.
#
# UPX: all Go binaries are compressed with `upx --best --lzma`. Costs
# ~50ms decompression-on-exec. For long-running services, free 30-50%
# image shrink. Skipped if upx fails on a particular binary (some
# binaries with complex section layouts refuse to pack).

# -------- go-builder: compile the Go v2 fan controller --------
# Same source tree the bash script lives in; we copy host-agent/go.mod
# + the Go source dirs. Built static (CGO_ENABLED=0) + stripped so the
# final image stays small. VERSION is stamped into main.version via
# -ldflags so `fan-controller --version` (if we ever add the flag)
# matches /etc/host-agent-version.
FROM golang:1.27-alpine AS go-builder
ARG VERSION=dev
RUN apk add --no-cache upx
WORKDIR /src
COPY go.mod ./
COPY cmd/      cmd/
COPY internal/ internal/
RUN CGO_ENABLED=0 go build \
      -trimpath \
      -ldflags="-s -w -X main.version=${VERSION}" \
      -o /fan-controller \
      ./cmd/fan-controller \
 && upx --best --lzma /fan-controller || true

# -------- builder: fetch the Go binaries from upstream releases --------
# Run UPX --best --lzma against each. `|| true` so a refusal on any
# single binary doesn't abort the whole build — we get the uncompressed
# version in that case.
FROM alpine:3 AS builder

ARG NODE_EXPORTER_VERSION=1.8.2
ARG CADVISOR_VERSION=0.55.1
ARG IPMI_EXPORTER_VERSION=1.10.0
ARG SMARTCTL_EXPORTER_VERSION=0.13.0
ARG NVIDIA_GPU_EXPORTER_VERSION=1.4.1
ARG VMAGENT_VERSION=1.108.0

RUN apk add --no-cache curl ca-certificates tar xz upx

WORKDIR /tmp
RUN curl -fsSL -o node.tgz \
      "https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz" \
 && tar -xzf node.tgz \
 && cp "node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64/node_exporter" /node_exporter \
 && upx --best --lzma /node_exporter || true

RUN curl -fsSL -o /cadvisor \
      "https://github.com/google/cadvisor/releases/download/v${CADVISOR_VERSION}/cadvisor-v${CADVISOR_VERSION}-linux-amd64" \
 && chmod +x /cadvisor \
 && upx --best --lzma /cadvisor || true

RUN curl -fsSL -o ipmi.tgz \
      "https://github.com/prometheus-community/ipmi_exporter/releases/download/v${IPMI_EXPORTER_VERSION}/ipmi_exporter-${IPMI_EXPORTER_VERSION}.linux-amd64.tar.gz" \
 && tar -xzf ipmi.tgz \
 && cp "ipmi_exporter-${IPMI_EXPORTER_VERSION}.linux-amd64/ipmi_exporter" /ipmi_exporter \
 && upx --best --lzma /ipmi_exporter || true

RUN curl -fsSL -o smartctl.tgz \
      "https://github.com/prometheus-community/smartctl_exporter/releases/download/v${SMARTCTL_EXPORTER_VERSION}/smartctl_exporter-${SMARTCTL_EXPORTER_VERSION}.linux-amd64.tar.gz" \
 && tar -xzf smartctl.tgz \
 && cp "smartctl_exporter-${SMARTCTL_EXPORTER_VERSION}.linux-amd64/smartctl_exporter" /smartctl_exporter \
 && upx --best --lzma /smartctl_exporter || true

RUN curl -fsSL -o nvidia.tgz \
      "https://github.com/utkuozdemir/nvidia_gpu_exporter/releases/download/v${NVIDIA_GPU_EXPORTER_VERSION}/nvidia_gpu_exporter_${NVIDIA_GPU_EXPORTER_VERSION}_linux_x86_64.tar.gz" \
 && tar -xzf nvidia.tgz \
 && cp nvidia_gpu_exporter /nvidia_gpu_exporter \
 && upx --best --lzma /nvidia_gpu_exporter || true

RUN curl -fsSL -o vmutils.tgz \
      "https://github.com/VictoriaMetrics/VictoriaMetrics/releases/download/v${VMAGENT_VERSION}/vmutils-linux-amd64-v${VMAGENT_VERSION}.tar.gz" \
 && tar -xzf vmutils.tgz vmagent-prod \
 && mv vmagent-prod /vmagent \
 && upx --best --lzma /vmagent || true


# -------- runtime --------
FROM alpine:3

# Short git SHA baked at build time. vmagent reads /etc/host-agent-version
# and stamps it onto every sample as the `version` external_label, so the
# dashboard can show which build is running per host. Defaults to "dev"
# for local builds.
ARG VERSION=dev
ARG S6_OVERLAY_VERSION=3.2.0.2
RUN echo "$VERSION" > /etc/host-agent-version

# OS tools needed by sub-services:
#   ipmitool, freeipmi    — chassis sensors / Dell raw fan commands
#   smartmontools         — drive SMART (smartctl_exporter shells out)
#   dmidecode             — chassis detection by fan-controller
#   gcompat               — musl→glibc shim (lets glibc-linked
#                           nvidia-smi run on Alpine; nvidia-smi is
#                           injected by NVIDIA Container Runtime on
#                           GPU hosts, not bundled here)
#   ca-certificates       — TLS to GitHub releases, push endpoints
#   mawk, xz, tini, procps — shell tooling for s6 run scripts +
#                            startup probes
RUN apk add --no-cache \
      ipmitool freeipmi smartmontools dmidecode \
      gcompat \
      ca-certificates mawk xz tini procps

# s6-overlay (PID 1, restarts crashed sub-services individually)
ADD "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-noarch.tar.xz" /tmp/
ADD "https://github.com/just-containers/s6-overlay/releases/download/v${S6_OVERLAY_VERSION}/s6-overlay-x86_64.tar.xz" /tmp/
RUN tar -Jxpf /tmp/s6-overlay-noarch.tar.xz -C / \
 && tar -Jxpf /tmp/s6-overlay-x86_64.tar.xz -C / \
 && rm /tmp/s6-overlay-*.tar.xz

# Exporter binaries (already UPX-compressed in builder stage)
COPY --from=builder /node_exporter        /usr/local/bin/node_exporter
COPY --from=builder /cadvisor             /usr/local/bin/cadvisor
COPY --from=builder /ipmi_exporter        /usr/local/bin/ipmi_exporter
COPY --from=builder /smartctl_exporter    /usr/local/bin/smartctl_exporter
COPY --from=builder /nvidia_gpu_exporter  /usr/local/bin/nvidia_gpu_exporter
COPY --from=builder /vmagent              /usr/local/bin/vmagent

# Fan controller (Go v2, UPX-compressed) + per-chassis profiles.
COPY --from=go-builder /fan-controller /usr/local/bin/fan-controller
COPY profiles/                              /etc/fan-controller/profiles/
RUN chmod +x /usr/local/bin/fan-controller

# s6 service definitions: one per sub-service, each probes its hardware
COPY s6/ /etc/s6-overlay/s6-rc.d/
COPY docker-entrypoint.sh /usr/local/bin/host-agent-entrypoint
RUN chmod +x /usr/local/bin/host-agent-entrypoint

ENV S6_KEEP_ENV=1 \
    S6_BEHAVIOUR_IF_STAGE2_FAILS=2 \
    S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0

ENTRYPOINT ["/usr/local/bin/host-agent-entrypoint"]