From f4cbb799cc31acc80fec95af5213bbd56286a575 Mon Sep 17 00:00:00 2001 From: Scot Lunsford Date: Wed, 20 May 2026 16:28:46 -0500 Subject: [PATCH 1/2] Add live reload TAXII dev workflow --- Dockerfile | 23 ++++++++++++------- src/main.ts | 1 + src/taxii/controllers/root/root.controller.ts | 5 ++-- 3 files changed, 19 insertions(+), 10 deletions(-) diff --git a/Dockerfile b/Dockerfile index b2eca2c..64d19c7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -3,7 +3,7 @@ # unexpected behavior. # Since we are using the multi-stage build feature, we are also using the AS statement to name the image development. # The name here can be anything; it is only to reference the image later on. -FROM node:current-alpine3.14 AS development +FROM node:22-alpine AS development # Set the working directory within the container to /app. After setting WORKDIR, each command Docker executes (defined # in the RUN statement) will be executed in the specified context. @@ -13,21 +13,28 @@ WORKDIR /app # install command. Once it finishes, we copy the rest of our application’s files into the Docker container. COPY package*.json ./ -# Here we install only devDependencies due to the container being used as a “builder” that takes all the necessary tools -# to build the application and later send a clean /dist folder to the production image. -RUN npm install --only=development +RUN npm ci COPY . . +RUN mkdir -p /app-seed && cp -R src /app-seed/src + +ENV CHOKIDAR_USEPOLLING=true + +EXPOSE 8000 + +CMD ["sh", "-c", "if [ ! -f src/main.ts ]; then cp -R /app-seed/src/. src/; fi; exec npm run start:dev"] # Finally, we make sure the app is built in the /dist folder. Since our application uses TypeScript and other build-time -# dependencies, we have to execute this command in the development image. +# dependencies, we have to execute this command in a build image derived from the development image. +FROM development AS build + RUN npm run build # By using the FROM statement again, we are telling Docker that it should create a new, fresh image without any # connection to the previous one. This time we are naming it production. # Thanks to the multi-stage build feature, we can keep our final image (here called production) as slim as possible by # keeping all the unnecessary bloat in the development image. -FROM node:current-alpine3.14 AS production +FROM node:22-alpine AS production # Define build arguments ARG VERSION=dev @@ -73,11 +80,11 @@ COPY ecosystem.config.js . # Here we copy the built /dist folder from the development image. This way we are only getting the /dist directory, # without the devDependencies, installed in our final image. -COPY --from=development /app/dist ./dist +COPY --from=build /app/dist ./dist # Copy .env file and optional SSL keys (public-certificate.pem + private-key.pem) to image RUN mkdir config RUN cp config/*pem dist/config/ | true # Here we define the default command to execute when the image is run. -CMD ["pm2-runtime", "ecosystem.config.js"] \ No newline at end of file +CMD ["pm2-runtime", "ecosystem.config.js"] diff --git a/src/main.ts b/src/main.ts index 4ecb795..5041cd4 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,6 +12,7 @@ import { TaxiiConfigModule, TaxiiConfigService } from './config'; * Starts the Nest.js application */ export async function bootstrap() { + // Dev watch validation marker. // ** Initialize Express adapter ** // const server: express.Express = express(); diff --git a/src/taxii/controllers/root/root.controller.ts b/src/taxii/controllers/root/root.controller.ts index 9818b18..d07a35e 100644 --- a/src/taxii/controllers/root/root.controller.ts +++ b/src/taxii/controllers/root/root.controller.ts @@ -18,9 +18,10 @@ export class RootController { } @Get('/health/ping') - @HttpCode(HttpStatus.NO_CONTENT) - healthPing(): void { + @HttpCode(HttpStatus.OK) + healthPing(): string { this.logger.debug('Health ping.'); + return 'taxii live reload worx!'; } @ApiOkResponse({ From 6db6d4a559a7e09bd8658794a4503dc7513b5435 Mon Sep 17 00:00:00 2001 From: Scot Lunsford Date: Wed, 20 May 2026 16:29:01 -0500 Subject: [PATCH 2/2] Back out live reload demo markers --- src/main.ts | 1 - src/taxii/controllers/root/root.controller.ts | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main.ts b/src/main.ts index 5041cd4..4ecb795 100644 --- a/src/main.ts +++ b/src/main.ts @@ -12,7 +12,6 @@ import { TaxiiConfigModule, TaxiiConfigService } from './config'; * Starts the Nest.js application */ export async function bootstrap() { - // Dev watch validation marker. // ** Initialize Express adapter ** // const server: express.Express = express(); diff --git a/src/taxii/controllers/root/root.controller.ts b/src/taxii/controllers/root/root.controller.ts index d07a35e..9818b18 100644 --- a/src/taxii/controllers/root/root.controller.ts +++ b/src/taxii/controllers/root/root.controller.ts @@ -18,10 +18,9 @@ export class RootController { } @Get('/health/ping') - @HttpCode(HttpStatus.OK) - healthPing(): string { + @HttpCode(HttpStatus.NO_CONTENT) + healthPing(): void { this.logger.debug('Health ping.'); - return 'taxii live reload worx!'; } @ApiOkResponse({