Can we use http package in nodejs with docker - node.js

I am researching about docker and I have code a demo nodejs with docker. I use HTTP package in nodejs instead of express, the app is built with docker, but when I go to localhost:80, the return is
ERR_EMPTY_RESPONSE
I have code a demo with nodejs and use express, it can run, and I cannot find any example using HTTP package.
I do not clear what EXPOSE port in docker for, that is port call to browser or port for app?
Docker file
FROM node:8
RUN mkdir -p /home/node/app && chown -R node:node /home/node/app
WORKDIR /home/node/app
COPY package*.json ./
USER node
RUN npm install
COPY --chown=node:node . .
EXPOSE 80
CMD ["npm", "start"]
index.js
const http = require('http');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/plain');
res.end("Hello world \n");
});
server.listen(port, hostname, () => {
console.log(`server is running at abcxyz http://${hostname}:${port}/`);
});

Have you published the port at your docker run command?
docker run -p 80:3000 ...
Your hostname if you run it without docker is localhost (127.0.0.1)
But if you run it in docker it have to be:
const hostname = '0.0.0.0';

In your code, server listens to PORT 3000 and you have exposed PORT 80 to HOST which means PORT 80 has nothing corresponding running inside docker container, you actually have to EXPOSE PORT 3000 from docker container and use that.
You can use this command to map to a port usable in host where port number before : represents port to be exposed in host and port number after : represents port in docker container that's exposed AFAIK.
docker run -p 80:80

Related

Failed to start and then listen on the port

I have an NodeJS app that I want to deploy on Google Cloud Run.
I have Google Cloud Build configured to build container from dockerfile whenever something has been pushed ona master branch and after build Cloud Run will run new revision.
My problem is that every time I want to deploy my app I got the following error:
Cloud Run error: Container failed to start. Failed to start and then listen on the port defined by the PORT environment variable.
Cloud Run have configured containerPort: 8080
In my dockerfile I'm exposing port 8080 and in nodejs I have set up simply http server using
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, {'Content-Type': 'text/plain'});
res.end('Just for testing purposes\n');
});
const port = parseInt(process.env.PORT, 10) || 8080;
server.listen(port, '0.0.0.0', () => {
console.log('Hello world listening on port', port);
});
my Dockerfile
FROM node:12-alpine
# Install app dependencies.
COPY package.json /src/package.json
WORKDIR /src
RUN npm install
# Cloud Run requrement
EXPOSE 8080
COPY index.js /src/index.js
ENTRYPOINT "node index.js"
Have I missed something? This is my first time working with google cloud so I'm sure there is something I need to configure that I don't know about yet.
The problem was in my Dockerfile.
I had to change ENTRYPOINT "node index.js" to CMD ["node", "index.js"].
Bu reason behind it is still unknown to me.

node js docker is not running on heroku

Node js project in Docker container is not running on Heroku.
Here is the source code.
Docker file
FROM node:14
WORKDIR /home/tor/Desktop/work/docker/speech-analysis/build
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD [ "node", "server.js" ]
server.js
'use strict';
const express = require('express');
const PORT = process.env.port||8080;
const app = express();
app.get('/', (req, res) => {
res.send('Hello World');
});
app.listen(PORT);
console.log("Running on http://:${PORT}");
You don't need to expose anything when having a container for Heroku. It takes care of it automatically. If you are running the same Docker locally, you can do:
docker build -t myapp:latest .
docker run -e PORT=8080 -p 8080:8080 -t myapp:latest
I think that the environment variables are case-sensitive on Linux systems - so you need to change the
const PORT = process.env.port||8080;
... to:
const PORT = process.env.PORT||8080;
... as Heroku sets an environment variable PORT (and not port).
According to this answer you just need to use the port 80 in your expose or inside of nodejs:
app.listen(80)
Heroku at run, will generate a random port and bind it to 80
docker run ... -p 46574:80 ...
So if your nodejs app is running at port 80 inside of container, everything will be fine

Can't access Hapi server inside Docker Container

I built a simple NodeJS server with Hapi and tried to run it inside a Docker container.
It runs nicely inside Docker, but I can't get access to it (even though I have done port mapping).
const hapi = require("#hapi/hapi");
const startServer = async () => {
const server = hapi.Server({
host: "localhost",
port: 5000,
});
server.route({
method: 'GET',
path: '/sample',
handler: (request, h) => {
return 'Hello World!';
}
});
await server.start();
console.log(`Server running on port ${server.settings.port}`);
};
startServer();
Docker file is as follows:
FROM node:alpine
WORKDIR /usr/app
COPY ./package.json ./
RUN npm install
COPY ./ ./
CMD [ "npm","run","dev" ]
To run docker, I first build with:
docker build .
I then run the image I get from above command to do port mapping:
docker run -p 5000:5000 <image-name>
When I try to access it via postman on http://localhost:5000/sample or even localhost:5000/sample, it keeps saying Couldn't connect to server and when I open in chrome, it says the same Can't display page.
PS. When i run the code as usual without Docker container, with simply npm run dev from my terminal, the code runs just fine.
So, I am confident, the API code is fine.
Any suggestions??
As mentioned by #pzaenger on your HAPI server configuration change localhost to 0.0.0.0.
host: 'localhost' to host: '0.0.0.0',

Creating a Docker Container to deploy to a prod env

I'm having some problems with building my application through Jenkins and running the container on a extrernal tomcat.
Dockerfile:
FROM node:10.16.3
RUN ls -al
WORKDIR /app
COPY /package/repo/package.json /app/package.json
RUN npm install
COPY /package/repo /app
RUN npm run build
EXPOSE 8080
CMD ["npm", "start]
npm start calls node server.js
server.js:
const express = require('express');
const app = express();
const port = 8080;
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(port, () => {
console.log(`Example app listening on port ${port}!`);
console.log(__dirname+'/client/build/index.html');
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
docker build -t reacttest .
docker run reacttest
I'm trying to access the container using localhost:8080, however, whenever I access that port, I'm getting error not found. Is there a step I'm missing. Sorry, i'm very new to docker.
You need to map a port from your machine to the container. Use the p flag for this.
docker run reacttest -p 8080:8080
In general the syntax is:
docker run <image> -p <host port>:<container port>
You can read more in the documentation
EXPOSE does not accually publish the port. You should run you container with -p flag to map ports from container to your host system. See the documents.

Docker EXPOSE. Can't get it

this past two day I'm having trouble with docker and i can get it. Following to the docker doc you can expose the ports on which a container will listen for connections with EXPOSE. So far, so good!
If my app listen on port 8080 I should expose my docker container with EXPOSE 8080 and bind it to port 80 of the main host with docker run -p 80:8080.
Here is my Dockerfile:
# DOCKER-VERSION 0.0.1
FROM ubuntu:14.10
# make sure apt is up to date
RUN apt-get update
# install nodejs and npm
RUN apt-get install -y nodejs-legacy npm git git-core
ADD package.json /root/
ADD server.js /root/
# start script
ADD start.sh /root/
RUN chmod +x /root/start.sh
EXPOSE 8080
CMD ./root/start.sh
And my start.sh just runan cd /root/ & npm install & node server.js.
I got a simple express nodejs app:
var express = require('express');
// Constants
var PORT = 8080;
// App
var app = express();
app.get('/', function (req, res) {
res.send('Hello world\n');
});
app.listen(PORT);
console.log('Running on http://localhost:' + PORT);
Here is how i build my docker image: docker build -t app1 .
And how i launch my docker: docker run -it -p 80:8080 --name app1 app1
What is really wired, this is not working. To make it work i have to change EXPOSE 8080 to EXPOSE 80. I don't get it.
Any explanation?
Thanks for reading,
Tom
In your nodejs app, you have the instruction app.listen(PORT); which tells nodejs to start a server listening for connections on the loopback interface on port PORT.
As a result your app will only by able to see connections originating from localhost (the container itself).
You need to tell your app to listen on all interfaces on port PORT:
app.listen(PORT, "0.0.0.0");
This way it will see the connections originating from outside your Docker container.

Resources