# syntax=docker/dockerfile:1

# Node 22 LTS on Alpine. The tag is deliberately unpinned: rebuilding this image is
# how you pick up new Node patches, Alpine packages and tool releases.
FROM node:22-alpine

# Alpine package versions are intentionally unpinned. This image tracks "current" —
# reproducibility comes from the published image tag, not from version pins that
# would rot against Alpine's rolling repositories.
# hadolint ignore=DL3018
RUN apk add --no-cache \
        bash \
        ca-certificates openssl \
        coreutils findutils diffutils gawk grep sed \
        file less patch tree \
        curl wget \
        jq \
        bind-tools iputils-ping netcat-openbsd socat rsync \
        git git-lfs openssh-client-default \
        ripgrep fd \
        tar gzip xz zip unzip \
        helm kubectl \
        make procps-ng su-exec tini tzdata

# Use bash with pipefail for the remaining build steps so a failure anywhere in a
# pipeline fails the layer.
SHELL ["/bin/bash", "-o", "pipefail", "-c"]

# yq is not packaged for Alpine, so take the current upstream release. Running the
# binary immediately is the verification that matters here: it catches a truncated
# or HTML-error-page download, which is the realistic failure mode.
RUN arch="$(apk --print-arch | sed -e 's/x86_64/amd64/' -e 's/aarch64/arm64/')" \
    && curl -fsSL -o /usr/local/bin/yq \
        "https://github.com/mikefarah/yq/releases/latest/download/yq_linux_${arch}" \
    && chmod 0755 /usr/local/bin/yq \
    && yq --version

# Defaults that keep non-interactive agent shells from hanging or failing:
#   * pagers off      — git/kubectl/helm otherwise block on `less` with no TTY
#   * no git prompts  — a private remote without creds fails fast instead of waiting
#   * helm homes /tmp — lets the image run with a read-only root filesystem
ENV PAGER=cat \
    GIT_PAGER=cat \
    GIT_TERMINAL_PROMPT=0 \
    HELM_CACHE_HOME=/tmp/.cache/helm \
    HELM_CONFIG_HOME=/tmp/.config/helm \
    HELM_DATA_HOME=/tmp/.local/share/helm

# tini reaps the grandchildren a shell workload leaves behind; the base image's
# docker-entrypoint.sh is kept so `node`-style invocations still work.
ENTRYPOINT ["/sbin/tini", "--", "docker-entrypoint.sh"]
CMD ["bash"]

# Last, so bumping build metadata does not invalidate the layers above.
ARG VERSION=dev
ARG REVISION=unknown
ARG CREATED=unknown
LABEL org.opencontainers.image.title="node-agent" \
      org.opencontainers.image.description="Node 22 LTS on Alpine with a GNU shell, network, and Kubernetes toolchain for AI agent command execution" \
      org.opencontainers.image.source="https://gitea.libretechconsulting.com/rmcguire/images" \
      org.opencontainers.image.base.name="docker.io/library/node:22-alpine" \
      org.opencontainers.image.version="${VERSION}" \
      org.opencontainers.image.revision="${REVISION}" \
      org.opencontainers.image.created="${CREATED}"
