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:
nest start --watch which uses tsc to compile the application in watch mode.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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With