Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript and Docker Slow Compilation

I recently updated to Docker 2.2.0.0 and am compiling a Typescript (3.7.5) NestJs project.

The typescript compilation takes a long time (a few minutes) when run in docker, but only take a few seconds run locally.

This is my tsconfig.json:

{
  "compilerOptions": {
    "module": "CommonJS",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "target": "ESNext",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "noUnusedLocals": true,
    "diagnostics": true
  },
  "include": ["src", "test"],
  "exclude": ["node_modules", "dist"]
}

Application hangs on:

Starting compilation in watch mode.

Then after several minutes it completes the build and the server starts.

Update:

  • Command to compile / run: nest start --watch which uses tsc to compile the application in watch mode.
  • My docker file is below:
FROM OUR-custom-docker-image

WORKDIR /app
COPY . .
RUN yarn install --production=false

EXPOSE 4200
CMD yarn db:migrate && yarn start:dev

Edit: - I ran `` both locally and within docker to see the runtime difference:

locally

Files:                       1270
Lines:                     140094
Nodes:                     516055
Identifiers:               186330
Symbols:                   775100
Types:                     255282
Memory used:              618234K
Assignability cache size:  284236
Identity cache size:          603
Subtype cache size:          1045
I/O Read time:              0.21s
Parse time:                 0.72s
Program time:               2.25s
Bind time:                  0.52s
Check time:                 7.32s
transformTime time:         0.15s
commentTime time:           0.00s
printTime time:             0.64s
Emit time:                  0.65s
Source Map time:            0.01s
I/O Write time:             0.12s
Total time:                10.74s

docker

 Files:                       1269
 Lines:                     140047
 Nodes:                     515825
 Identifiers:               186267
 Symbols:                   775022
 Types:                     255265
 Memory used:              618717K
 Assignability cache size:  284236
 Identity cache size:          603
 Subtype cache size:          1045
 I/O Read time:              1.13s
 Parse time:                 1.01s
 Program time:               5.88s
 Bind time:                  0.74s
 Check time:                 8.87s
 transformTime time:         0.21s
 commentTime time:           0.00s
 printTime time:             1.75s
 Emit time:                  1.76s
 Source Map time:            0.03s
 I/O Write time:             1.11s
 Total time:                17.25s
like image 276
coler-j Avatar asked Oct 30 '25 17:10

coler-j


1 Answers

There is a known problem that accessing NTFS files from WSL2 is very slow. When you run tsc from within a Docker container, it is running under WSL2, and tsc needs to access the files on NTFS, hence you are encountering the cross-file system slow down issue.

You can confirm the file access slow-down with a quick experiment. Have a git repository stored on NTFS. Run git status natively in Windows and compare the run time when git status is run from a docker container. You will notice a dramatic slow down because of the cross-file system access.

On my machine I see the following results using Powershell:

# Run git status from Windows
Measure-Command -Expression {git status} | select -Property TotalSeconds

TotalSeconds
------------
   0.1172657

# Run git status from Docker
Measure-Command -Expression{ docker run -ti --rm -v ${HOME}:/root -v ${pwd}:/git alpine/git status} | select -Property TotalSeconds

TotalSeconds
------------
  25.4326815

Just to confirm that the additional time is not taken by starting the git container, the following compares the time to run git version:

# Run git version from Windows
Measure-Command -Expression {git version} | select -Property TotalSeconds

TotalSeconds
------------
   0.0821073

# Run git version from Docker
Measure-Command -Expression{ docker run -ti --rm -v ${HOME}:/root -v ${pwd}:/git alpine/git version} | select -Property TotalSeconds

TotalSeconds
------------
   1.2742293

The startup time of the docker container takes less than 2 seconds, while the difference in time to perform that git status which needs to traverse the repository files is around 25 seconds.

If you really need to use the node installation from within a Docker container, you can avoid the cross-file access problem by storing your git repository directly in the WSL2 file system. That way, the file access is WSL2 to WSL2 (assuming you enable WSL2 support in Docker Desktop), which is fast.

like image 139
Phillip Ngan Avatar answered Nov 03 '25 03:11

Phillip Ngan



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!