Skip to content

Commit

Permalink
Merge pull request #3783 from bcgov/NDT-308-Rework-build-and-move-to-…
Browse files Browse the repository at this point in the history
…Next.js-compiler

Ndt 308 rework build and move to next.js compiler
  • Loading branch information
rafasdc authored Jan 15, 2025
2 parents d6804e7 + 7660d16 commit e752c96
Show file tree
Hide file tree
Showing 53 changed files with 3,571 additions and 1,390 deletions.
30 changes: 10 additions & 20 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,12 @@ jobs:
packages: write
name: ${{ matrix.name }}
steps:
- name: Checkout repository
- name: Checkout
uses: actions/checkout@v4
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
id: buildx
uses: docker/setup-buildx-action@v3
with:
install: true
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
Expand All @@ -57,43 +56,34 @@ jobs:
tags: |
type=sha,format=long,prefix=sha-
latest
- name: Log in to the Container registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ matrix.name }}-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-${{ matrix.name }}
- name: Build and push Docker image
env:
GIT_HASH: ${{ env.GIT_HASH }}
SENTRY_AUTH_TOKEN: ${{ env.SENTRY_AUTH_TOKEN }}
uses: docker/build-push-action@v6
with:
context: ${{ matrix.context }}
builder: ${{ steps.buildx.outputs.name }}
# builder: ${{ steps.buildx.outputs.name }}
push: true
file: ${{ matrix.dockerfile }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
SENTRY_AUTH_TOKEN=${{ env.SENTRY_AUTH_TOKEN }}
GIT_HASH=${{ env.GIT_HASH }}
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new
cache-from: type=gha
cache-to: type=gha,mode=max
# Temp fix
# https://github.com/docker/build-push-action/issues/252
# https://github.com/moby/buildkit/issues/1896
- name: Move cache
run: |
rm -rf /tmp/.buildx-cache
mv /tmp/.buildx-cache-new /tmp/.buildx-cache
# - name: Move cache
# run: |
# rm -rf /tmp/.buildx-cache
# mv /tmp/.buildx-cache-new /tmp/.buildx-cache
12 changes: 0 additions & 12 deletions app/.babelrc

This file was deleted.

1 change: 1 addition & 0 deletions app/.eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.js
!*.cy.js
!e2e.js
instrumentation.ts
3 changes: 3 additions & 0 deletions app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,6 @@ yalc.lock
# Persisted queries
.persisted_operations
/schema/queryMap.json

# Sentry Config File
.env.sentry-build-plugin
161 changes: 96 additions & 65 deletions app/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
FROM registry.access.redhat.com/ubi9/s2i-base@sha256:77267c08bec417e9abc486241cab8ebc2c39693ed649ebc0a82f775db679b16a
# Base stage to install global dependencies
FROM node:20-alpine AS base

ENV SUMMARY="An image for the CONN-CCBC-portal app" \
DESCRIPTION="This image contains the compiled CONN-CCBC-portal node app"
Expand All @@ -12,79 +13,109 @@ LABEL summary="$SUMMARY" \
vendor="Province of British Columbia" \
maintainer="Romer, Meherzad CITZ:EX <[email protected]>"

ENV USER_ID=1001
ENV APP_HOME=/root
ENV HOME=/root
# Environment variables
ARG GIT_HASH
ENV GIT_HASH=${GIT_HASH}
ARG SENTRY_AUTH_TOKEN

Check warning on line 18 in app/Dockerfile

View workflow job for this annotation

GitHub Actions / build / app

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ARG "SENTRY_AUTH_TOKEN") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV USER_ID=1001
ENV APP_HOME=/application
ENV GIT_HASH=${GIT_HASH}
ENV SENTRY_AUTH_TOKEN=${SENTRY_AUTH_TOKEN}

Check warning on line 22 in app/Dockerfile

View workflow job for this annotation

GitHub Actions / build / app

Sensitive data should not be used in the ARG or ENV commands

SecretsUsedInArgOrEnv: Do not use ARG or ENV instructions for sensitive data (ENV "SENTRY_AUTH_TOKEN") More info: https://docs.docker.com/go/dockerfile/rule/secrets-used-in-arg-or-env/
ENV UPLOAD_DIR=${APP_HOME}/uploads

WORKDIR ${APP_HOME}

RUN INSTALL_PKGS="yarn-1.22.18-1" && \
yum -y update && \
curl --silent --location https://dl.yarnpkg.com/rpm/yarn.repo > /etc/yum.repos.d/yarn.repo && \
rpm --import https://dl.yarnpkg.com/rpm/pubkey.gpg && \
yum -y install --setopt=tsflags=nodocs $INSTALL_PKGS && \
rpm -V $INSTALL_PKGS && \
yum -y clean all --enablerepo='*' && \
rm -rf /var/cache

# Install asdf package manager
RUN git clone https://github.com/asdf-vm/asdf.git ${APP_HOME}/asdf --branch v0.8.1 && \
cd ${APP_HOME}/asdf && \
git checkout v0.8.1
ENV BASH_ENV="${APP_HOME}/asdf/asdf.sh"
# Because asdf is loaded via BASH_ENV, all commands using adsf need to be executed using /usr/bin/env bash -c
SHELL ["/usr/bin/env", "bash", "-c"]

# The app container only needs yarn and node; make sure they're installed
COPY .tool-versions ${APP_HOME}/.tool-versions
RUN sed -i -nr '/node|yarn/p' ${APP_HOME}/.tool-versions && \
cat ${APP_HOME}/.tool-versions | cut -f 1 -d ' ' | xargs -n 1 asdf plugin-add && \
asdf plugin-update --all && \
asdf install && \
asdf reshim && \
pushd ${APP_HOME}/.asdf/installs/nodejs/$(awk '/^nodejs/ { print $2 }' .tool-versions)/lib && \
npm i npm corepack && \
rm -f package.json package-lock.json && \
popd

ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.0/dumb-init_1.2.0_amd64 /usr/local/bin/dumb-init
RUN chmod +x /usr/local/bin/dumb-init
ENTRYPOINT ["dumb-init", "--", "/usr/bin/env", "bash", "-c"]

COPY app/ ${APP_HOME}/

# FIX CVE-2022-29244
RUN rm -rf /usr/local/bin/npm \
&& rm -rf /root/.npm
# Install system dependencies
RUN apk add --no-cache libc6-compat

# 1ST STAGE: INSTALL ALL DEPENDENCIES NEEDED FOR BUILD --

# Install both dev and prod dependencies during build
FROM base AS deps

# Copy only package.json yarn.lock and the patches for caching purposes
COPY app/patches patches
COPY app/package.json .
COPY app/yarn.lock .

# Install all dependencies (including dev) to ensure build tools are available
RUN yarn --frozen-lockfile

# -- END OF 1ST STAGE --

# -- 2ND STAGE: BUILD THE APP --

# Build the app
FROM base AS builder

# Copy node_modules from the deps stage
COPY --from=deps ${APP_HOME}/node_modules ./node_modules

# Copy the application source code
COPY app/ .

# Build the app (compile Relay, server, and Next.js)
ENV NODE_ENV=production
RUN yarn build:relay
RUN yarn build:server
RUN yarn build:next

# -- END OF 2ND STAGE --

# -- 3RD STAGE: PRODUCTION DEPENDENCIES --

# Separate stage for production dependencies to leverage Docker caching
FROM base AS prod-deps

# Copy only package.json yarn.lock and the patches for caching purposes
COPY app/patches patches
COPY app/package.json .
COPY app/yarn.lock .

# Install only production dependencies so this layer can be cached separately
RUN yarn install --frozen-lockfile --production=true --prefer-offline

# -- END OF 3RD STAGE --

# -- FINAL STAGE --
# Production image to run the application
FROM node:20-alpine AS runner

# Env variables for the final image
ENV APP_HOME=/application
ENV UPLOAD_DIR=${APP_HOME}/uploads
ENV USER_ID=1001
ENV NODE_ENV=production
ENV ENABLE_ANALYTICS=true

RUN PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 CYPRESS_INSTALL_BINARY=0 \
yarn install --frozen-lockfile --production=false && \
yarn build:relay && \
yarn build:server && \
yarn build:next && \
yarn install --frozen-lockfile --production=true && \
yarn cache clean && \
# Make everything in the home group-writable to support OpenShift's restricted SCC
# Needs to be done as root to chown
# same layer as yarn install to keep re-chowned files from using up several hundred MBs more space
chown -R ${USER_ID}:0 ${APP_HOME} && \
chmod -R g+rwX ${APP_HOME}

# Create a directory for uploads
RUN mkdir -p ${UPLOAD_DIR} && \
chown -R ${USER_ID}:0 ${UPLOAD_DIR} && \
chmod -R g+rw ${UPLOAD_DIR}

EXPOSE 3000 9000
USER ${USER_ID}
WORKDIR ${APP_HOME}

CMD ["yarn start"]
# Create a non-root user for OCP
RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001

COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/public ./public
COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/.next ./.next
COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/.persisted_operations ./.persisted_operations
COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/config ./config
COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/schema ./schema
COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/*.json5 .
COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/*.ts .
COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/*.js .
COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/*.properties .
COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/*.json .
COPY --from=builder --chown=${USER_ID}:0 ${APP_HOME}/dist ./dist

# Copy production dependencies
COPY --from=prod-deps --chown=${USER_ID}:0 ${APP_HOME}/node_modules ./node_modules

# Make sure uploads directory has proper permission
RUN mkdir -p ${UPLOAD_DIR}
RUN chown -PR ${USER_ID}:0 ${UPLOAD_DIR}
RUN chmod -R g+rw ${UPLOAD_DIR}

# Run as the non-root user
USER ${USER_ID}

# Expose ports
EXPOSE 3000 9000

# Command to run the application
CMD ["node", "--unhandled-rejections=strict", "--enable-network-family-autoselection", "dist/server.js"]
13 changes: 0 additions & 13 deletions app/babel.config.json

This file was deleted.

2 changes: 1 addition & 1 deletion app/backend/lib/express-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ export const isDeployedToOpenShift =
export const commonFormidableConfig: formidable.Options = {
maxFileSize: 8000000,
keepExtensions: false,
uploadDir: isDeployedToOpenShift ? '/root/uploads' : undefined,
uploadDir: isDeployedToOpenShift ? '/application/uploads' : undefined,
allowEmptyFiles: true,
minFileSize: 0,
};
19 changes: 0 additions & 19 deletions app/backend/lib/graphql/resolveFileUpload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,6 @@ if (!isDeployedToOpenShift) {
}

export const saveRemoteFile = async (stream) => {
const transaction = Sentry.startTransaction({ name: 'ccbc.function' });
const span = transaction.startChild({
op: 'resolve-file-upload',
description: 'resolveFileUpload saveRemoteFile function',
});
span.setData('start-of-funciton-call', new Date().toISOString());

try {
console.time('saveRemoteFile');

Expand Down Expand Up @@ -79,29 +72,17 @@ export const saveRemoteFile = async (stream) => {
const uploadProgressInMB =
Math.round((progress.loaded / 1000000) * 10) / 10;
console.log(`Uploaded ${uploadProgressInMB}MB`);
transaction.setMeasurement('memoryUsed', uploadProgressInMB, 'megabtye');
});
span.setData('upload-start', new Date().toISOString());
const data = await parallelUploads3.done();
span.setData('upload-finish', new Date().toISOString());

const key = (data as CompleteMultipartUploadCommandOutput)?.Key;

if (!key) {
throw new Error('Data does not contain a key');
}

span.setStatus('ok');
span.finish();
transaction.finish();

return key;
} catch (err) {
span.setData('error-obj', err);
span.setStatus('unknown_error');
span.finish();
transaction.finish();

console.log('Error', err);
throw new Error(err);
} finally {
Expand Down
2 changes: 1 addition & 1 deletion app/cypress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const happoTask = require('happo-cypress/task');
export default defineConfig({
video: false,
pageLoadTimeout: 100000,
retries: 3,
retries: 4,
fixturesFolder: '../db/data',
e2e: {
setupNodeEvents(on, config) {
Expand Down
Loading

0 comments on commit e752c96

Please sign in to comment.