Express does not run on docker, but on localhost - node.js

I am struggling on deploying my backend to the docker container. I found out, that my ploblem is the express framework. First of all, I must say, that everything works on my localhost fine. But when I deploy my app to the server I am getting the 503 Error (service is not availible). If I initialize my app NOT via express, than everything is also working inside the docker container. So what could be the problem? Here is my docker code:
FROM node:alpine
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
EXPOSE 9080
CMD [ "npm", "start" ]
And here is my node code:
var express = require('express');
var app = express();
app.listen(process.env.PORT || 9080);
app.get('/test', function(req, res){
res.send("hi");
});
And here is my package.json:
{
"name": "server",
"version": "1.0.0",
"description": "Backend Shareco",
"main": "index.js",
"scripts": {
"start": "node index.js"
},
"author": "Shareco GmbH",
"license": "ISC",
"dependencies": {
"multer": "1.1.0",
"mysql": "^2.13.0",
"express": "^4.14.0"
}
}
Why does it not work? Would be thankful for any help.
Kind regards,
Andrej

After you run docker build, when you run docker run you need to implement port forwarding by using the -p tag.
In your case, you would run
docker run -p 5000:9080 <image id>
Now when you go to http://localhost:5000 you should see your app running.

Related

docker-compose exit code 243 on node v18.4.0

When I try to deploy a container using docker-compose, I get the following error:
testing |
testing | > test#1.0.0 start
testing | > npm-run-all --parallel start:server
testing |
testing |
testing | ERROR: "start:server" exited with 243.
testing exited with code 1
This only happens on any node:18.4.0 images. I have to use that node version.
My Dockerfile:
FROM node:18.4.0-alpine3.16
WORKDIR /app
COPY ./package.json ./
COPY ./package-lock.json ./
RUN npm install
COPY . /app
EXPOSE 80
CMD npm start
My docker-compose
version: '2'
services:
testing:
container_name: testing
build:
context: .
volumes:
- '.:/app'
ports:
- 80
- 9009:9009
My app (index.js):
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
My package.json
"name": "test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "npm-run-all --parallel start:server",
"start:server": "nodemon .",
"start:web": "echo web starting"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.18.1",
"nodemon": "^2.0.18"
},
"devDependencies": {
"npm-run-all": "^4.1.5"
}
}
os: Ubuntu 20.04.4 LTS.
docker-compose: version 1.29.2
docker: Docker version 20.10.12, build 20.10.12-0ubuntu2~20.04.1
Maybe you found the problem, but this can help someone:
I was havin the same issue using node:bullseye image that comes with npm v8.13.0, so I updated it to the latest version (v8.15.1, in my case) an it was solved.
So, to keep using this image with the latest version, i put this in Dockerfile:
RUN npm install -g npm#latest
You have a volume mapping onto the /app path. That hides everything in that path in the image, including the npm packages you install when building your Dockerfile.
Also, your port mappings don't match your app. Your app listens on port 3000, so your should map port 3000 to a host port.
If you use this docker-compose file, it'll work.
version: '2'
services:
testing:
container_name: testing
build:
context: .
ports:
- 3000:3000
Then you can go to http://localhost:3000/ and you'll get your "Hello World!" message.
First of all, In your index.js you exposed port 3000 const port = 3000.
But on docker you exposed 80 and 3009
ports:
- 80
- 9009:9009
A tip - you don't have to COPY ./package.json ., you copied the entire folder into the container.
WORKDIR /app
COPY . /app
RUN npm install
EXPOSE 80
CMD npm start

docker run puts me into a node repl

When I go to run docker run -p 8080:3000 --name cabinfeverInstance -t something/cabinfever I get put into a Node.js REPL, when I expect to see "Listening on port: 3000". Going to localhost:8000 results in a "didn’t send any data. ERR_EMPTY_RESPONSE". I have found no other instances of this occurring (maybe I am not searching Google for the correct words/tricky phrases). I did find this issue which seems somewhat related. Their solution was to "make the containerized app expect requests from the windows host machine IP (not container IP)", but I am not sure how to implement that. Also, their solution could also not be my solution.
What I have tried:
Clean/purging the data.
Running docker run -p 8080:3000/tcp -p 8080:3000/udp --name cabinfeverInstance -t something/cabinfever
Not specifying the specific port (8080).
Specifying 0.0.0.0.
Several additional ideas.
None have worked and I still get the wonderful Node REPL.
If anyone has any suggestions, I would appreciate them.
Here are the relevant files:
index.js
var express = require('express');
var app = express();
var port = 3000;
app.get('/', function(req,res) {
console.log(new Date().toLocaleString());
res.send(new Date().toLocaleString());
});
app.listen(port, () => {
console.log(`Listening at http://localhost: ${port}`);
});
package.json:
{
"name": "docnode",
"version": "1.0.0",
"description": "barebones node on docker",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "index.js"
},
"author": "my.email.address#gmail.com",
"license": "MIT",
"dependencies": {
"express": "^4.15.5"
}
}
docker-compose.yml:
version: "3"
services:
node:
build: .
command: node index.js
ports:
- "3000:3000"
Dockerfile:
FROM node:slim
LABEL author="my.email.address#gmail.com"
WORKDIR /app
# copy code, install npm dependencies
COPY index.js /app/index.js
COPY package.json /app/package.json
RUN npm install
You should specify the command to run in the Dockerfile, not the docker-compose.yml file:
CMD ["node", "index.js"]
When you docker run an image, the only options it considers are those on the docker run command line. docker run doesn't know about docker-compose.yml, so if you specify things like command: there it won't be honored. Since the CMD isn't in the Dockerfile and it isn't on the docker run command line (after the image name), you fall back to the base image's CMD, which in the case of node is to run the REPL.
With this change you don't need to override command: in the docker-compose.yml file and you can delete that line. Running
docker-compose up -d
will start the container(s) in the docker-compose.yml file with the options specified there (note, the ports: mapping and the docker run -p ports are slightly different).

How do you setup Nodemon in a Docker container?

I am trying to setup Nodemon in a Docker container. It says that nodemon is running, but when I change code in my index.js file it does not reload like it does outside of docker. I've tried adding -L to the command, but no luck. I've also tried installing nodemon in the docker file instead, but no luck.
I have to do docker-compose up --build anytime I change my index.js file.
Any ideas?
Here is my file structure:
-api
-node_modules
-.dockerignore
-Dockerfile
-index.js
-package.json
-package-lock.json
-docker-compose.yml
docker-compose.yml:
version: '3.4'
services:
api:
build:
context: ./api
container_name: api
environment:
- PORT=3001
volumes:
- ./api/src:/usr/app/src
ports:
- '3001:3001'
command: npm run dev
Dockerfile:
FROM node:14.15.2-alpine3.12
WORKDIR /usr/app
COPY package*.json ./
RUN npm install
COPY . .
package.json:
{
"name": "api",
"version": "1.0.0",
"description": "",
"main": "index.js",
"dependencies": {
"express": "^4.17.1"
},
"scripts": {
"dev": "nodemon index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"nodemon": "^2.0.6"
}
}
I FIGURED IT OUT!!!
After a lot of trial and error. It has to do with my volumes in my docker compose as well as nodemon. Not 100% sure why any insight would be helpful too.
The fix was to change my volume from
- ./api/src:/usr/app/src
to:
- ./api:/usr/src/app
Then I had to add the -L flag to my nodemon command in order for it to reload.

docker with nodejs(running pm2) with postgresql

I am new to Docker. I have an application which runs on apache2 and nodejs (running on pm2) with postgresql database.
I am trying to create a Dockerfile and package.json file to the existing project(which mentioned above) but I am not able to proceed further as sometimes I am getting error as npm problem.
I am trying to do it sample nodejs with apache running but I am getting this error .. curl: (52) Empty reply from server.
My sample Dockerfile is
FROM node:4.2.6
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
#RUN npm install pm2 -g
COPY . .
EXPOSE 4000
CMD ["npm", "start"]
My Package.json is
{
"name": "pm2",
"version": "1.0.0",
"description": "Node.js on Docker",
"author": "",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.1"
}
}
Please help me out

Node.js spawn process not working inside Docker container

I have a server.js file in Node that calls python scripts as follows:
// call python scripts
var spawn = require("child_process").spawn;
var process = spawn('python',["test.py", function_args]);
process.stdout.on('data', function (data){
res.json({
"answer" : from_python
})
});
This works perfectly when simply running node as usual:
node server.js
But when I place everything inside a docker container, the application never enters the process.stdout.on
Everything else works perfectly. I can serve static files, call express endpoints, etc. It is just the process that is not getting called.
I have tried placing child_process inside my package.json file as a dependency.
Here is my Dockerfile:
FROM node:carbon
# 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
COPY package*.json ./
RUN npm install
# Bundle app source
COPY . .
EXPOSE 80
CMD ["npm","start"]
This is my package.json file:
{
"name": "my_app_name",
"version": "1.0.0",
"description": "my_desc",
"author": "my_name",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"dependencies": {
"express": "^4.16.2",
"path": "^0.12.7",
"fs": "^0.0.1-security",
"child_process": "^1.0.2"
}
}
Note that running server.js is not the problem. This file runs the other pieces such as serving static files and exposing express endpoints. The problem seems to just be with the child_process not running. It is not that Python isn't getting called, it is that node will not even enter the process part of server.js.
Also note that the Python prints its output via stdout. Not sure of docker has an issue registering standard outputs.
I think
FROM node:carbon
should be
FROM node:9.3
Carbon is the LTS (currently still 8..). You are using libraries from latest v9.3.0.

Resources