When building an image that needs to be compiled from typescript, I get this error.
sh: 1: tsc: not found
The command '/bin/sh -c npm run tsc' returned a non-zero code: 127
Here is the relevant code:
docker-compose.yaml
version: '3.1'
services:
nodeserver:
build:
context: .
target: prod
ports:
- "3000:3000"
volumes:
- ./src:/app/src
- ./public:/app/public
- ./templates:/app/templates
Dockerfile
FROM node:15.11.0 AS base
EXPOSE 3000
ENV NODE_ENV=production
WORKDIR /app
COPY package*.json ./
RUN npm install --only=production && npm cache clean --force
##########################################################################################
FROM base AS dev
ENV NODE_ENV=development
RUN npm install --only=development
CMD npm run dev
##########################################################################################
FROM dev AS source
COPY dist dist
COPY templates templates
COPY public public
RUN npm run tsc
##########################################################################################
FROM base AS test
COPY --from=source /app/node_modules /app/node_modules
COPY --from=source /app/templates /app/templates
COPY --from=source /app/public /app/public
COPY --from=source /app/dist /app/dist
CMD npm run test
##########################################################################################
FROM test AS prod
CMD npm start
package.json
{
"name": "nodeserver",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"start": "node ./dist/app.js",
"deploy": "git add . && git commit -m Heroku && git push heroku main",
"tsc": "tsc --outDir ./dist",
"dev": "npm run ts-watch",
"test": "npm run jest --runInBand",
"ts-watch": "tsc-watch --project . --outDir ./dist --onSuccess \"nodemon ./dist/app.js\""
},
"jest": {
"testEnvironment": "node"
},
"repository": {
"type": "git",
"url": "git+https://github.com/MiquelPiza/nodeserver.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/MiquelPiza/nodeserver/issues"
},
"homepage": "https://github.com/MiquelPiza/nodeserver#readme",
"dependencies": {
"@sendgrid/mail": "^7.4.2",
"bcryptjs": "^2.4.3",
"express": "^4.17.1",
"handlebars": "^4.7.7",
"jsonwebtoken": "^8.5.1",
"lodash": "^4.17.20",
"mongodb": "^3.6.4",
"mongoose": "^5.11.19",
"multer": "^1.4.2",
"socket.io": "^4.0.0",
"validator": "^13.5.2"
},
"devDependencies": {
"@types/bcryptjs": "^2.4.2",
"@types/express": "^4.17.11",
"@types/jsonwebtoken": "^8.5.0",
"@types/lodash": "^4.14.168",
"@types/mongoose": "^5.10.3",
"@types/multer": "^1.4.5",
"@types/node": "^14.14.33",
"@types/sendgrid": "^4.3.0",
"@types/validator": "^13.1.3",
"env-cmd": "^10.1.0",
"jest": "^26.6.3",
"nodemon": "^2.0.7",
"supertest": "^6.1.3",
"tsc-watch": "^4.2.9",
"typescript": "^4.2.3"
},
"engines": {
"node": "15.11.0"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs",
"strict": true,
"strictNullChecks": false,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
},
"include": ["src"]
}
This dockerfile works:
FROM node:15.11.0 AS build
WORKDIR /app
COPY package.json .
RUN npm install
ADD . .
RUN npm run tsc
FROM node:15.11.0
WORKDIR /app
COPY package.json .
RUN npm install --production
ADD public ./public
ADD templates ./templates
COPY --from=build /app/dist dist
EXPOSE 3000
CMD npm start
I'm using this dockerfile for reference, from a Docker course: https://github.com/BretFisher/docker-mastery-for-nodejs/blob/master/typescript/Dockerfile I don't see what I'm doing wrong, the source stage should have the dev dependencies, among them typescript, so it should be able to run tsc.
Any help appreciated. Thanks.
EDIT:
In addition to using npm ci instead of npm install, I had to copy tsconfig.json to the working directory (and copy src directory instead of dist, which is created by tsc) for tsc to work properly. This is the modified source stage in the Dockerfile:
FROM dev AS source
COPY src src
COPY templates templates
COPY public public
COPY tsconfig.json tsconfig.json
RUN npm run tsc