diff --git a/.dockerignore b/.dockerignore index 1df915d24611c..73e3c4731fa2c 100644 --- a/.dockerignore +++ b/.dockerignore @@ -22,3 +22,4 @@ node_modules !.yarn/plugins !.yarn/versions !.yarn/cache +Dockerfile.pluralkit diff --git a/.github/workflows/pluralkit-docker.yml b/.github/workflows/pluralkit-docker.yml new file mode 100644 index 0000000000000..d10102c1ed479 --- /dev/null +++ b/.github/workflows/pluralkit-docker.yml @@ -0,0 +1,37 @@ +name: Build and push Docker image +on: push + +jobs: + build: + runs-on: ubuntu-latest + permissions: + packages: write + if: github.repository == 'PluralKit/grafana' + steps: + - uses: docker/login-action@v1 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.CR_PAT }} + - uses: actions/checkout@v2 + - run: echo "BRANCH_NAME=${GITHUB_REF#refs/heads/}" | sed 's|/|-|g' >> $GITHUB_ENV + + - name: Extract Docker metadata + id: meta + uses: docker/metadata-action@v3 + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=raw,value=${{ github.sha }} + flavor: | + latest=false + + - uses: docker/build-push-action@v2 + with: + # https://github.com/docker/build-push-action/issues/378 + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + cache-from: type=registry,ref=ghcr.io/pluralkit/grafana:${{ env.BRANCH_NAME }} + cache-to: type=inline + diff --git a/Dockerfile.pluralkit b/Dockerfile.pluralkit new file mode 100644 index 0000000000000..d11ae971820b4 --- /dev/null +++ b/Dockerfile.pluralkit @@ -0,0 +1,104 @@ +FROM alpine:latest AS js-src +RUN apk add nodejs-current yarn +WORKDIR /tmp/grafana +COPY . . +RUN yarn install --immutable +RUN yarn dev + +FROM alpine:edge AS go-src +RUN apk add go bash binutils-gold gcc g++ make git make +WORKDIR /tmp/grafana +COPY . . +RUN make build-go + +# Final stage +FROM alpine:latest + +LABEL maintainer="Grafana Labs " + +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 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 + +# 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 + +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" + +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 ./ + +EXPOSE 3000 + +ARG RUN_SH=./packaging/docker/run.sh + +COPY ${RUN_SH} /run.sh + +USER "$GF_UID" +ENTRYPOINT [ "/run.sh" ] +