Docker-Compose fail - node.js

I'm working with docker, docker-compose, trying to create an image but I'm getting an issue that I can't fix, I have tried a lot of ways but nothing seems to work, this configuration for my image, this is my docker file
FROM node:16-alpine#sha256:53ebfa5e6df1e458b47f677cb4f6fd3cf1d079083647dc40d182910a57b5a63d
RUN apk add dumb-init
ENV PORT=443
ENV NODE_ENV=development
ENV DBUSER=user
ENV DBPASS=pass
WORKDIR /app
COPY --chown=node:node . /app
RUN npm ci --only=prod
USER node
CMD ["dumb-init", "node", "/app/index.js"]
And my docker-compose.yaml looks like this:
version: '1.7'
services:
web:
build:
context: .
dockerfile: ./Dockerfile.web
ports:
- "9000:443"
extra_hosts:
"host.docker.internal": host-gateway
.dockerignore:
Dockerfile*
install.sh
README.md
docs/
dev/
var/db/
var/db.tar.gz
node_modules
npm-debug.log
.dockerignore
.git
.gitignore
.npmrc
package.json
"dependencies": {
"#peculiar/webcrypto": "^1.1.7",
"bcrypt": "^5.0.1",
"cookie-parser": "^1.4.5",
"cors": "^2.8.5",
"express": "^4.17.1",
"fs": "0.0.1-security",
"fs.promises": "^0.1.2",
"https": "^1.0.0",
"rethinkdb": "^2.4.2",
"uuid": "^8.3.2",
"ws": "^8.2.2"
},
"devDependencies": {
"eslint": "^8.8.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"husky": "^7.0.4",
"lint-staged": "^12.3.3",
"prettier": "^2.5.1"
},
And this is the error that I'm getting when I run docker-compose build:

Related

NestJs doesn't hot reload work in inside Docker

Minimum reproduction code
sample code
Steps to reproduce
npm install
docker compose up
Expected behavior
wait for the docker container to be created and run nest, modify the main.ts file, the nest listener does not perform hot reloading
package.json
"dependencies": {
"#nestjs/common": "^9.0.0",
"#nestjs/core": "^9.0.0",
"#nestjs/platform-express": "^9.0.0",
"reflect-metadata": "^0.1.13",
"rxjs": "^7.2.0"
},
"devDependencies": {
"#nestjs/cli": "^9.0.0",
"#nestjs/schematics": "^9.0.0",
"#nestjs/testing": "^9.0.0",
"#types/express": "^4.17.13",
"#types/jest": "29.2.4",
"#types/node": "18.11.18",
"#types/supertest": "^2.0.11",
"#typescript-eslint/eslint-plugin": "^5.0.0",
"#typescript-eslint/parser": "^5.0.0",
"eslint": "^8.0.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"jest": "29.3.1",
"prettier": "^2.3.2",
"source-map-support": "^0.5.20",
"supertest": "^6.1.3",
"ts-jest": "29.0.3",
"ts-loader": "^9.2.3",
"ts-node": "^10.0.0",
"tsconfig-paths": "4.1.1",
"typescript": "^4.7.4"
}
Dockerfile
###################
# BUILD FOR LOCAL DEVELOPMENT
###################
FROM node:18-alpine As development
WORKDIR /usr/src/app
COPY --chown=node:node package*.json ./
RUN npm ci
COPY --chown=node:node . .
USER node
docker-compose.yml
version: '2.13.0'
services:
api:
build:
dockerfile: Dockerfile
context: .
# Only will build development stage from our dockerfile
target: development
volumes:
- .:/usr/src/app
- /usr/src/app/node_modules
# Run in dev Mode: npm run start:dev
command: npm run start:dev
ports:
- 3000:3000
use the listening mode in the docker container, and bind the volume, but modify the file under src, nest does not perform hot reload

sh: 1: nodemon: not found on Docker compose

I am having serious issues setting up docker. When I run sudo docker-compose up -d and sudo docker-compose logs -f my app is logging sh: 1: nodemon: not found over and over again. The problem is that I don't even have nodemon anymore : /
If I run the exact same project with npm start and manually turn on mysql it works.
My dockerfile:
FROM node:latest
# Create app directory
WORKDIR ./
# 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 ./
#WORKDIR /node_modules
RUN npm ci --only=production
RUN npm install
# Bundle app source
COPY . .
EXPOSE 8003
CMD [ "npm", "start" ]
My package.json:
{
"name": "name",
"version": "6.4",
"description": "sdasdsadsad",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node --inspect=0.0.0.0 app.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"axios": "^0.25.0",
"bcryptjs": "^2.4.3",
"body-parser": "^1.19.0",
"compression": "^1.7.4",
"connect-flash": "^0.1.1",
"cookie-parser": "^1.4.5",
"dotenv": "^10.0.0",
"ejs": "^3.1.6",
"express": "^4.17.1",
"express-flash": "^0.0.2",
"express-flash-messages": "^0.1.1",
"express-formidable": "^1.2.0",
"express-mysql-session": "^2.1.7",
"express-session": "^1.17.2",
"express-validator": "5.3.1",
"helmet": "^4.6.0",
"jsonwebtoken": "^8.5.1",
"multer": "^1.4.3",
"mysql": "^2.18.1",
"mysql-pool-booster": "^1.0.3",
"node-lame": "^1.3.2",
"nodemailer": "^6.7.0",
"sharp": "^0.29.1",
"uglify-js": "^3.14.5",
"uglifycss": "^0.0.29",
"util.promisify": "^1.1.1"
}
}
My docker-compose and package-lock.json also don't contain nodemon anymore...
Delete package lock file and Try using this command to rebuild the container.
sudo docker-compose up -d --build

Optimizing Dockerfile for smaller image size

I'm trying to build a docker image which is as small as possible. My project is codded in typescript.
For what I have at the moment, it works just fine, but I'm sure not if my implementation is even good. When I run docker build the image size comes up to 276.23MB.
The problem is that I have to call "tsc" to compile my code into JavaScript which is a dev-dependency.
This is my Dockerfile:
FROM node:16-alpine3.11 as build
WORKDIR /usr/src/app
COPY . /usr/src/app/
RUN \
npm install && \
npm run build
FROM node:16-alpine3.11
WORKDIR /app
COPY --from=build /usr/src/app .
CMD [ "npm", "start" ]
These are the scripts & dependencies in my package.json file:
{
...
"scripts": {
"test": "jest --coverage",
"test:watch": "jest --watch",
"start": "fastify start -l info dist/src/app.js",
"build": "npx rimraf /dist && tsc",
"prebuild": "ts-node scripts/clean",
"docker": "docker build -t barnes-biz/pokemon:1.0.0 .",
"predocker": "npm run build",
},
"dependencies": {
"fastify": "^3.0.0",
"fastify-autoload": "^3.3.1",
"fastify-cli": "^2.13.0",
"fastify-helmet": "^5.3.2",
"fastify-plugin": "^3.0.0",
"fastify-sensible": "^3.1.0",
"fastify-swagger": "^4.8.3",
"mongoose": "^5.13.5",
"weak-napi": "^2.0.2"
},
"devDependencies": {
"#types/jest": "^26.0.23",
"#types/node": "^15.0.0",
"#types/rimraf": "^3.0.1",
"#typescript-eslint/eslint-plugin": "^4.28.0",
"#typescript-eslint/parser": "^4.28.0",
"concurrently": "^6.0.0",
"cross-env": "^7.0.3",
"eslint": "^7.29.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^3.4.0",
"fastify-tsconfig": "^1.0.1",
"jest": "^27.0.5",
"prettier": "^2.3.2",
"rimraf": "^3.0.2",
"ts-jest": "^27.0.3",
"ts-node": "^10.0.0",
"typescript": "^4.2.4"
}
}
I don't seem to understand how to do it. Can you help me? Do you also know some best practices that I should follow writing the Dockerfile or anything else? Thank you!
A couple of things:
You want to copy the output of the compiler, not the source files
You still need to install node_modules in the running container, but want to use the production flag to make sure dev dependencies are ignore. The docker file will then look something like this:
FROM node:16-alpine3.11 as build
WORKDIR /usr/src/app
COPY package*.json ./ # A small optimization to allow for caching in between Docker builds
RUN npm ci
COPY . /usr/src/app/
RUN npm run build
FROM node:16-alpine3.11
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY --from=build /usr/build/app . # This line will depend on your tsconfig
RUN ls -la
CMD [ "npm", "start" ]
You could alternatively prune your node_modules in the build image and copy that over as well.

Typescript Looks for Redis Types in wrong location inside Docker

My typescript compiler is looking in the wrong place for the types for one of my modules (redis), but only when run inside of Docker. Here's the end of the logging information running tsc inside the container:
======== Module name '../classes/range' was successfully resolved to '/app/node_modules/#types/semver/classes/range.d.ts' with Package ID '#types/semver/classes/range.d.ts#7.3.4'. ========
... more successful logs ...
node_modules/#types/connect-redis/index.d.ts(22,29): error TS2694: Namespace '"/app/redis"' has no exported member 'RedisClient'.
As you can see, it appears that the tsc command is looking inside of /app/redis for the member RedisClient rather than inside /app/node_modules/#types/redis which does export the type information. The tsc compiler doesn't have any problems when run from my local machine, only when it's being run inside the docker instance. Why is this the case?
Inside docker, the tsc command is being run from my package.json file, which is being run using docker-compose. The docker-compose file looks like this:
version: "3"
services:
api:
image: "typeorm-api:production"
container_name: "typeorm-api"
build:
context: ./
dockerfile: Dockerfile
volumes:
- ./src:/app/src
environment:
ENV: production
PORT: 1234
env_file:
- ".env.production"
# This command will overwrite what is contained in the Dockerfile
command: "npm run start:production"
ports:
- 1234:1234
depends_on:
- redis_server
reverse:
container_name: reverse
hostname: reverse
image: nginx:latest
volumes:
- ${PWD}/nginx/nginx.conf:/etc/nginx/nginx.conf
ports:
- 80:80
- 443:443
redis_server:
image: "redis:alpine"
container_name: redis_server
volumes:
- "./redis/production/data:/var/lib/redis"
expose:
- 6379
The npm run start:production command runs a command that's contained inside my package.json file (which installs my dependencies inside my application on the build step) and looks like this:
"start:production": "tsc --extendedDiagnostics --traceResolution && node dist/index.js"
The part that's failing is the tsc step and gives the error mentioned above.
The development settings work fine. Other files that might be useful in debugging, listed below.
Full package.json file:
{
"name": "myapi",
"version": "0.2.1",
"devDependencies": {
"#types/bcryptjs": "^2.4.2",
"#types/connect-redis": "^0.0.16",
"#types/cors": "^2.8.10",
"#types/express": "^4.17.11",
"#types/express-session": "^1.17.3",
"#types/ioredis": "^4.22.0",
"#types/node": "^14.14.31",
"#typescript-eslint/eslint-plugin": "^4.15.2",
"#typescript-eslint/parser": "^4.15.2",
"eslint": "^7.21.0",
"ts-node": "9.1.1",
"ts-node-dev": "^1.1.6"
},
"dependencies": {
"#types/redis": "^2.8.28",
"apollo-server-express": "^2.21.0",
"bcryptjs": "^2.4.3",
"class-validator": "^0.13.1",
"connect-redis": "^5.1.0",
"cors": "^2.8.5",
"express": "^4.17.1",
"express-session": "^1.17.1",
"graphql": "^15.5.0",
"ioredis": "^4.23.0",
"pg": "^8.5.1",
"redis": "^3.0.2",
"reflect-metadata": "^0.1.13",
"type-graphql": "^1.1.1",
"typeorm": "0.2.31",
"typescript": "^4.2.2"
},
"scripts": {
"start:development": "ts-node-dev --respawn --poll src/index.ts",
"start:production": "tsc --extendedDiagnostics --traceResolution && node dist/index.js"
}
}
Full Dockerfile
FROM node:15.4.0-alpine3.10
# Specify that when you create the container, put the application inside the /app container
WORKDIR /app
# Copy our package.json + package-lock.json file into the /app folder (wildcard allows for package.lock.json)
COPY package*.json /app/
RUN npm ci
# Copy source files + compilation configuration, db connection options, etc.
COPY ./src .
COPY tsconfig.json .
COPY ormconfig.js .
COPY modules.d.ts .
# This command will be overwritten to be start:production with our docker-compose.prod.yml file
CMD npm run start:development
EXPOSE 1234
I'm so dumb.
I'd named a file that I was using in my project redis.ts and placed it in the root of my project. So, when the compiler was following it's normal rules to look for types, it looked at that file first, and didn't see the type declarations declared in it (because it wasn't the redis.d.ts file).
It didn't look inside the node_modules folder because of the name I chose. After changing the redis.ts file to redisConfiguration.ts everything works fine!

Why is Docker suddenly trying to open docker-entrypoint.sh?

I have dockerised a Node.js app for my Ubuntu server. The Dockerfile is incredibly simple, and had been working fine. Suddenly, on my Ubuntu server, I'm now seeing this error:
sudo docker run -p 80:8080 username/test:test
/bin/sh: 0: Can't open /usr/local/bin/docker-entrypoint.sh
My Dockerfile looks like this:
FROM node:12
# Create the app directory
WORKDIR /Tap2Tap/TapServer
COPY package*.json ./
RUN npm install
# Bundle app source
COPY . .
EXPOSE 8080
CMD ["npm", "start"]
There is no reference to this docker-entrypoint.sh and I don't know why it seems to have spontaneously stopped working. Any help would be much appreciated.
Best,
Peter
package.json file is:
{
"name": "Tap2Tap",
"version": "0.0.0",
"scripts": {
"start": "node ./bin/www.js"
},
"dependencies": {
"dotenv": "^8.2.0",
"express": "^4.17.1",
"helmet": "^3.22.0",
"https": "^1.0.0",
"mqtt": "^4.0.1",
"pg": "^8.0.3",
"winston": "^3.2.1",
"winston-daily-rotate-file": "^4.4.2"
}

Resources