Brand new to the Mean Stack but have managed to get one set up in a dockerized environment by following various tutorials. I mainly used the one explained at https://itnext.io/building-restful-web-apis-with-node-js-express-mongodb-and-typescript-part-1-2-195bdaf129cf
The issue I am having is that to get changes to TypeScript files automatically compiled and serice restarted is failing and I'm unsure what I'm missing in the config. I've tried various iterations using nodemon and ts-node-dev without success.
The server starts up and serves pages 100% but a code change isn't triggering anything.
Below are the Dockerfile (for the Node Express server), package.json and my tsconfig.json, if anyone can possible indicate where I'm going wrong it would be a great help. I've also shown my docker-compose.yml file for the entire stack.
Dockerfile
FROM node:latest
# Create app directory
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm@5+)
COPY package*.json ./
RUN npm install
RUN npm install --save body-parser express mongoose
RUN npm install --save nocache
RUN npm install --save nodemon typescript ts-node ts-node-dev
RUN npm install --save-dev tsc-watch
# If you are building your code for production
# RUN npm ci --only=production
# Bundle app source
COPY . .
EXPOSE 3000 27017
# Also tried starting with 'dev'
CMD [ "npm", "run", "prod" ]
package.json
{
"name": "apis-project",
"version": "1.0.0",
"description": "https://itnext.io/building-restful-web-apis-with-node-js-express-mongodb-and-typescript-part-1-2-195bdaf129cf",
"main": "index.js",
"scripts": {
"build": "tsc",
"dev": "ts-node ./lib/server.ts",
"start": "nodemon ./dist/server.js",
"prod": "npm run build && npm run start"
},
"keywords": [
"nodejs",
"typescript"
],
"author": "",
"license": "ISC",
"dependencies": {
"@types/express": "^4.17.1",
"body-parser": "^1.19.0",
"express": "^4.17.1",
"mongoose": "^5.7.7",
"nodemon": "^1.19.4"
},
"devDependencies": {
"ts-node-dev": "^1.0.0-pre.43"
}
}
Other variations I've tried within the scripts section are:
"dev2": "ts-node-dev --respawn --transpileOnly ./lib/server.ts",
"dev3": "nodemon --watch 'lib/*.ts' --exec 'ts-node' lib/server.ts",
"dev5": "tsc-watch ./lib/server.ts --outDir ./dist --onSuccess \"node ./dist/server.js\" --onFailure \"echo Beep! Compilation Failed\" --compiler typescript/bin/tsc",
"dev6": "tsc-watch ./lib/*.ts --outDir ./dist --onSuccess \"node ./dist/server.js\" --onFailure \"echo Beep! Compilation Failed\" --compiler typescript/bin/tsc",
"dev7": "tsc-watch ./lib/server.ts --outDir ./dist --onSuccess \"node ./dist/server.js\" --onFailure \"echo Beep! Compilation Failed\" --compiler typescript/bin/tsc",
"x-compile": "tsc && node ./dist/server.js",
"x-dev": "./node_modules/nodemon/bin/nodemon.js -e ts --exec \"npm run x-compile\"",
tsconfig.json
// tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"moduleResolution": "node",
"pretty": true,
"sourceMap": true,
"target": "es6",
"outDir": "./dist",
"baseUrl": "./lib"
},
"include": [
"lib/**/*.ts"
],
"exclude": [
"node_modules"
]
}
docker-compose.yml
version: '3' # specify docker-compose version
# Define the services/containers to be run
services:
# angular: # name of the first service
# hostname: localhost
# build: serviceangular # specify the directory of the Dockerfile
# ports:
# - 4200:4200 # specify port forewarding
#
express: #name of the second service
build: ./node-apis-project # specify the directory of the Dockerfile
ports:
- 3000:3000 #specify ports forwarding
links:
- database
database: # name of the third service
image: mongo # specify image to build container from
ports:
- 27017:27017 # specify port forewarding
volumes:
- ./data/mongo:/data/db
volumes:
data:
external: true
Docker logs output when viewing the express container
> [email protected] prod /usr/src/app
> npm run build && npm run start
> [email protected] build /usr/src/app
> tsc
> [email protected] start /usr/src/app
> nodemon ./dist/server.js
[nodemon] 1.19.4
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): lib/**/*
[nodemon] watching extensions: js
[nodemon] starting `node ./dist/server.js`
(node:62) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
(node:62) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
Express server listening on port 3000
You might have found a solution by now. I'll leave this answer as a reference.
In docker-compose.yml
, ensure that you already mapped the source code to the app service. In your case:
version: '3'
services:
...
express:
build: ./node-apis-project
ports:
- 3000:3000
links:
- database
volumes:
- .:/usr/src/app # same as WORKDIR in your Dockerfile
...
According to nodemon manual, normal watch mechanism might fail in some networked environments (such as a container running nodemon reading across a mounted drive) so you might have to use polling which is a little CPU intensive (6-10% CPU utilization in my case)
For nodemon, use --legacy-watch
:
"dev3": "nodemon --legacy-watch --watch 'lib/*.ts' --exec 'ts-node' lib/server.ts",
For ts-node-dev, use --poll
:
"dev2": "ts-node-dev --poll --respawn --transpile-only ./lib/server.ts",
For anyone else that landed on this issue due to issues with Kubernetes + ts-node-dev failing and sending errors similar to :
[INFO] 09:29:47 ts-node-dev ver. 1.1.1 (using ts-node ver. 9.1.1, typescript ver. 4.1.3)
npm ERR! path /app
npm ERR! command failed
npm ERR! signal SIGKILL
npm ERR! command sh -c ts-node-dev src/index.ts
check the resources you have allocated to the container in your deployment yaml and try de-restricting them.
this resolved the issue for me and I was able to tune in to the resources following this.
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