diff --git a/.github/workflows/build-package.yml b/.github/workflows/build-package.yml index 19c55f5..fdd4d3e 100644 --- a/.github/workflows/build-package.yml +++ b/.github/workflows/build-package.yml @@ -56,5 +56,5 @@ jobs: --builder=buildx-multi-arch \ --provenance=false \ --build-arg TAG=$IMAGE_TAG \ - --file Dockerfile \ + --file Dockerfile.ubi-minimal \ --tag=quay.io/microcks/microcks-postman-runtime:$IMAGE_TAG . \ No newline at end of file diff --git a/Dockerfile.ubi-minimal b/Dockerfile.ubi-minimal new file mode 100644 index 0000000..26caa86 --- /dev/null +++ b/Dockerfile.ubi-minimal @@ -0,0 +1,54 @@ +FROM registry.access.redhat.com/ubi9/ubi-minimal:9.4-1194 + +MAINTAINER Laurent Broudoux + +# Some version information +LABEL io.k8s.description="Microcks is Open Source Kubernetes native tool for API Mocking and Testing" \ + io.k8s.display-name="Microcks Postman Runtime" \ + maintainer="Laurent Broudoux " + +ENV NODEJS_VERSION=20 + +# Install Node runtime +RUN INSTALL_PKGS="nodejs npm tar which" \ + && microdnf -y module disable nodejs \ + && microdnf -y module enable nodejs:$NODEJS_VERSION \ + && microdnf -y --nodocs --setopt=install_weak_deps=0 install $INSTALL_PKGS \ + && node -v | grep -qe "^v$NODEJS_VERSION\." && echo "Found VERSION $NODEJS_VERSION" \ + && microdnf clean all \ + && rm /var/lib/rpm/rpmdb.sqlite \ + && rm -rf /mnt/rootfs/var/cache/* /mnt/rootfs/var/log/dnf* /mnt/rootfs/var/log/yum.* + +# Set the running environment as production +ENV NODE_ENV production +ENV LOG_LEVEL info +ENV PORT 3000 + +# Define working directory +ENV APP_ROOT=/app +WORKDIR ${APP_ROOT} + +# root for build stages +USER root + +# Copy files and install dependencies +COPY lib/ ${APP_ROOT}/lib +COPY bin/ ${APP_ROOT}/bin +COPY package*.json ${APP_ROOT} +COPY app.js ${APP_ROOT} +RUN cd ${APP_ROOT} \ + && npm install \ + && rm -rdf ${APP_ROOT}/.npm /tmp/v8-compile-cache-0 + +### Setup user for build execution and application runtime +ENV HOME=${APP_ROOT} +RUN chmod -R u+x ${APP_ROOT}/bin && \ + chgrp -R 0 ${APP_ROOT} && \ + chmod -R g=u ${APP_ROOT} /etc/passwd + +### Containers should NOT run as root as a good practice +USER 1001 + +# Executing defaults +EXPOSE 3000 +ENTRYPOINT [ "/app/bin/uid_entrypoint" ] \ No newline at end of file diff --git a/app.js b/app.js index 41570cd..156a8a6 100644 --- a/app.js +++ b/app.js @@ -57,15 +57,19 @@ app.post('/tests/:testResultId', function (req, res) { // Check validity and warn if missing. if (operation == undefined) { + winston.error('operation field is missing into request body, returning 400'); return res.status(400).send('operation field is missing into request body'); } if (testScript == undefined) { + winston.error('testScript field is missing into request body, returning 400'); return res.status(400).send('testScript field is missing into request body'); } if (callbackUrl == undefined) { + winston.error('callbackUrl field is missing into request body, returning 400'); return res.status(400).send('callbackUrl field is missing into request body'); } if (requests == undefined || !isArray(requests)) { + winston.error('requests array is missing into request body, returning 400'); return res.status(400).send('requests array is missing into request body'); } @@ -81,6 +85,26 @@ app.post('/tests/:testResultId', function (req, res) { res.status(201).send('New Postman collection test launched'); }) -app.listen(port, function () { +const server = app.listen(port, function () { console.log('Microcks postman-runtime wrapper listening on port: ' + port); }) + +function gracefulShutdown() { + console.log('Shutting down gracefully...'); + + server.close(() => { + console.log('Server closed.'); + + // Close any other connections or resources here + process.exit(0); + }); + + // Force close the server after 5 seconds + setTimeout(() => { + console.error('Could not close connections in time, forcefully shutting down'); + process.exit(1); + }, 5000); +} + +process.on('SIGTERM', gracefulShutdown); +process.on('SIGINT', gracefulShutdown); \ No newline at end of file diff --git a/bin/uid_entrypoint b/bin/uid_entrypoint new file mode 100755 index 0000000..6cac4d5 --- /dev/null +++ b/bin/uid_entrypoint @@ -0,0 +1,7 @@ +#!/bin/sh +if ! whoami &> /dev/null; then + if [ -w /etc/passwd ]; then + echo "${USER_NAME:-default}:x:$(id -u):0:${USER_NAME:-default} user:${HOME}:/sbin/nologin" >> /etc/passwd + fi +fi +exec /usr/bin/node /app/app.js