Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
299 changes: 187 additions & 112 deletions Source/Applications/openHistorian/openHistorian/Grafana/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,97 +1,116 @@
# syntax=docker/dockerfile:1
# syntax=docker/dockerfile:1.7-labs

ARG BASE_IMAGE=alpine:3.19.1
ARG JS_IMAGE=node:20-alpine
# to maintain formatting of multiline commands in vscode, add the following to settings.json:
# "docker.languageserver.formatter.ignoreMultilineInstructions": true

ARG GO_IMAGE=go-builder-base
ARG JS_IMAGE=js-builder-base
ARG JS_PLATFORM=linux/amd64
ARG GO_IMAGE=golang:1.23.1-alpine

# Default to building locally
ARG GO_SRC=go-builder
ARG JS_SRC=js-builder

FROM --platform=${JS_PLATFORM} ${JS_IMAGE} as js-builder
# Dependabot cannot update dependencies listed in ARGs
# By using FROM instructions we can delegate dependency updates to dependabot
FROM alpine:3.23.3 AS alpine-base
FROM ubuntu:24.04 AS ubuntu-base
FROM golang:1.25.9-alpine AS go-builder-base
FROM --platform=${JS_PLATFORM} node:24-alpine AS js-builder-base
# Javascript build stage
FROM --platform=${JS_PLATFORM} ${JS_IMAGE} AS js-builder
ARG JS_NODE_ENV=production
ARG JS_YARN_INSTALL_FLAG=--immutable
ARG JS_YARN_BUILD_FLAG=build

ENV NODE_OPTIONS=--max_old_space_size=8000

WORKDIR /tmp/grafana

RUN apk add --no-cache make build-base python3

COPY package.json project.json nx.json yarn.lock .yarnrc.yml ./
COPY .yarn .yarn
COPY packages packages
COPY plugins-bundled plugins-bundled
COPY e2e-playwright e2e-playwright
COPY public public
COPY LICENSE ./
COPY conf/defaults.ini ./conf/defaults.ini

RUN apk add --no-cache make build-base python3

RUN yarn install --immutable

COPY tsconfig.json .eslintrc .editorconfig .browserslistrc .prettierrc.js ./
COPY e2e e2e

#
# Set the node env according to defaults or argument passed
#
ENV NODE_ENV=${JS_NODE_ENV}
#
RUN if [ "$JS_YARN_INSTALL_FLAG" = "" ]; then \
yarn install; \
else \
yarn install --immutable; \
fi

COPY tsconfig.json eslint.config.js .editorconfig .browserslistrc .prettierrc.js ./
COPY scripts scripts
COPY emails emails

ENV NODE_ENV production
RUN yarn build
# Set the build argument according to default or argument passed
RUN yarn ${JS_YARN_BUILD_FLAG}

FROM ${GO_IMAGE} as go-builder
# Golang build stage
FROM ${GO_IMAGE} AS go-builder

ARG COMMIT_SHA=""
ARG BUILD_BRANCH=""
ARG GO_BUILD_TAGS="oss"
ARG WIRE_TAGS="oss"
ARG BINGO="true"

RUN if grep -i -q alpine /etc/issue; then \
apk add --no-cache \
# This is required to allow building on arm64 due to https://github.com/golang/go/issues/22040
binutils-gold \
bash \
# Install build dependencies
gcc g++ make git; \
fi
apk add --no-cache \
bash \
# Install build dependencies
make git; \
fi

WORKDIR /tmp/grafana

COPY go.* ./
COPY .bingo .bingo

# Include vendored dependencies
COPY pkg/util/xorm/go.* pkg/util/xorm/
COPY pkg/apiserver/go.* pkg/apiserver/
COPY pkg/apimachinery/go.* pkg/apimachinery/
COPY pkg/build/go.* pkg/build/
COPY pkg/build/wire/go.* pkg/build/wire/
COPY pkg/promlib/go.* pkg/promlib/
COPY pkg/storage/unified/resource/go.* pkg/storage/unified/resource/
COPY pkg/storage/unified/apistore/go.* pkg/storage/unified/apistore/
COPY pkg/semconv/go.* pkg/semconv/
COPY pkg/aggregator/go.* pkg/aggregator/
COPY apps/playlist/go.* apps/playlist/

RUN go mod download
RUN if [[ "$BINGO" = "true" ]]; then \
go install github.com/bwplotka/bingo@latest && \
bingo get -v; \
fi

COPY embed.go Makefile build.go package.json ./
COPY go.mod go.sum go.work go.work.sum ./
COPY .citools .citools

# Copy go.mod/go.sum from each workspace module for dependency caching.
# Only dependency file changes invalidate the go mod download cache layer.
# Uses --parents to preserve directory structure with fewer COPY directives.
COPY --parents **/go.mod **/go.sum ./

RUN --mount=type=cache,target=/go/pkg/mod \
go mod download

# Copy full source
COPY embed.go Makefile package.json ./
COPY cue.mod cue.mod
COPY kinds kinds
COPY kindsv2 kindsv2
COPY local local
COPY packages/grafana-schema packages/grafana-schema
COPY packages/grafana-data/src/themes/themeDefinitions packages/grafana-data/src/themes/themeDefinitions
COPY public/app/plugins public/app/plugins
COPY public/api-merged.json public/api-merged.json
COPY pkg pkg
COPY apps apps
COPY scripts scripts
COPY conf conf
COPY .github .github

ENV COMMIT_SHA=${COMMIT_SHA}
ENV BUILD_BRANCH=${BUILD_BRANCH}

RUN make build-go GO_BUILD_TAGS=${GO_BUILD_TAGS} WIRE_TAGS=${WIRE_TAGS}
RUN --mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache/go-build \
make build-go GO_BUILD_TAGS=${GO_BUILD_TAGS} WIRE_TAGS=${WIRE_TAGS}

RUN mkdir -p data/plugins-bundled

FROM ${BASE_IMAGE} as tgz-builder
# From-tarball build stage
FROM alpine-base AS tgz-builder

WORKDIR /tmp/grafana

Expand All @@ -102,91 +121,80 @@ COPY ${GRAFANA_TGZ} /tmp/grafana.tar.gz
# add -v to make tar print every file it extracts
RUN tar x -z -f /tmp/grafana.tar.gz --strip-components=1

RUN mkdir -p data/plugins-bundled

# helpers for COPY --from
FROM ${GO_SRC} as go-src
FROM ${JS_SRC} as js-src
FROM ${GO_SRC} AS go-src
FROM ${JS_SRC} AS js-src

# Final stage
FROM ${BASE_IMAGE}
# Alpine final stage
FROM alpine-base AS final-alpine

LABEL maintainer="Grafana Labs <hello@grafana.com>"
LABEL org.opencontainers.image.source="https://github.com/grafana/grafana"

ARG GF_UID="472"
ARG GF_GID="0"

ENV PATH="/usr/share/grafana/bin:$PATH" \
GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \
GF_PATHS_DATA="/var/lib/grafana" \
GF_PATHS_HOME="/usr/share/grafana" \
GF_PATHS_LOGS="/var/log/grafana" \
GF_PATHS_PLUGINS="/var/lib/grafana/plugins" \
GF_PATHS_PROVISIONING="/etc/grafana/provisioning"
GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \
GF_PATHS_DATA="/var/lib/grafana" \
GF_PATHS_HOME="/usr/share/grafana" \
GF_PATHS_LOGS="/var/log/grafana" \
GF_PATHS_PLUGINS="/var/lib/grafana/plugins" \
GF_PATHS_PROVISIONING="/etc/grafana/provisioning"

WORKDIR $GF_PATHS_HOME

# Install dependencies
RUN if grep -i -q alpine /etc/issue; then \
apk add --no-cache ca-certificates bash curl tzdata musl-utils && \
apk info -vv | sort; \
elif grep -i -q ubuntu /etc/issue; then \
DEBIAN_FRONTEND=noninteractive && \
apt-get update && \
apt-get install -y ca-certificates curl tzdata musl && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*; \
else \
echo 'ERROR: Unsupported base image' && /bin/false; \
fi
RUN apk add --no-cache ca-certificates bash bubblewrap curl tzdata musl-utils && \
apk info -vv | sort

# glibc support for alpine x86_64 only
RUN if grep -i -q alpine /etc/issue && [ `arch` = "x86_64" ]; then \
wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-2.35-r0.apk \
-O /tmp/glibc-2.35-r0.apk && \
wget https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-bin-2.35-r0.apk \
-O /tmp/glibc-bin-2.35-r0.apk && \
apk add --force-overwrite --no-cache /tmp/glibc-2.35-r0.apk /tmp/glibc-bin-2.35-r0.apk && \
rm -f /lib64/ld-linux-x86-64.so.2 && \
ln -s /usr/glibc-compat/lib64/ld-linux-x86-64.so.2 /lib64/ld-linux-x86-64.so.2 && \
rm -f /tmp/glibc-2.35-r0.apk && \
rm -f /tmp/glibc-bin-2.35-r0.apk && \
rm -f /lib/ld-linux-x86-64.so.2 && \
rm -f /etc/ld.so.cache; \
fi
# docker run --rm --env STDOUT=1 sgerrand/glibc-builder 2.40 /usr/glibc-compat > glibc-bin-2.40.tar.gz
ARG GLIBC_VERSION=2.40

RUN if [ "$(arch)" = "x86_64" ]; then \
wget -qO- "https://dl.grafana.com/glibc/glibc-bin-$GLIBC_VERSION.tar.gz" | tar zxf - -C / \
usr/glibc-compat/lib/ld-linux-x86-64.so.2 \
usr/glibc-compat/lib/libc.so.6 \
usr/glibc-compat/lib/libdl.so.2 \
usr/glibc-compat/lib/libm.so.6 \
usr/glibc-compat/lib/libpthread.so.0 \
usr/glibc-compat/lib/librt.so.1 \
usr/glibc-compat/lib/libresolv.so.2 && \
mkdir /lib64 && \
ln -s /usr/glibc-compat/lib/ld-linux-x86-64.so.2 /lib64; \
fi

COPY --from=go-src /tmp/grafana/conf ./conf

RUN if [ ! $(getent group "$GF_GID") ]; then \
if grep -i -q alpine /etc/issue; then \
addgroup -S -g $GF_GID grafana; \
else \
addgroup --system --gid $GF_GID grafana; \
fi; \
fi && \
GF_GID_NAME=$(getent group $GF_GID | cut -d':' -f1) && \
mkdir -p "$GF_PATHS_HOME/.aws" && \
if grep -i -q alpine /etc/issue; then \
adduser -S -u $GF_UID -G "$GF_GID_NAME" grafana; \
else \
adduser --system --uid $GF_UID --ingroup "$GF_GID_NAME" grafana; \
fi && \
mkdir -p "$GF_PATHS_PROVISIONING/datasources" \
"$GF_PATHS_PROVISIONING/dashboards" \
"$GF_PATHS_PROVISIONING/notifiers" \
"$GF_PATHS_PROVISIONING/plugins" \
"$GF_PATHS_PROVISIONING/access-control" \
"$GF_PATHS_PROVISIONING/alerting" \
"$GF_PATHS_LOGS" \
"$GF_PATHS_PLUGINS" \
"$GF_PATHS_DATA" && \
cp conf/sample.ini "$GF_PATHS_CONFIG" && \
cp conf/ldap.toml /etc/grafana/ldap.toml && \
chown -R "grafana:$GF_GID_NAME" "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"
RUN if [ ! "$(getent group "$GF_GID")" ]; then \
addgroup -S -g $GF_GID grafana; \
fi && \
GF_GID_NAME=$(getent group $GF_GID | cut -d':' -f1) && \
mkdir -p "$GF_PATHS_HOME/.aws" && \
adduser -S -u $GF_UID -G "$GF_GID_NAME" grafana && \
mkdir -p "$GF_PATHS_PROVISIONING/datasources" \
"$GF_PATHS_PROVISIONING/dashboards" \
"$GF_PATHS_PROVISIONING/notifiers" \
"$GF_PATHS_PROVISIONING/plugins" \
"$GF_PATHS_PROVISIONING/access-control" \
"$GF_PATHS_PROVISIONING/alerting" \
"$GF_PATHS_LOGS" \
"$GF_PATHS_PLUGINS" \
"$GF_PATHS_DATA" && \
cp conf/sample.ini "$GF_PATHS_CONFIG" && \
cp conf/ldap.toml /etc/grafana/ldap.toml && \
chown -R "grafana:$GF_GID_NAME" "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"

COPY --from=go-src /tmp/grafana/bin/grafana* /tmp/grafana/bin/*/grafana* ./bin/
COPY --from=js-src /tmp/grafana/public ./public
COPY --from=js-src /tmp/grafana/LICENSE ./
COPY --from=go-src /tmp/grafana/data/plugins-bundled ./data/plugins-bundled

RUN grafana server -v | sed -e 's/Version //' > /.grafana-version
RUN chmod 644 /.grafana-version

EXPOSE 3000

Expand All @@ -196,3 +204,70 @@ COPY ${RUN_SH} /run.sh

USER "$GF_UID"
ENTRYPOINT [ "/run.sh" ]

# Ubuntu final stage — use --target=final-ubuntu to select this variant
FROM ubuntu-base AS final-ubuntu

LABEL maintainer="Grafana Labs <hello@grafana.com>"
LABEL org.opencontainers.image.source="https://github.com/grafana/grafana"

ARG GF_UID="472"
ARG GF_GID="0"

ENV PATH="/usr/share/grafana/bin:$PATH" \
GF_PATHS_CONFIG="/etc/grafana/grafana.ini" \
GF_PATHS_DATA="/var/lib/grafana" \
GF_PATHS_HOME="/usr/share/grafana" \
GF_PATHS_LOGS="/var/log/grafana" \
GF_PATHS_PLUGINS="/var/lib/grafana/plugins" \
GF_PATHS_PROVISIONING="/etc/grafana/provisioning"

WORKDIR $GF_PATHS_HOME

RUN DEBIAN_FRONTEND=noninteractive apt-get update && \
apt-get install -y ca-certificates curl tzdata musl && \
apt-get autoremove -y && \
rm -rf /var/lib/apt/lists/*

COPY --from=go-src /tmp/grafana/conf ./conf

RUN if [ ! "$(getent group "$GF_GID")" ]; then \
groupadd --system --gid $GF_GID grafana; \
fi && \
GF_GID_NAME=$(getent group $GF_GID | cut -d':' -f1) && \
mkdir -p "$GF_PATHS_HOME/.aws" && \
useradd --system --uid $GF_UID --gid "$GF_GID_NAME" --create-home grafana && \
mkdir -p "$GF_PATHS_PROVISIONING/datasources" \
"$GF_PATHS_PROVISIONING/dashboards" \
"$GF_PATHS_PROVISIONING/notifiers" \
"$GF_PATHS_PROVISIONING/plugins" \
"$GF_PATHS_PROVISIONING/access-control" \
"$GF_PATHS_PROVISIONING/alerting" \
"$GF_PATHS_LOGS" \
"$GF_PATHS_PLUGINS" \
"$GF_PATHS_DATA" && \
cp conf/sample.ini "$GF_PATHS_CONFIG" && \
cp conf/ldap.toml /etc/grafana/ldap.toml && \
chown -R "grafana:$GF_GID_NAME" "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING" && \
chmod -R 777 "$GF_PATHS_DATA" "$GF_PATHS_HOME/.aws" "$GF_PATHS_LOGS" "$GF_PATHS_PLUGINS" "$GF_PATHS_PROVISIONING"

COPY --from=go-src /tmp/grafana/bin/grafana* /tmp/grafana/bin/*/grafana* ./bin/
COPY --from=js-src /tmp/grafana/public ./public
COPY --from=js-src /tmp/grafana/LICENSE ./
COPY --from=go-src /tmp/grafana/data/plugins-bundled ./data/plugins-bundled

RUN grafana server -v | sed -e 's/Version //' > /.grafana-version
RUN chmod 644 /.grafana-version

EXPOSE 3000

ARG RUN_SH=./packaging/docker/run.sh

COPY ${RUN_SH} /run.sh

USER "$GF_UID"
ENTRYPOINT [ "/run.sh" ]

# Default stage — alpine. Builds without --target produce an alpine image.
# Use --target=final-ubuntu to build the ubuntu variant instead.
FROM final-alpine
Loading
Loading