backstage-demo-janus-showcase/.rhdh/docker/Dockerfile
Med Mouine 089a1cd890 config
2024-04-18 10:23:04 -04:00

236 lines
11 KiB
Docker

#
# Copyright (c) 2023 Red Hat, Inc.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# To transform into Brew-friendly Dockerfile:
# 1. comment out lines with EXTERNAL_SOURCE=. and CONTAINER_SOURCE=/opt/app-root/src
# 2. uncomment lines with EXTERNAL_SOURCE and CONTAINER_SOURCE pointing at $REMOTE_SOURCES and $REMOTE_SOURCES_DIR instead (Brew defines these paths)
# 3. uncomment lines with RUN source .../cachito.env
# 4. add Brew metadata
# Stage 1 - Build nodejs skeleton
#@follow_tag(registry.access.redhat.com/ubi9/nodejs-18:1)
FROM registry.access.redhat.com/ubi9/nodejs-18:1-98 AS build
# hadolint ignore=DL3002
USER 0
# Install isolated-vm dependencies
# hadolint ignore=DL3041
RUN dnf install -y -q --allowerasing --nobest nodejs-devel nodejs-libs \
# already installed or installed as deps:
openssl openssl-devel ca-certificates make cmake cpp gcc gcc-c++ zlib zlib-devel brotli brotli-devel python3 nodejs-packaging && \
dnf update -y && dnf clean all
# Downstream sources
ENV EXTERNAL_SOURCE=$REMOTE_SOURCES/upstream1/app
ENV EXTERNAL_SOURCE_NESTED=$EXTERNAL_SOURCE/distgit/containers/rhdh-hub
# /remote-source/
ENV CONTAINER_SOURCE=$REMOTE_SOURCES_DIR
# Env vars
ENV YARN=$CONTAINER_SOURCE/.yarn/releases/yarn-1.22.19.cjs
WORKDIR $CONTAINER_SOURCE/
COPY $EXTERNAL_SOURCE_NESTED/.yarn ./.yarn
COPY $EXTERNAL_SOURCE_NESTED/.yarnrc.yml ./
RUN chmod +x $YARN
# Stage 2 - Install dependencies
COPY $EXTERNAL_SOURCE_NESTED/dynamic-plugins/ ./dynamic-plugins/
COPY $EXTERNAL_SOURCE_NESTED/package.json $EXTERNAL_SOURCE_NESTED/yarn.lock ./
COPY $EXTERNAL_SOURCE_NESTED/packages/app/package.json ./packages/app/package.json
COPY $EXTERNAL_SOURCE_NESTED/packages/backend/package.json ./packages/backend/package.json
COPY $EXTERNAL_SOURCE_NESTED/plugins/scalprum-backend/package.json ./plugins/scalprum-backend/package.json
COPY $EXTERNAL_SOURCE_NESTED/plugins/dynamic-plugins-info-backend/package.json ./plugins/dynamic-plugins-info-backend/package.json
COPY $EXTERNAL_SOURCE_NESTED/plugins/auth-backend-module-oidc-provider/package.json ./plugins/auth-backend-module-oidc-provider/package.json
# Downstream only - debugging
# COPY $REMOTE_SOURCES/ ./
# hadolint ignore=SC2086
# RUN for d in $(find / -name ".npmrc" -o -name ".yarnrc" 2>/dev/null); do echo; echo "==== $d ===="; cat $d; done
# # ls -la ./ upstream1 upstream1/app/ upstream1/app/distgit/containers/ upstream1/app/distgit/containers/rhdh-hub/ || true
# # debug contents of /remote-source/
# echo "###### /tmp/tls-ca-bundle.pem ######>>"; cat /tmp/tls-ca-bundle.pem; echo "<<###### /tmp/tls-ca-bundle.pem ######"
# echo "###### $CONTAINER_SOURCE/registry-ca.pem ######>>"; cat $CONTAINER_SOURCE/registry-ca.pem; echo "<<###### $CONTAINER_SOURCE/registry-ca.pem ######"
# Downstream only - Cachito configuration
# see https://docs.engineering.redhat.com/pages/viewpage.action?pageId=228017926#UpstreamSources(Cachito,ContainerFirst)-CachitoIntegrationfornpm
COPY $REMOTE_SOURCES/upstream1/cachito.env \
$REMOTE_SOURCES/upstream1/app/registry-ca.pem \
$REMOTE_SOURCES/upstream1/app/distgit/containers/rhdh-hub/.npmrc \
./
# registry=https://cachito-nexus.engineering.redhat.com/repository/cachito-yarn-814335/
# email=noreply@domain.local
# always-auth=true
# //cachito-nexus.engineering.redhat.com/repository/cachito-yarn-814335/:_auth=SHA-goes-here==
# fetch-retries=5
# fetch-retry-factor=2
# strict-ssl=true
# cafile="../../../registry-ca.pem"
# NOTE: this is overridden to "/remote-source/registry-ca.pem" below
# hadolint ignore=SC1091,SC2046
RUN \
# debug
# cat $CONTAINER_SOURCE/cachito.env; \
# load envs
source $CONTAINER_SOURCE/cachito.env; \
\
# load cert
cert_path=$CONTAINER_SOURCE/registry-ca.pem; \
# debug
# ls -la "${cert_path}"; \
npm config set cafile "${cert_path}"; $YARN config set cafile "${cert_path}" -g; \
\
# set longer timeouts
# npm config set fetch-retry-maxtimeout 6000000; \
# npm config set fetch-retry-mintimeout 1000000; \
$YARN config set network-timeout 600000 -g; \
# set cachito as default registry
$YARN config set registry $(npm config get registry) -g; \
\
# debug
# ls -l /usr/; \
# set up node dir with common.gypi and unsafe-perms=true
ln -s /usr/include/node/common.gypi /usr/common.gypi; $YARN config set nodedir /usr; $YARN config set unsafe-perm true; \
\
# add yarn to path via symlink
ln -s $CONTAINER_SOURCE/$YARN /usr/local/bin/yarn
# Downstream only - debug
# RUN echo $PATH; ls -la /usr/local/bin/yarn; whereis yarn;which yarn; yarn --version; \
# cat $CONTAINER_SOURCE/.npmrc || true; \
# $YARN config list --verbose; npm config list; npm config list -l
RUN $YARN install --frozen-lockfile --network-timeout 600000
# Stage 3 - Build packages
COPY $EXTERNAL_SOURCE_NESTED ./
RUN git config --global --add safe.directory ./
# Upstream only
# RUN rm app-config.yaml && mv app-config.example.yaml app-config.yaml
# hadolint ignore=DL3059,DL4006,SC2086
RUN $YARN build --filter=backend && \
# Build dynamic plugins: yarn.lock files need to be present in order to transform to point to cachito URLs
$YARN --cwd ./dynamic-plugins/imports export-dynamic --no-install && \
# Downstream only - replace registry refs with cachito ones
cachitoRegistry=$(npm config get registry); echo "cachito registry: $cachitoRegistry"; \
for d in $(find . -name yarn.lock); do echo; echo "===== $d ====="; \
sed -i $d -r -e "s#(https://registry.yarnpkg.com|https://registry.npmjs.org)#${cachitoRegistry}#g"; \
grep resolved $d | head -1; echo "Total $(grep resolved $d | wc -l) resolution lines in $d"; \
done; \
# Already imported the packages above; need to `yarn install` on the `dist-dynamic` sub-folder for backend plugins
$YARN --cwd ./dynamic-plugins/imports install-dynamic && \
$YARN export-dynamic -- --filter=./dynamic-plugins/wrappers/* && \
$YARN copy-dynamic-plugins dist
# Downstream only - debug
# hadolint ignore=SC3010,DL4006
RUN echo "=== Check for yarn.lock files that don't use cachito registry ===>"; \
for d in $(find . -name yarn.lock); do \
found=$(grep -E "yarnpkg.com|npmjs.org" $d | head -1); \
if [[ $found ]]; then echo;echo "$d : $found"; fi; \
done; \
echo "<=== Check for yarn.lock files that don't use cachito registry ==="
# Downstream only - clean up dynamic plugins sources:
# Only keep the dist sub-folder in the dynamic-plugins folder
RUN find dynamic-plugins -maxdepth 1 -mindepth 1 -type d -not -name dist -exec rm -Rf {} \;
# Stage 4 - Build the actual backend image and install production dependencies
# Downstream only - files already exist, nothing to copy; next line for debugging only
# RUN ls -l $CONTAINER_SOURCE/ $CONTAINER_SOURCE/packages/backend/dist/
ENV TARBALL_PATH=./packages/backend/dist
RUN tar xzf $TARBALL_PATH/skeleton.tar.gz; tar xzf $TARBALL_PATH/bundle.tar.gz; \
rm -f $TARBALL_PATH/skeleton.tar.gz $TARBALL_PATH/bundle.tar.gz
# Copy app-config files needed in runtime
# Upstream only
# COPY $EXTERNAL_SOURCE_NESTED/app-config*.yaml ./
# COPY $EXTERNAL_SOURCE_NESTED/dynamic-plugins.default.yaml ./
# Install production dependencies
# hadolint ignore=DL3059
RUN $YARN install --frozen-lockfile --production --network-timeout 600000
# Stage 5 - Build the runner image
#@follow_tag(registry.access.redhat.com/ubi9/nodejs-18-minimal:1)
FROM registry.access.redhat.com/ubi9/nodejs-18-minimal:1-103 AS runner
USER 0
ENV CONTAINER_SOURCE=/opt/app-root/src
WORKDIR $CONTAINER_SOURCE/
# Downstream only - install techdocs dependencies using cachito sources
COPY $REMOTE_SOURCES/upstream2 $REMOTE_SOURCES_DIR/upstream2/
# hadolint ignore=DL3013,DL3041,SC2086
RUN microdnf update -y && \
microdnf install -y python3.11 python3.11-pip python3.11-devel make cmake cpp gcc gcc-c++; \
ln -s /usr/bin/pip3.11 /usr/bin/pip3; \
ln -s /usr/bin/pip3.11 /usr/bin/pip; \
# ls -la $REMOTE_SOURCES_DIR/ $REMOTE_SOURCES_DIR/upstream2/ $REMOTE_SOURCES_DIR/upstream2/app/distgit/containers/rhdh-hub/docker/ || true; \
# cat $REMOTE_SOURCES_DIR/upstream2/cachito.env && \
# cachito.env contains path to cert:
# export PIP_CERT=/remote-source/upstream2/app/package-index-ca.pem
source $REMOTE_SOURCES_DIR/upstream2/cachito.env && \
# fix ownership for pip install folder
mkdir -p /opt/app-root/src/.cache/pip && chown -R root:root /opt/app-root && \
# ls -ld /opt/ /opt/app-root /opt/app-root/src/ /opt/app-root/src/.cache /opt/app-root/src/.cache/pip || true; \
pushd $REMOTE_SOURCES_DIR/upstream2/app/distgit/containers/rhdh-hub/docker/ >/dev/null && \
set -xe; \
python3.11 -V; pip3.11 -V; \
pip3.11 install --no-cache-dir --upgrade pip setuptools pyyaml; \
pip3.11 install --no-cache-dir -r requirements.txt -r requirements-build.txt; mkdocs --version; \
popd >/dev/null; \
microdnf clean all; rm -fr $REMOTE_SOURCES_DIR/upstream2
# Downstream only - Make python3.11 the default python
RUN alternatives --install /usr/bin/python python /usr/bin/python3.11 1
# Downstream only - copy from build, not cleanup stage
COPY --from=build --chown=1001:1001 $REMOTE_SOURCES_DIR/ ./
# Downstream only - copy embedded dynamic plugins from $REMOTE_SOURCES_DIR
COPY --from=build $REMOTE_SOURCES_DIR/dynamic-plugins/dist/ ./dynamic-plugins/dist/
# Copy script to gather dynamic plugins; copy embedded dynamic plugins to root folder; fix permissions
COPY docker/install-dynamic-plugins.py docker/install-dynamic-plugins.sh ./
RUN chmod -R a+r ./dynamic-plugins/ ./install-dynamic-plugins.py; \
chmod -R a+rx ./install-dynamic-plugins.sh; \
rm -fr dynamic-plugins-root && cp -R dynamic-plugins/dist/ dynamic-plugins-root
# Downstream only - fix for https://issues.redhat.com/browse/RHIDP-728
RUN mkdir /opt/app-root/src/.npm
RUN chown -R 1001:1001 /opt/app-root/src/.npm
# The fix-permissions script is important when operating in environments that dynamically use a random UID at runtime, such as OpenShift.
# The upstream backstage image does not account for this and it causes the container to fail at runtime.
RUN fix-permissions ./
# Switch to nodejs user
USER 1001
# Temporary workaround to avoid triggering issue
# https://github.com/backstage/backstage/issues/20644
ENV CHOKIDAR_USEPOLLING='1' CHOKIDAR_INTERVAL='10000'
# To avoid running scripts when using `npm pack` to install dynamic plugins
ENV NPM_CONFIG_ignore-scripts='true'
ENTRYPOINT ["node", "packages/backend", "--config", "app-config.yaml", "--config", "app-config.example.yaml", "--config", "app-config.example.production.yaml"]
# append Brew metadata here