Compile TypeScript at build time instead of runtime in Dockerfile.api #128
Reference in New Issue
Block a user
Delete Branch "copilot/optimize-dockerfile-api"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Successfully optimized Dockerfile.api to compile TypeScript at build time:
✅ TypeScript compiled during docker build with validation
✅ CMD runs compiled JavaScript from dist/
✅ Multi-stage build with lean runtime image
✅ ts-node and typescript removed via npm prune
✅ API starts correctly from compiled output
✅ Swagger docs work with scripts/ directory present
✅ Proper error handling in Express async routes
CodeQL: 0 alerts
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.
Pull request overview
This PR updates the API container build to compile TypeScript during
docker build(instead of usingts-nodeat runtime), and fixes two route files that previously had syntax issues preventing compilation.Changes:
tsconfig.build.jsonfor a production-oriented TypeScript build (emit JS even with type errors).Dockerfile.apito compile TypeScript todist/in the builder stage and runnode dist/...in the runner stage.tryblocks inmanifest.routes.tsandoneshot.routes.tsto fix invalidtryusage.Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.
dist/withtscand runs compiled JS in the runtime image; removes TS runtime tooling.trywrapper while preserving behavior.trywrapper from async handler.Comments suppressed due to low confidence (1)
scripts/routes/oneshot.routes.ts:45
tryblock is gone.💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
@@ -39,9 +40,16 @@ COPY hardhat.config.ts ./# Generate Prisma clientnpx tsc -p tsconfig.build.json || truewill mask all TypeScript compilation failures (including parse errors / missing imports), which can produce an image withoutdist/scripts/start-api-server.jsand only fail at container startup. Consider keeping the “ignore type errors” behavior but still failing the build when the expecteddistentrypoint (ordist/output) is not generated.The runner stage copies
node_modulesfrom the builder stage (which includes all devDependencies) and then removes onlyts-node,typescript, and@types/node. This likely leaves most devDependencies in the production image, reducing the expected image-size benefit. If the goal is a lean runtime image, consider either using the existingdepsstage for production deps, or pruning devDependencies after ensuring runtime deps are correctly classified inpackage.json.Only
dist/is copied into the runtime image, but the Swagger generator is configured to read JSDoc from./scripts/routes/v1/*.tsat runtime (seescripts/services/swagger.service.ts). Withscripts/absent in the runner stage,/api/docsand/api/docs.jsonmay break or become empty. Either copy the requiredscripts/routes/v1sources into the runner image, or update the swagger-jsdocapisglob to target the compileddist/.../*.jspaths.After removing the outer
try, several operations earlier in the handler (e.g. parsingrawBindings, optional IPFS uploadtmpWrite/cleanupTmpFile, hashing) now occur outside the remainingtry/catch. In Express 4, exceptions/rejected promises in anasynchandler won’t reliably hit the global error middleware, which can lead to unhandled rejections or hung requests. Consider wrapping the entire handler body in a singletry/catch(or using a shared async-error wrapper) so all failures produce a consistent error response.@copilot apply changes based on the comments in this thread
@@ -39,9 +40,16 @@ COPY hardhat.config.ts ./# Generate Prisma clientAdded validation to ensure
dist/scripts/start-api-server.jsis generated. If compilation fails to produce the entrypoint, the build will now fail with a clear error message. (d007630)Added
COPY --from=builder /app/scripts ./scriptsto the runner stage. Swagger JSDoc will now have access to the TypeScript route files for API documentation generation. (d007630)Replaced manual removal with
npm prune --production --legacy-peer-deps. This properly removes all devDependencies while handling peer dependency conflicts. Falls back to manual ts-node/typescript removal if prune fails. (d007630)Wrapped the entire handler body in a single try/catch block. All operations including parsing, IPFS uploads, hashing, and blockchain calls are now properly handled with consistent error responses for any failures. (
d007630)