Skip to content

Dockerfile.api: API fails at runtime with ERR_MODULE_NOT_FOUND (extensionless ESM imports) #57

@computerpoet

Description

@computerpoet

Bug

Dockerfile.api produces images that crash at startup with:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/app/packages/coredb/dist/schema'
imported from /app/packages/coredb/dist/lib/organization-service-account.js

Root Cause

Two issues in the production runtime:

1. Extensionless ESM imports

@refref/coredb uses "type": "module" and compiles with moduleResolution: "bundler". The compiled JS output has extensionless imports:

// packages/coredb/dist/lib/organization-service-account.js
import { user, orgUser, apikey, org } from "../schema";  // missing .js extension

Node.js ESM strict resolution requires file extensions. The dev server uses tsx which patches resolution, but production uses node dist/index.js which doesn't.

2. Missing non-JS files in runner stage

The runner stage only copies dist/ and package.json from apps/api/, missing openapi.yaml which is read at runtime:

Error: ENOENT: no such file or directory, open '/app/apps/api/openapi.yaml'

Workaround

Use tsx instead of node to run the compiled output:

CMD ["pnpm", "tsx", "dist/index.js"]

And copy the full app directory instead of just dist:

COPY --from=base /app/ ./

Proper Fix Options

  1. Add rewriteRelativeImportExtensions: true to tsconfig (TS 5.7+) so compiled output has .js extensions
  2. Or switch to a bundler (e.g., tsup, esbuild) that produces a single output file with resolved imports
  3. Copy openapi.yaml in the Dockerfile runner stage

Environment

  • Node.js v24
  • TypeScript 5.7+
  • pnpm 10.15.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions