From 615958f5142ab5e936a11b9d62cfff3c3bb58d1d Mon Sep 17 00:00:00 2001 From: Aaron Knudtson Date: Thu, 29 May 2025 00:12:05 -0400 Subject: [PATCH] feat: use esbuild for building the api --- .changeset/tricky-laws-march.md | 5 + docker/hyperdx/Dockerfile | 7 +- docker/hyperdx/entry.local.base.sh | 4 +- docker/hyperdx/entry.prod.sh | 4 +- packages/api/build.js | 42 ++++ packages/api/package.json | 5 +- packages/api/src/opamp/utils/protobuf.ts | 6 +- yarn.lock | 242 +++++++++++++++++++++++ 8 files changed, 303 insertions(+), 12 deletions(-) create mode 100644 .changeset/tricky-laws-march.md create mode 100644 packages/api/build.js diff --git a/.changeset/tricky-laws-march.md b/.changeset/tricky-laws-march.md new file mode 100644 index 000000000..7ae856106 --- /dev/null +++ b/.changeset/tricky-laws-march.md @@ -0,0 +1,5 @@ +--- +"@hyperdx/api": patch +--- + +api is now bundled in build and the Dockerfile benefits greatly diff --git a/docker/hyperdx/Dockerfile b/docker/hyperdx/Dockerfile index 29de32dec..693ef2066 100644 --- a/docker/hyperdx/Dockerfile +++ b/docker/hyperdx/Dockerfile @@ -26,7 +26,7 @@ WORKDIR /app COPY .yarn ./.yarn COPY .yarnrc.yml yarn.lock package.json nx.json .prettierrc .prettierignore ./ COPY ./packages/common-utils ./packages/common-utils -COPY ./packages/api/jest.config.js ./packages/api/tsconfig.json ./packages/api/package.json ./packages/api/ +COPY ./packages/api/jest.config.js ./packages/api/tsconfig.json ./packages/api/package.json ./packages/api/build.js ./packages/api/ COPY ./packages/app/jest.config.js ./packages/app/tsconfig.json ./packages/app/tsconfig.test.json ./packages/app/package.json ./packages/app/next.config.js ./packages/app/mdx.d.ts ./packages/app/.eslintrc.js ./packages/app/ # Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed. @@ -68,10 +68,7 @@ USER node # Set up API WORKDIR /app/api -COPY --chown=node:node --from=builder /app/node_modules ./node_modules -COPY --chown=node:node --from=builder /app/packages/api/build ./packages/api/build -COPY --chown=node:node --from=builder /app/packages/common-utils/dist ./packages/common-utils/dist -COPY --chown=node:node --from=node_base /app/packages/common-utils/node_modules ./packages/common-utils/node_modules +COPY --chown=node:node --from=builder /app/packages/api/dist ./dist # Set up App WORKDIR /app/app diff --git a/docker/hyperdx/entry.local.base.sh b/docker/hyperdx/entry.local.base.sh index 97ecc4e3f..3850dd5c4 100644 --- a/docker/hyperdx/entry.local.base.sh +++ b/docker/hyperdx/entry.local.base.sh @@ -61,9 +61,9 @@ opampsupervisor --config /etc/otel/supervisor.yaml > /var/log/otel-collector.log npx concurrently \ "--kill-others" \ "--names=API,APP,ALERT-TASK" \ - "PORT=${HYPERDX_API_PORT:-8000} HYPERDX_APP_PORT=${HYPERDX_APP_PORT:-8080} node -r /app/api/node_modules/@hyperdx/node-opentelemetry/build/src/tracing /app/api/packages/api/build/index.js" \ + "PORT=${HYPERDX_API_PORT:-8000} HYPERDX_APP_PORT=${HYPERDX_APP_PORT:-8080} node -r /app/api/dist/tracing.bundle.js /app/api/dist/index.js" \ "HYPERDX_API_PORT=${HYPERDX_API_PORT:-8000} /app/app/node_modules/.bin/next start -p ${HYPERDX_APP_PORT:-8080}" \ - "node -r /app/api/node_modules/@hyperdx/node-opentelemetry/build/src/tracing /app/api/packages/api/build/tasks/index.js check-alerts" \ + "node -r /app/api/dist/tracing.bundle.js /app/api/dist/tasks/index.js check-alerts" \ > /var/log/app.log 2>&1 & echo "" diff --git a/docker/hyperdx/entry.prod.sh b/docker/hyperdx/entry.prod.sh index 1a02b3a08..c07283ad3 100644 --- a/docker/hyperdx/entry.prod.sh +++ b/docker/hyperdx/entry.prod.sh @@ -15,6 +15,6 @@ echo "" npx concurrently \ "--kill-others" \ "--names=API,APP,ALERT-TASK" \ - "PORT=${HYPERDX_API_PORT:-8000} HYPERDX_APP_PORT=${HYPERDX_APP_PORT:-8080} node -r /app/api/node_modules/@hyperdx/node-opentelemetry/build/src/tracing /app/api/packages/api/build/index.js" \ + "PORT=${HYPERDX_API_PORT:-8000} HYPERDX_APP_PORT=${HYPERDX_APP_PORT:-8080} node -r /app/api/dist/tracing.bundle.js /app/api/dist/index.js" \ "HYPERDX_API_PORT=${HYPERDX_API_PORT:-8000} /app/app/node_modules/.bin/next start -p ${HYPERDX_APP_PORT:-8080}" \ - "node -r /app/api/node_modules/@hyperdx/node-opentelemetry/build/src/tracing /app/api/packages/api/build/tasks/index.js check-alerts" + "node -r /app/api/dist/tracing.bundle.js /app/api/dist/tasks/index.js check-alerts" diff --git a/packages/api/build.js b/packages/api/build.js new file mode 100644 index 000000000..77e57a173 --- /dev/null +++ b/packages/api/build.js @@ -0,0 +1,42 @@ +const esbuild = require('esbuild'); +const path = require('path'); +const fs = require('fs'); + +async function build() { + try { + // Make sure dist directory exists + const distDir = path.resolve(__dirname, 'dist'); + if (!fs.existsSync(distDir)) { + fs.mkdirSync(distDir, { recursive: true }); + } + + // Build main application + await esbuild.build({ + entryPoints: ['src/index.ts', 'src/tasks/index.ts'], + bundle: true, + platform: 'node', + target: 'node22', + outdir: 'dist', + sourcemap: false, + minify: true, + format: 'cjs', + define: { + 'process.env.NODE_ENV': '"production"', + }, + banner: { + js: '#!/usr/bin/env node', + }, + alias: { + // Add path aliases from tsconfig + '@': path.resolve(__dirname, 'src'), + }, + }); + + console.log('Build completed successfully!'); + } catch (error) { + console.error('Build failed:', error); + process.exit(1); + } +} + +build(); diff --git a/packages/api/package.json b/packages/api/package.json index 6e1339384..389c72b2d 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -75,6 +75,7 @@ "@types/supertest": "^2.0.12", "@types/swagger-jsdoc": "^6", "@types/uuid": "^8.3.4", + "esbuild": "^0.21.0", "jest": "^28.1.3", "migrate-mongo": "^11.0.0", "nodemon": "^2.0.20", @@ -89,10 +90,10 @@ "typescript": "^4.9.5" }, "scripts": { - "start": "node ./build/index.js", + "start": "node ./dist/index.js", "dev": "DOTENV_CONFIG_PATH=.env.development nodemon --signal SIGTERM -e ts,json --exec 'ts-node' --transpile-only -r tsconfig-paths/register -r dotenv-expand/config -r '@hyperdx/node-opentelemetry/build/src/tracing' ./src/index.ts", "dev-task": "DOTENV_CONFIG_PATH=.env.development nodemon --signal SIGTERM -e ts,json --exec 'ts-node' --transpile-only -r tsconfig-paths/register -r dotenv-expand/config -r '@hyperdx/node-opentelemetry/build/src/tracing' ./src/tasks/index.ts", - "build": "rimraf ./build && tsc && tsc-alias && cp -r src/opamp/proto build/opamp/", + "build": "rimraf ./dist && node ./build.js && esbuild ../../node_modules/@hyperdx/node-opentelemetry/build/src/tracing --bundle --minify --platform=node --outfile=dist/tracing.bundle.js && cp -r src/opamp/proto dist/opamp/", "lint": "eslint --quiet . --ext .ts", "lint:fix": "eslint . --ext .ts --fix", "ci:lint": "yarn lint && yarn tsc --noEmit", diff --git a/packages/api/src/opamp/utils/protobuf.ts b/packages/api/src/opamp/utils/protobuf.ts index c2cf7c792..e411a72c5 100644 --- a/packages/api/src/opamp/utils/protobuf.ts +++ b/packages/api/src/opamp/utils/protobuf.ts @@ -3,10 +3,14 @@ import * as fs from 'fs'; import * as path from 'path'; import * as protobuf from 'protobufjs'; +import { IS_PROD } from '@/config'; import logger from '@/utils/logger'; // Define the root path of the proto file -const PROTO_PATH = path.resolve(__dirname, '../proto/opamp.proto'); +const PROTO_PATH = path.resolve( + __dirname, + IS_PROD ? 'opamp/opamp.proto' : '../proto/opamp.proto', +); // Load the OpAMP proto definition let root: protobuf.Root; diff --git a/yarn.lock b/yarn.lock index 60a33a201..ad9ac4fc7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3710,6 +3710,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/aix-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/aix-ppc64@npm:0.21.5" + conditions: os=aix & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/aix-ppc64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/aix-ppc64@npm:0.25.1" @@ -3724,6 +3731,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm64@npm:0.21.5" + conditions: os=android & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/android-arm64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/android-arm64@npm:0.25.1" @@ -3738,6 +3752,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-arm@npm:0.21.5" + conditions: os=android & cpu=arm + languageName: node + linkType: hard + "@esbuild/android-arm@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/android-arm@npm:0.25.1" @@ -3752,6 +3773,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/android-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/android-x64@npm:0.21.5" + conditions: os=android & cpu=x64 + languageName: node + linkType: hard + "@esbuild/android-x64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/android-x64@npm:0.25.1" @@ -3766,6 +3794,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-arm64@npm:0.21.5" + conditions: os=darwin & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/darwin-arm64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/darwin-arm64@npm:0.25.1" @@ -3780,6 +3815,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/darwin-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/darwin-x64@npm:0.21.5" + conditions: os=darwin & cpu=x64 + languageName: node + linkType: hard + "@esbuild/darwin-x64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/darwin-x64@npm:0.25.1" @@ -3794,6 +3836,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-arm64@npm:0.21.5" + conditions: os=freebsd & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/freebsd-arm64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/freebsd-arm64@npm:0.25.1" @@ -3808,6 +3857,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/freebsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/freebsd-x64@npm:0.21.5" + conditions: os=freebsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/freebsd-x64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/freebsd-x64@npm:0.25.1" @@ -3822,6 +3878,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm64@npm:0.21.5" + conditions: os=linux & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/linux-arm64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/linux-arm64@npm:0.25.1" @@ -3836,6 +3899,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-arm@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-arm@npm:0.21.5" + conditions: os=linux & cpu=arm + languageName: node + linkType: hard + "@esbuild/linux-arm@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/linux-arm@npm:0.25.1" @@ -3850,6 +3920,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ia32@npm:0.21.5" + conditions: os=linux & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/linux-ia32@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/linux-ia32@npm:0.25.1" @@ -3864,6 +3941,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-loong64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-loong64@npm:0.21.5" + conditions: os=linux & cpu=loong64 + languageName: node + linkType: hard + "@esbuild/linux-loong64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/linux-loong64@npm:0.25.1" @@ -3878,6 +3962,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-mips64el@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-mips64el@npm:0.21.5" + conditions: os=linux & cpu=mips64el + languageName: node + linkType: hard + "@esbuild/linux-mips64el@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/linux-mips64el@npm:0.25.1" @@ -3892,6 +3983,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-ppc64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-ppc64@npm:0.21.5" + conditions: os=linux & cpu=ppc64 + languageName: node + linkType: hard + "@esbuild/linux-ppc64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/linux-ppc64@npm:0.25.1" @@ -3906,6 +4004,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-riscv64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-riscv64@npm:0.21.5" + conditions: os=linux & cpu=riscv64 + languageName: node + linkType: hard + "@esbuild/linux-riscv64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/linux-riscv64@npm:0.25.1" @@ -3920,6 +4025,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-s390x@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-s390x@npm:0.21.5" + conditions: os=linux & cpu=s390x + languageName: node + linkType: hard + "@esbuild/linux-s390x@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/linux-s390x@npm:0.25.1" @@ -3934,6 +4046,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/linux-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/linux-x64@npm:0.21.5" + conditions: os=linux & cpu=x64 + languageName: node + linkType: hard + "@esbuild/linux-x64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/linux-x64@npm:0.25.1" @@ -3955,6 +4074,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/netbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/netbsd-x64@npm:0.21.5" + conditions: os=netbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/netbsd-x64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/netbsd-x64@npm:0.25.1" @@ -3976,6 +4102,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/openbsd-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/openbsd-x64@npm:0.21.5" + conditions: os=openbsd & cpu=x64 + languageName: node + linkType: hard + "@esbuild/openbsd-x64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/openbsd-x64@npm:0.25.1" @@ -3990,6 +4123,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/sunos-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/sunos-x64@npm:0.21.5" + conditions: os=sunos & cpu=x64 + languageName: node + linkType: hard + "@esbuild/sunos-x64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/sunos-x64@npm:0.25.1" @@ -4004,6 +4144,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-arm64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-arm64@npm:0.21.5" + conditions: os=win32 & cpu=arm64 + languageName: node + linkType: hard + "@esbuild/win32-arm64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/win32-arm64@npm:0.25.1" @@ -4018,6 +4165,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-ia32@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-ia32@npm:0.21.5" + conditions: os=win32 & cpu=ia32 + languageName: node + linkType: hard + "@esbuild/win32-ia32@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/win32-ia32@npm:0.25.1" @@ -4032,6 +4186,13 @@ __metadata: languageName: node linkType: hard +"@esbuild/win32-x64@npm:0.21.5": + version: 0.21.5 + resolution: "@esbuild/win32-x64@npm:0.21.5" + conditions: os=win32 & cpu=x64 + languageName: node + linkType: hard + "@esbuild/win32-x64@npm:0.25.1": version: 0.25.1 resolution: "@esbuild/win32-x64@npm:0.25.1" @@ -4294,6 +4455,7 @@ __metadata: cron: "npm:^3.5.0" date-fns: "npm:^2.28.0" date-fns-tz: "npm:^2.0.0" + esbuild: "npm:^0.21.0" express: "npm:^4.19.2" express-rate-limit: "npm:^6.7.1" express-session: "npm:^1.17.3" @@ -14942,6 +15104,86 @@ __metadata: languageName: node linkType: hard +"esbuild@npm:^0.21.0": + version: 0.21.5 + resolution: "esbuild@npm:0.21.5" + dependencies: + "@esbuild/aix-ppc64": "npm:0.21.5" + "@esbuild/android-arm": "npm:0.21.5" + "@esbuild/android-arm64": "npm:0.21.5" + "@esbuild/android-x64": "npm:0.21.5" + "@esbuild/darwin-arm64": "npm:0.21.5" + "@esbuild/darwin-x64": "npm:0.21.5" + "@esbuild/freebsd-arm64": "npm:0.21.5" + "@esbuild/freebsd-x64": "npm:0.21.5" + "@esbuild/linux-arm": "npm:0.21.5" + "@esbuild/linux-arm64": "npm:0.21.5" + "@esbuild/linux-ia32": "npm:0.21.5" + "@esbuild/linux-loong64": "npm:0.21.5" + "@esbuild/linux-mips64el": "npm:0.21.5" + "@esbuild/linux-ppc64": "npm:0.21.5" + "@esbuild/linux-riscv64": "npm:0.21.5" + "@esbuild/linux-s390x": "npm:0.21.5" + "@esbuild/linux-x64": "npm:0.21.5" + "@esbuild/netbsd-x64": "npm:0.21.5" + "@esbuild/openbsd-x64": "npm:0.21.5" + "@esbuild/sunos-x64": "npm:0.21.5" + "@esbuild/win32-arm64": "npm:0.21.5" + "@esbuild/win32-ia32": "npm:0.21.5" + "@esbuild/win32-x64": "npm:0.21.5" + dependenciesMeta: + "@esbuild/aix-ppc64": + optional: true + "@esbuild/android-arm": + optional: true + "@esbuild/android-arm64": + optional: true + "@esbuild/android-x64": + optional: true + "@esbuild/darwin-arm64": + optional: true + "@esbuild/darwin-x64": + optional: true + "@esbuild/freebsd-arm64": + optional: true + "@esbuild/freebsd-x64": + optional: true + "@esbuild/linux-arm": + optional: true + "@esbuild/linux-arm64": + optional: true + "@esbuild/linux-ia32": + optional: true + "@esbuild/linux-loong64": + optional: true + "@esbuild/linux-mips64el": + optional: true + "@esbuild/linux-ppc64": + optional: true + "@esbuild/linux-riscv64": + optional: true + "@esbuild/linux-s390x": + optional: true + "@esbuild/linux-x64": + optional: true + "@esbuild/netbsd-x64": + optional: true + "@esbuild/openbsd-x64": + optional: true + "@esbuild/sunos-x64": + optional: true + "@esbuild/win32-arm64": + optional: true + "@esbuild/win32-ia32": + optional: true + "@esbuild/win32-x64": + optional: true + bin: + esbuild: bin/esbuild + checksum: 10c0/fa08508adf683c3f399e8a014a6382a6b65542213431e26206c0720e536b31c09b50798747c2a105a4bbba1d9767b8d3615a74c2f7bf1ddf6d836cd11eb672de + languageName: node + linkType: hard + "esbuild@npm:^0.25.0": version: 0.25.1 resolution: "esbuild@npm:0.25.1"