Problem
Production Docker images only install dependencies, not devDependencies. ts-node is a devDependency — it is absent in production images and cannot be called at runtime.
What doesn’t work
# ts-node not installed in the production image
command: ["npx", "ts-node", "--transpile-only", "scripts/ensureIndexes.ts"]# Adds ~90s per deployment; fragile if network or yarn is unavailable
command: ["sh", "-c", "yarn add ts-node --non-interactive && node_modules/.bin/ts-node --transpile-only scripts/ensureIndexes.ts"]Solution: compile in the builder stage
Run tsc during the Docker builder stage so the compiled JS is baked into the image. The production stage gets plain JS it can run with node.
# Builder stage
COPY scripts ./scripts
RUN node_modules/.bin/tsc --module commonjs --esModuleInterop --skipLibCheck --outDir dist scripts/ensureIndexes.tsThe compiled file lands at dist/scripts/ensureIndexes.js and is available in the final image.
# Runtime (e.g. initContainer)
command: ["node", "dist/scripts/ensureIndexes.js"]Tip
Rule — anything that requires
devDependencies(ts-node, tsc, jest) must be invoked during the build stage, not at runtime.
Warning
Build-time tsc failures block all deployments — if the compile step fails, no new image is produced and every tenant sharing the image is blocked until fixed. Keep scripts type-correct and test the build in CI.
Trade-offs
| Approach | Pod start time | Reliability |
|---|---|---|
| ts-node at runtime | +90s | Poor — absent in prod image |
| Install ts-node in initContainer | +90s | Poor — network-dependent |
| Compile in builder stage | Instant | Good |
See also
- initcontainer-setup-scripts — running the compiled script as a Kubernetes initContainer