How to hit HTTP endpoint from Docker image? - node.js

I have NodeJS/TypeScript application (github repo) which is working fine when I run the script defined in package.json. i.e., npm run start will start my local host and I can hit endpoint via POSTMAN.
I have created docker image (I am new to Docker and this is my first image). Here, I am getting Error: connect ECONNREFUSED 127.0.0.1:7001 error in POSTMAN.
I noticed that I do not see Listening on port 7001 message in terminal when I run docker file. This tells me that I am making some mistake in .Dockerfile.
Steps:
I created docker image using docker build -t <IMAGE-NAME> . I can see successfully created image.
I launched container using docker run --name <CONTAINER-NAME> <IMAGE-NAME>
I've also disabled Use the system proxy setting in POSTMAN but no luck.
Details:
Package.json file
"scripts": {
"dev": "ts-node-dev --respawn --pretty --transpile-only src/server.ts",
"compile": "tsc -p .",
"start": "npm run compile && npm run dev"
}
Response from terminal when I run npm run start (This is successful)
Dockerfile
#FROM is the base image for which we will run our application
FROM node:12.0.0
# Copy source code
COPY . /app
# Change working directory
WORKDIR /app
# Install dependencies
RUN npm install
RUN npm install -g typescript
# Expose API port to the outside
EXPOSE 7001
# Launch application
CMD ["npm", "start"]
Response after running docker command
GitHub repo structure

By any chance did you forget to map your container port to the host one?
docker run --name <CONTAINER-NAME> -p 7001:7001 <IMAGE-NAME>
the -p does the trick of exposing the port to your network. The number on the left side is the container port (7001 as exposed on the Dockerfile) and the second one is the target port on the host machine. You can set this up to other available ports as well. Eg.: -p 7001:3000to expose on http://localhost:3000
Check out Docker documentation about networking

Finally, I was able to make this work with two things:
Using #Dante's suggestion (mentioned above).
Updating my .Dockerfile with following:
FROM node:12.0.0
# Change working directory
WORKDIR /user/app
# Copy package.json into the container at /app
COPY package*.json ./
# Install dependencies
RUN npm install
RUN npm install -g typescript
# Copy the current directory contents into the container at root level (in this case, /app directory)
COPY . ./
# Expose API port to the outside
EXPOSE 7001
# Launch application
CMD ["npm", "run", "start"]

Related

Docker container is refusing connection

I am using Dockerfile for Nodejs project but its returning Connection refused error
When I run the app without Docker it works absolutely fine.
Command I use to build and run the docker container is as follows:
docker build -t myapp .
docker run -it -p 8080:8080 myapp
Running above command runs without any error but when I hit http://localhost:8080/test-url it fails
My dockerfile is as follows:
FROM node:16.16.0-alpine
ADD . /opt
COPY . .
RUN npm install
EXPOSE 8080
RUN chmod +x /opt/deploy.sh
RUN apk update && apk add bash
CMD ["/bin/bash", "/opt/deploy.sh"]
And my package.json is as follows (truncated to show only script):
"scripts": {
"start": "DEBUG=app* node index.js",
"build": "rimraf build && babel-node ./src --out-dir build/src && npm run docs",
"dev": "DEBUG=app* nodemon --exec babel-node index.js",
"lint": "eslint 'index.js' 'src/**/*.js' 'src/index.js'",
"docs": "apidoc -i src/ -o public/docs",
"prepare": "husky install",
"lint-staged": "lint-staged"
},
For development I use following command which works fine::
npm run dev
For deploymeent I run deploy.sh which has env variables and final command as ::
npm run build
npm run start
Even when I am trying http://localhost:8080/test-url by loging into docker interactive terminal it returns same error - Connection Refused
Your Port mapping looks right to me. Did you check your firewall? Maybe it is blocking the connection. It could also be helpful to test, if you can run an NGINX-Container on Port 8080. That way you can check if it is a general configuration-problem with Docker or a specific problem of your Image.
Also, did you try to set your node server to listen to 0.0.0.0 instead of localhost? I'm not sure how Docker handles IPs in the Containers, but I was thinking maybe it is called by it's internal ip. If that is the case and your server listens to localhost only, it shouldn't accept the connection.
I hope one of these things can point you in the right direction.

Docker Node backend - "this site can't be reached"

I'm trying do build a docker image of my Node backend for deployment but when I run it in a container and open in the browser I get "This site can’t be reached" error and the following log in dev tools:
crbug/1173575, non-JS module files deprecated
My backend is based on GraphQL Apollo server. Dockerfile is as following:
FROM node:16
WORKDIR /app
COPY ./package*.json ./
RUN npm ci --only=production
# RUN npm install
COPY . .
# RUN npm run build
EXPOSE 4000
CMD [ "node", "dist/main.js" ]
I've also tried to use the commented code, with no result.
The image builds without a problem and after running the container I get 🚀 Server ready at localhost:4000 in the docker logs, so I'd expect it to work properly.
"scripts": {
"build": "tsc",
"start": "node dist/main.js",
"dev": "concurrently \"tsc -w\" \"nodemon dist/main.js\""
},
That's the scripts part of my package.json I've also tried CMD ["npm", "start"] in Dockerfile but that doesn't work either. When I run the backend from terminal using npm start I can access the GraphQL playground at localhost:4000 - I assume that should be the same with docker?
I'm still new to docker so I'd be grateful for any hints. Thanks
EDIT:
I run the container with the following command:
docker run --rm -d -p 4000:80 image-name:latest
Seemingly it's running on port 0.0.0.0:4000 as that's what it says under 'PORT' when I execute docker ps
Please run docker inspect command and you will get IP and then run through that ip in browser

Dockerfile to run nodejs static-content in docker container

Need an advice to dockerize and run a node JS static-content app on K8s cluster.
I have a static web-content which I run "npm run build” into the terminal which generates /build and direct my IIS webserver to /build/Index.html.
Now, I started creating a Docker file, how do I point my nodeJS image to invoke /build/Index.html file
FROM node:carbon
WORKDIR /app
COPY /Core/* ./app
npm run build
EXPOSE 8080
CMD [ "node", ".app/build/index.html" ]
Please how can I run this app only on node v8.9.3 and
npm 5.6.0 ?
Any inputs please ?
You can specify the version of node specifically:
FROM node:8.9.3
Assumptions:
package.json is under Code directory.
npm run build will be running outside of the container and a build directory will be created in Code directory.
We will copy the whole Code/build directory under /app directory of the container.
We will copy package.json to /app folder and will run the website through scripts available in package.json file.
Solution:
I would say add a script named start in the package.json and call that script from Dockerfile's CMD command. The script would look like:
"scripts": {
"start": "node ./index.html",
},
And the Dockerfile would look like:
FROM node:8.9.3
# Make app directory in the container.
RUN MKDIR /app
# Copy whole code to app directory.
COPY Code/build/ /app
# Copy package.json app directory.
COPY package.json /app
# make app directory as the working directory.
WORKDIR /app
# Install dependencies.
RUN npm install -only=production
# Expose the port
EXPOSE 8080
# Start the process
CMD ["npm", "start"]

Docker + React App - Docker run command doesn't open up localhost

I'm having trouble with running Docker (I'm a total beginner at it) with my React app. This was given as a coding challenge so I was given these Docker commands:
docker build --tag app-name .
docker run -it -p 7357:80 app-name
Here is my dockerfile:
FROM node:6-wheezy
WORKDIR /srv/tenor-frontend-test/
COPY package.json package-lock.json ./
RUN npm install
COPY . .
EXPOSE 80
ENV NODE_JS_PORT=80
CMD [ "npm", "start" ]
My start script in package.json:
"start": "PORT=7357 react-scripts start"
Using "npm start" in my terminal opens up localhost fine but when I run the "docker run" command, it prints exactly what happens with "npm start" but no browser opens and localhost:7357 doesn't work.
I'm hoping this is just a dockerfile issue since "npm start" works fine?
Thanks in advance!

On server startup NPM find start script

I'm working with docker and I'm wondering how I can get the command npm start to locate the app.js file without me doing it via the command line.
my package.json (located: /srv/www) looks as so:
{
"name": "dist",
"version": "1.0.0",
"description": "",
"main": "app.js",
"scripts": {
"start": "forever start -c \"nodemon --harmony\" app.js --exitcrash"
},
"author": "",
"license": "ISC"
}
I'm currently invoking my docker image as so:
docker run -d -v /srv/docker/instantynode/srv:/srv -p 80:8080 myimg ???
I am hoping to replace the ??? with a command which will startup node and invoke npm start in the correct directory, any ideas?
I was thinking maybe of making a little startup script to fix this however I was wondering if npm can fix this on it's own?
Regarding node application, you can start with ONBUILD in Dockerfile, so you can try as below:
$ cat Dockerfile
FROM node:0.10-onbuild (or version 0.12, depend your request)
PORT 8000
the image node:0.10-onbuild has codes already as below:
WORKDIR /usr/src/app
ONBUILD COPY package.json /usr/src/app/
ONBUILD RUN npm install
ONBUILD COPY . /usr/src/app
CMD ["npm" "start"]
With ONBUILD, during docker build, your node.js (or angularjs) codes will be not copied to image and npm install doesn't run.
But when you run the container, it starts to copy the files to /usr/src/app and install npm package. Then start npm service.
So in your case, you should be fine to run your application directly without mount the volume every time.
# I guess file package.json is under /srv/docker/instantynode/srv
$ cd /srv/docker/instantynode/srv
$ cat Dockerfile
FROM node:0.10-onbuild
PORT 8000
$ docker build -t myimg .
$ docker run -d -p 8000:8000 myimg
That's all, you should be fine to access your application via port 8000 now.

Resources