mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Build: Unified dockerfile for all builds (#59173)
* unified dockerfile for all builds * update builder * include docker commands and output in logs * quiet docker build * quiet gsutil
This commit is contained in:
38
Dockerfile
38
Dockerfile
@@ -1,16 +1,12 @@
|
||||
######################## IMPORTANT ########################
|
||||
#
|
||||
# There are 2 Dockerfiles which must be kept in sync:
|
||||
#
|
||||
# - Dockerfile
|
||||
# - packaging/docker/Dockerfile
|
||||
#
|
||||
###########################################################
|
||||
# syntax=docker/dockerfile:1
|
||||
|
||||
ARG BASE_IMAGE=alpine:3.15
|
||||
ARG JS_IMAGE=node:16-alpine3.15
|
||||
ARG GO_IMAGE=golang:1.19.3-alpine3.15
|
||||
|
||||
ARG GO_SRC=go-builder
|
||||
ARG JS_SRC=js-builder
|
||||
|
||||
FROM ${JS_IMAGE} as js-builder
|
||||
|
||||
ENV NODE_OPTIONS=--max_old_space_size=8000
|
||||
@@ -56,9 +52,25 @@ COPY public/app/plugins public/app/plugins
|
||||
COPY public/api-spec.json public/api-spec.json
|
||||
COPY pkg pkg
|
||||
COPY scripts scripts
|
||||
COPY conf conf
|
||||
|
||||
RUN make build-go
|
||||
|
||||
FROM ${BASE_IMAGE} as tgz-builder
|
||||
|
||||
WORKDIR /tmp/grafana
|
||||
|
||||
ARG GRAFANA_TGZ="grafana-latest.linux-x64-musl.tar.gz"
|
||||
|
||||
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
|
||||
|
||||
# helpers for COPY --from
|
||||
FROM ${GO_SRC} as go-src
|
||||
FROM ${JS_SRC} as js-src
|
||||
|
||||
# Final stage
|
||||
FROM ${BASE_IMAGE}
|
||||
|
||||
@@ -106,7 +118,7 @@ RUN if grep -i -q alpine /etc/issue && [ `arch` = "x86_64" ]; then \
|
||||
rm -f /etc/ld.so.cache; \
|
||||
fi
|
||||
|
||||
COPY conf ./conf
|
||||
COPY --from=go-src /tmp/grafana/conf ./conf
|
||||
|
||||
RUN if [ ! $(getent group "$GF_GID") ]; then \
|
||||
if grep -i -q alpine /etc/issue; then \
|
||||
@@ -136,12 +148,14 @@ RUN if [ ! $(getent group "$GF_GID") ]; then \
|
||||
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-builder /tmp/grafana/bin/*/grafana-server /tmp/grafana/bin/*/grafana-cli /tmp/grafana/bin/*/grafana ./bin/
|
||||
COPY --from=js-builder /tmp/grafana/public ./public
|
||||
COPY --from=go-src /tmp/grafana/bin/grafana* /tmp/grafana/bin/*/grafana* ./bin/
|
||||
COPY --from=js-src /tmp/grafana/public ./public
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
COPY ./packaging/docker/run.sh /run.sh
|
||||
ARG RUN_SH=./packaging/docker/run.sh
|
||||
|
||||
COPY ${RUN_SH} /run.sh
|
||||
|
||||
USER "$GF_UID"
|
||||
ENTRYPOINT [ "/run.sh" ]
|
||||
|
||||
2
Makefile
2
Makefile
@@ -158,11 +158,13 @@ shellcheck: $(SH_FILES) ## Run checks for shell scripts.
|
||||
|
||||
build-docker-full: ## Build Docker image for development.
|
||||
@echo "build docker container"
|
||||
DOCKER_BUILDKIT=1 \
|
||||
docker build \
|
||||
--tag grafana/grafana:dev .
|
||||
|
||||
build-docker-full-ubuntu: ## Build Docker image based on Ubuntu for development.
|
||||
@echo "build docker container"
|
||||
DOCKER_BUILDKIT=1 \
|
||||
docker build \
|
||||
--build-arg BASE_IMAGE=ubuntu:20.04 \
|
||||
--build-arg GO_IMAGE=golang:1.19.3 \
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
######################## IMPORTANT ########################
|
||||
#
|
||||
# There are 2 Dockerfiles which must be kept in sync:
|
||||
#
|
||||
# - Dockerfile
|
||||
# - packaging/docker/Dockerfile
|
||||
#
|
||||
###########################################################
|
||||
|
||||
ARG BASE_IMAGE=alpine:3.15
|
||||
|
||||
FROM ${BASE_IMAGE} as tgz-builder
|
||||
|
||||
WORKDIR /tmp/grafana
|
||||
|
||||
ARG GRAFANA_TGZ="grafana-latest.linux-x64-musl.tar.gz"
|
||||
|
||||
# Make sure we have Gnu tar
|
||||
RUN if grep -i -q alpine /etc/issue; then \
|
||||
apk add --no-cache tar; \
|
||||
fi
|
||||
|
||||
COPY ${GRAFANA_TGZ} /tmp/grafana.tar.gz
|
||||
|
||||
# Change to tar xfzv to make tar print every file it extracts
|
||||
RUN tar xzf /tmp/grafana.tar.gz --strip-components=1 -C /tmp/grafana
|
||||
|
||||
# Final stage
|
||||
FROM ${BASE_IMAGE}
|
||||
|
||||
LABEL maintainer="Grafana Labs <hello@grafana.com>"
|
||||
|
||||
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
|
||||
|
||||
# Install dependencies
|
||||
RUN if grep -i -q alpine /etc/issue; then \
|
||||
apk add --no-cache ca-certificates bash 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 && \
|
||||
apt-get autoremove -y && \
|
||||
rm -rf /var/lib/apt/lists/*; \
|
||||
else \
|
||||
echo 'ERROR: Unsupported base image' && /bin/false; \
|
||||
fi
|
||||
|
||||
# glibc support for alpine x86_64 only
|
||||
RUN if grep -i -q alpine /etc/issue && [ `arch` = "x86_64" ]; then \
|
||||
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 --no-cache --allow-untrusted /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
|
||||
|
||||
COPY --from=tgz-builder /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"
|
||||
|
||||
COPY --from=tgz-builder /tmp/grafana/bin/grafana-server /tmp/grafana/bin/grafana-cli ./bin/
|
||||
COPY --from=tgz-builder /tmp/grafana/public ./public
|
||||
|
||||
EXPOSE 3000
|
||||
|
||||
COPY ./run.sh /run.sh
|
||||
|
||||
USER "$GF_UID"
|
||||
ENTRYPOINT [ "/run.sh" ]
|
||||
@@ -1,51 +0,0 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
UBUNTU_BASE=0
|
||||
TAG_SUFFIX=""
|
||||
|
||||
while [ "$1" != "" ]; do
|
||||
case "$1" in
|
||||
"--ubuntu")
|
||||
UBUNTU_BASE=1
|
||||
TAG_SUFFIX="-ubuntu"
|
||||
echo "Ubuntu base image enabled"
|
||||
shift
|
||||
;;
|
||||
* )
|
||||
# unknown param causes args to be passed through to $@
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
_raw_grafana_tag=$1
|
||||
_docker_repo=${2:-grafana/grafana-enterprise}
|
||||
|
||||
if echo "$_raw_grafana_tag" | grep -q "^v"; then
|
||||
_grafana_tag=$(echo "${_raw_grafana_tag}" | cut -d "v" -f 2)
|
||||
elif echo "$_raw_grafana_tag" | grep -q "^main-"; then
|
||||
_grafana_tag="main"
|
||||
else
|
||||
_grafana_tag="${_raw_grafana_tag}"
|
||||
fi
|
||||
|
||||
echo "Building and deploying ${_docker_repo}:${_grafana_tag}${TAG_SUFFIX}"
|
||||
|
||||
docker build \
|
||||
--tag "${_docker_repo}:${_grafana_tag}${TAG_SUFFIX}" \
|
||||
--no-cache=true \
|
||||
.
|
||||
|
||||
docker push "${_docker_repo}:${_grafana_tag}${TAG_SUFFIX}"
|
||||
|
||||
if echo "$_raw_grafana_tag" | grep -q "^v" && echo "$_raw_grafana_tag" | grep -qv "beta"; then
|
||||
docker tag "${_docker_repo}:${_grafana_tag}${TAG_SUFFIX}" "${_docker_repo}:latest${TAG_SUFFIX}"
|
||||
docker push "${_docker_repo}:latest${TAG_SUFFIX}"
|
||||
fi
|
||||
|
||||
|
||||
if echo "${_raw_grafana_tag}" | grep -q "^main-" && [ ${UBUNTU_BASE} = "1" ]; then
|
||||
docker tag "${_docker_repo}:${_grafana_tag}${TAG_SUFFIX}" "grafana/grafana-enterprise-dev:${_raw_grafana_tag}"
|
||||
docker push "grafana/grafana-enterprise-dev:${_raw_grafana_tag}"
|
||||
fi
|
||||
@@ -68,11 +68,16 @@ docker_build () {
|
||||
grafana_tgz=${GRAFANA_TGZ:-"grafana-latest.linux-${arch}${libc}.tar.gz"}
|
||||
tag="${_docker_repo}${repo_arch}:${_grafana_version}${TAG_SUFFIX}"
|
||||
|
||||
DOCKER_BUILDKIT=1 \
|
||||
docker build \
|
||||
--build-arg BASE_IMAGE=${base_image} \
|
||||
--build-arg GRAFANA_TGZ=${grafana_tgz} \
|
||||
--build-arg GO_SRC=tgz-builder \
|
||||
--build-arg JS_SRC=tgz-builder \
|
||||
--build-arg RUN_SH=./run.sh \
|
||||
--tag "${tag}" \
|
||||
--no-cache=true \
|
||||
--file ../../Dockerfile \
|
||||
.
|
||||
}
|
||||
|
||||
|
||||
@@ -116,33 +116,49 @@ func BuildImage(version string, arch config.Architecture, grafanaDir string, use
|
||||
tags = append(tags, tag)
|
||||
|
||||
args := []string{
|
||||
"build", "--build-arg", fmt.Sprintf("BASE_IMAGE=%s", baseImage),
|
||||
"--build-arg", fmt.Sprintf("GRAFANA_TGZ=%s", archive), "--tag", tag, "--no-cache",
|
||||
"build",
|
||||
"-q",
|
||||
"--build-arg", fmt.Sprintf("BASE_IMAGE=%s", baseImage),
|
||||
"--build-arg", fmt.Sprintf("GRAFANA_TGZ=%s", archive),
|
||||
"--build-arg", "GO_SRC=tgz-builder",
|
||||
"--build-arg", "JS_SRC=tgz-builder",
|
||||
"--build-arg", "RUN_SH=./run.sh",
|
||||
"--tag", tag,
|
||||
"--no-cache",
|
||||
"--file", "../../Dockerfile",
|
||||
".",
|
||||
}
|
||||
|
||||
log.Printf("Running Docker: docker %s", strings.Join(args, " "))
|
||||
//nolint:gosec
|
||||
cmd := exec.Command("docker", args...)
|
||||
cmd.Dir = buildDir
|
||||
cmd.Env = append(os.Environ(), "DOCKER_CLI_EXPERIMENTAL=enabled")
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return []string{}, fmt.Errorf("building Docker image failed: %w\n%s", err, output)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Env = append(os.Environ(), "DOCKER_CLI_EXPERIMENTAL=enabled", "DOCKER_BUILDKIT=1")
|
||||
log.Printf("Running Docker: DOCKER_CLI_EXPERIMENTAL=enabled DOCKER_BUILDKIT=1 %s", cmd)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return []string{}, fmt.Errorf("building Docker image failed: %w", err)
|
||||
}
|
||||
if shouldSave {
|
||||
imageFile := fmt.Sprintf("%s-%s%s-%s.img", imageFileBase, version, tagSuffix, arch)
|
||||
//nolint:gosec
|
||||
cmd = exec.Command("docker", "save", tag, "-o", imageFile)
|
||||
cmd.Dir = buildDir
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return []string{}, fmt.Errorf("saving Docker image failed: %w\n%s", err, output)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
log.Printf("Running Docker: %s", cmd)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return []string{}, fmt.Errorf("saving Docker image failed: %w", err)
|
||||
}
|
||||
gcsURL := fmt.Sprintf("gs://grafana-prerelease/artifacts/docker/%s/%s", version, imageFile)
|
||||
//nolint:gosec
|
||||
cmd = exec.Command("gsutil", "cp", imageFile, gcsURL)
|
||||
cmd = exec.Command("gsutil", "-q", "cp", imageFile, gcsURL)
|
||||
cmd.Dir = buildDir
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return []string{}, fmt.Errorf("storing Docker image failed: %w\n%s", err, output)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
log.Printf("Running gsutil: %s", cmd)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return []string{}, fmt.Errorf("storing Docker image failed: %w", err)
|
||||
}
|
||||
log.Printf("Docker image %s stored to grafana-prerelease GCS bucket", imageFile)
|
||||
}
|
||||
@@ -152,8 +168,11 @@ func BuildImage(version string, arch config.Architecture, grafanaDir string, use
|
||||
//nolint:gosec
|
||||
cmd = exec.Command("docker", "tag", tag, additionalTag)
|
||||
cmd.Dir = buildDir
|
||||
if output, err := cmd.CombinedOutput(); err != nil {
|
||||
return []string{}, fmt.Errorf("tagging Docker image failed: %w\n%s", err, output)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
log.Printf("Running Docker: %s", cmd)
|
||||
if err := cmd.Run(); err != nil {
|
||||
return []string{}, fmt.Errorf("tagging Docker image failed: %w", err)
|
||||
}
|
||||
tags = append(tags, additionalTag)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user