Having modules problems Dockerizng simple node app - node.js

Having some problems while trying to create my first node.js app , super new to JS..
Trying to dockerize the app , like so :
docker build -t echo_app .
docker run -p 3000:3000 echo_app
End goal is to echo user input , like so :
http://example/?name=Eyal -> Hello Eyal
http://example/ -> Hello World
ERROR IM GETTING
Error: Cannot find module 'express'
Require stack:
- /app/index.js
.
.
code: 'MODULE_NOT_FOUND',
requireStack: [ '/app/index.js' ]
}
Directroy containes :
index.js
const express = require('express')
const log4js = require('log4js')
const app = express()
const logger = log4js.getLogger()
const echo = (req, res) => {
logger.debug("Request: ", req)
const input = 'name' in req.query ? req.query.input : ''
if (input.length == 0) {
res.send('Echo World')
} else {
res.send(`Echo ${input}`)
}
}
app.get('/', (req, res) => echo(req, res))
Dockerfile
FROM mhart/alpine-node:12
WORKDIR /app
ADD . ./
ENTRYPOINT ["node", "/app/index.js"]
package.json
{
"name": "echo",
"version": "1.0.0",
"description": "You talk, we talk back!",
"main": "index.js",
"author": "eyal",
"license": "MIT",
"dependencies": {
"express": "^4.17.1",
"js-yaml": "^3.13.1",
"log4js": "^5.2.2",
"saslprep": "^1.0.3"
}
}

To get it up and running, you first need to install the node dependencies by adding npm install to your Dockerfile, like this
FROM mhart/alpine-node:12
WORKDIR /app
ADD . ./
RUN npm install
ENTRYPOINT ["node", "/app/index.js"]
Then you need to have your Node app listen for requests by adding
app.listen(3000, () => {
console.log(`Example app listening at http://localhost:3000`)
})
at the bottom of index.js.
Finally, a small error in your code. req.query.input needs to be req.query.name.
That should hopefully get you going.

Related

NodeJS + Docker + OSX

I'm trying to run from Docker a simple "hello world" in NodeJS, following a video tutorial. This is my first attempt in nodejs and in Docker so I'm sure I miss something obvious but passing through the video compared to the code I wrote many times, I still can't find the error.
Locally it works fine, but in Docker is unable to run. In Docker Desktop the container becomes green and immediately gray again.
I've tried to change the path many times, thinking that the problem is there but without any clue. I really haven't the experience to investigate further, please help me to solve the issue.
My Dockerfile
FROM node:16
WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . ./
EXPOSE 3000
CMD ["npm", "run", "dev"]
package.json
{
"dependencies": {
"express": "^4.18.1",
"node": "^18.5.0"
},
"name": "contratti",
"version": "1.0.0",
"description": "prova",
"main": "App.js",
"scripts": {
"start": "node App.js",
"dev": "nodemon -L App.js"
},
"author": "jegor",
"license": "ISC",
"devDependencies": {
"nodemon": "^2.0.19"
}
}
App.js
const express = require("express");
const app = express();
app.get("/", (req,res) => {
res.send("<h2> Ciao ciao ..</h2>");
});
const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Server running at ${port}`));
ZSH
docker run -v $(pwd):/usr/src/app -p 3000:3000 -d --name contratti contratti
Error returned
> contratti#1.0.0 dev
> nodemon -L App.js
/usr/src/app/node_modules/.bin/node: 1: /usr/src/app/node_modules/.bin/node: �����: Input/output error
/usr/src/app/node_modules/.bin/node: 3: /usr/src/app/node_modules/.bin/node: Syntax error: Unterminated quoted string

How to write API for updation of json data in node js

I have json object in front end while changing any object value ,that should be changed in Backend.we are using Node.js in Backend .For that I have to write API.How do I write .I am new to node js.
updateCountryConfig(config:any): Observable {
const url = ${AppConst.API_BASE_URL}/settings/update-config;
return this.http.post(url,config)
}
I have written like this in frontend.
This is a very generic question, but you can create your API using Node JS and Express JS. Check out this video and it will show you some basics.
Here is the code for a simple REST API,
Initialize your Node JS project with,
npm init
You will be asked to fill all of the below information for your project.
Once this command is run, you will have a package.json created.
Create your /src folder and app.js file.
mkdir src
cd src
touch app.js
Add the following code in your /src/app.js file.
console.log("I love tutorials from With Chanakya!");
Install express using npm as a dependency and nodemon as a dev-dependency.
npm install --save express
npm install --save-dev nodemon
Run the code with,
nodemon app.js
You can always use ctrl+c to come out of nodemon.
Update your package.json to have a start script.
{
"name": "dog-api",
"version": "1.0.0",
"description": "REST API that retrieves dog breeds ",
"main": "app.js",
"scripts": {
"start": "nodemon src/app.js"
},
"author": "Chanakya Lokam",
"license": "ISC",
"dependencies": {
"express": "^4.17.3"
},
"devDependencies": {
"nodemon": "^2.0.15"
}
}
Create basic REST API - refer to /src folder for soure code. We will create the following files,
app.js
// console.log("Subscribe to my channel - With Chanakya!");
//Import modules
const express = require("express");
const dogRoutes = require("./routes/dog.routes");
// Define PORT for HTTP Server
const PORT = 9900;
// Initialize Express
const app = express();
app.use(dogRoutes);
app.listen(PORT, (err) => {
console.log(`Server is up at localhost ${PORT}`);
});
/routes/dog.routes.js
const express = require("express");
const router = express.Router();
// Define Dog Breeds array
const dogs = [
{ id: "1", name: "Happy", breed: "Golden Retriever" },
{ id: "2", name: "Silky", breed: "Labrador" },
{ id: "3", name: "Mika", breed: "Husky" },
];
// GET route for Dogs
router.get("/dogs", (req, res) => {
res.status(200).send(dogs);
});
// GET route for Dog Breed Search
router.get("/dog/:name", (req, res) => {
var notFound = true;
// Find dog breed based on name
dogs.forEach((dog) => {
if (dog.name == req.params.name) {
//res.status(200).send(`${req.params.name} is a ${dog.breed}`);
notFound = false;
res.status(200).send(dog);
}
});
if (notFound) res.sendStatus(404);
});
module.exports = router;
You can now run your API using nodemon and test the routes in Postman (or) using curl.

Add a simple React form application to an existing Nodejs docker image

I have created a Dockerfile, when run with docker-compose displays 'Hello world' in the browser. Now I want to be able to display a simple react form with some fields to enter text in and a submit button. Is there examples of any simple projects out there that I can just use. How will I update my files, that I have shown below
These are the files that I cam using:
Package.json -
{
"name": "nodejs-hello",
"version": "1.0.0",
"description": "des",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "hh",
"license": "ISC",
"keywords": [
"h"
],
"dependencies": {
"express": "^4.17.1"
}
}
index.js -
//now it load express module with `require` directive
var express = require('express')
var app = express()
const PORT = 8080;
//Define request response in root URL (/) and response with text Hello World!
app.get('/', function (req, res) {
res.send('Hello World')
})
//Launch listening server on port 8080 and consoles the log.
app.listen(PORT, function () {
console.log('app listening on port ' + PORT)
})
Dockerfile -
FROM node:latest
WORKDIR /app
COPY package.json index.js ./
RUN npm install
EXPOSE 8080
CMD node index.js
Docker Compose -
version: "3"
services:
web:
image: my-image:1.0
build: .
ports:
- '8080:8080'
https://medium.com/faun/a-simple-docker-setup-for-simple-hello-world-nodejs-application-bcf79bb608a0
What I have now is similar to the example in that link.
Now I just want to be able to display a react form in the browser.
Just create your React app and then add this line to copy the src files into the container:
COPY . .
Also, change the CMD (if you're using a CRA) to this:
CMD [ "npm", "start" ]

Running react and node in a single port using Dockerfile

I am trying to run docker for my sample project where in the container I need a single port to run, But the build of react code will serve as the index.html, I have the below folder structure.
In index.js file I have tried to add the static path, What am I doing wrong here? I have commented it..
I have tried this much.
sampleapp
client
// using cra (create react app) files
src
public
...
server
index.js
Dockerfile
// app.js
import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';
class App extends Component {
state = {
response: null
}
componentWillMount(){
this.dataFetching()
}
dataFetching = async () => {
const resjson = await fetch('/api/data');
const res = await resjson.json();
this.setState({
response: res.data
})
}
render() {
return (
this.state.response ? this.state.response : null
);
}
}
export default App;
// package.json --client
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.8.3",
"react-dom": "^16.8.3",
"react-scripts": "2.1.5"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"proxy": "http://localhost:4000"
}
// index.js -- server
const express = require('express');
const path = require('path');
const app = express();
// app.use(express.static(path.join(__dirname, 'build')));
// app.get('/*', function(req, res) {
// res.sendFile(path.join(__dirname, '..', 'app', 'build', 'index.html'));
// });
app.get('/api/data', (req, res) => {
res.send({data: "Success"})
})
app.listen(4000);
// Dockerfile - sampleapp
FROM node:10.15.1-alpine
COPY . /var/app
WORKDIR /var/app/client
RUN npm install --no-cache && npm run build && npm install -g serve
WORKDIR /var/app/server
RUN npm install --no-cache
EXPOSE 4000
EXPOSE 3000
For the Dockerfile you can change it to the following:
FROM node:10.15.1-alpine
COPY . /var/app
WORKDIR /var/app/client
RUN npm install --no-cache && npm run build && npm install -g serve
WORKDIR /var/app/server
RUN npm install --no-cache
EXPOSE 4000
CMD [ "npm", "start", "index.js" ]
For index.js (server), you can change it to the following:
const express = require('express');
const path = require('path');
const app = express();
app.get('/api/data', (req, res) => {
res.send({data: "Success"})
})
app.use(express.static(path.join(__dirname, '..', 'client', 'build')));
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, '..', 'client', 'build', 'index.html'));
});
app.listen(4000, '0.0.0.0');
React will be served as a static file through nodeJS
index.js needs to be binded to 0.0.0.0 so you can connect to it from outside the container.

How to build next.js production?

I try to get a production build in next.js to run it on my server but I can't build next.js production build when I try
npm run build
Does anyone know how to get a prod build in next.js working correctly I did everything in the next.js documentation but always get this error below. If I do a dev build it works just fine but trying prod build results in errors.
I did also next build many times and reinstalled all node_modules packages still having this error.
it always shows me in terminal
Error: Could not find a valid build in the '/mnt/c/Users/NZXT_YOLO/Desktop/New folder (2)/learnnextjs-demo/.next' directory! Try building your app with 'next build' before starting the server.
at Server.readBuildId (/mnt/c/Users/NZXT_YOLO/Desktop/New folder (2)/learnnextjs-demo/node_modules/next/dist/server/next-server.js:753:15)
at new Server (/mnt/c/Users/NZXT_YOLO/Desktop/New folder (2)/learnnextjs-demo/node_modules/next/dist/server/next-server.js:80:25)
at module.exports (/mnt/c/Users/NZXT_YOLO/Desktop/New folder (2)/learnnextjs-demo/node_modules/next/dist/server/next.js:6:10)
at Object.<anonymous> (/mnt/c/Users/NZXT_YOLO/Desktop/New folder (2)/learnnextjs-demo/next.config.js:6:13)
at Module._compile (internal/modules/cjs/loader.js:707:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:718:10)
at Module.load (internal/modules/cjs/loader.js:605:32)
at tryModuleLoad (internal/modules/cjs/loader.js:544:12)
at Function.Module._load (internal/modules/cjs/loader.js:536:3)
at Module.require (internal/modules/cjs/loader.js:643:17)
at require (internal/modules/cjs/helpers.js:22:18)
at loadConfig (/mnt/c/Users/NZXT_YOLO/Desktop/New folder (2)/learnnextjs-demo/node_modules/next/dist/server/config.js:47:28)
at _callee2$ (/mnt/c/Users/NZXT_YOLO/Desktop/New folder (2)/learnnextjs-demo/node_modules/next/dist/build/index.js:52:42)
at tryCatch (/mnt/c/Users/NZXT_YOLO/Desktop/New folder (2)/learnnextjs-demo/node_modules/regenerator-runtime/runtime.js:62:40)
at Generator.invoke [as _invoke] (/mnt/c/Users/NZXT_YOLO/Desktop/New folder (2)/learnnextjs-demo/node_modules/regenerator-runtime/runtime.js:288:22)
at Generator.prototype.(anonymous function) [as next] (/mnt/c/Users/NZXT_YOLO/Desktop/New folder (2)/learnnextjs-demo/node_modules/regenerator-runtime/runtime.js:114:21)
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! hello-next#1.0.0 build: `next build`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the hello-next#1.0.0 build script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /home/kk/.npm/_logs/2018-12-10T19_58_00_588Z-debug.log
server.js
const express = require("express");
const next = require("next");
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV === "production";
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = express();
server.get("*", (req, res) => {
return handle(req, res);
});
server.listen(port, err => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
});
next.config.js
const express = require("express");
const next = require("next");
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV === "production";
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = express();
server.get("/projects/:page", (req, res) => {
const page = req.params.page;
let file = "";
switch (page) {
case "example1":
file = "/projects/example1";
break;
case "example2":
file = "/projects/example2";
break;
}
return app.render(req, res, file, { page });
});
server.get("*", (req, res) => {
return handle(req, res);
});
server.listen(port, err => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
});
package.json
{
"name": "hello-next",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"dev": "node server.js",
"build": "next build",
"export": "next export"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"#zeit/next-sass": "^1.0.1",
"express": "^4.16.4",
"next": "^7.0.2",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"redux": "^4.0.1",
"video-react": "^0.13.1"
}
}
If anyone has an idea would be so nice! I plan to run this next.js site using node on my AWS server. But to do this I need to get production build of react.js currently I can run just a development build.
Hope someone has an idea.
Thanks in advance!
next build followed by next start should be the right commands to prepare the build for production and run it.
Here's an example for package.json. if you want to export application to run as a static content, something like hosting it in s3 as a static website, you need to run next export
...
"scripts": {
"build": "next build",
"start": "next start",
"export": "next export"
}
...
Make sure you have the above scripts in your package.json then run the following in order
$ npm run build
$ npm run start
If you want to start application with specific port, you can specify -p port as argument for npm run command
npm run start -- -p 3232
If you want to incorporate this into a CI/CD pipeline, you need to have Dockerfile, here's a simple example
FROM node:alpine
#copy source
COPY . /app
# Install deps
RUN cd /app && npm install
# Build
RUN npm run build
ENTRYPOINT [ "npm", "run", "start" ]
Still need more explanation or help, don't hesitate to leave a comment and I will be more than happy to assist.
Seems your server.js config is not correct. Please try moving all you have from your next.config.js to server.js make sure the next.config.js file is empty then create a new npm run script:
"prod_start": "NODE_ENV=production node server.js"
Your package.json should then look like this:
{
"name": "hello-next",
"version": "1.0.0",
"description": "",
"main": "server.js",
"scripts": {
"dev": "node server.js",
"build": "next build",
"prod_start": "NODE_ENV=production node server.js",
"export": "next export"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"#zeit/next-sass": "^1.0.1",
"express": "^4.16.4",
"next": "^7.0.2",
"react": "^16.6.3",
"react-dom": "^16.6.3",
"redux": "^4.0.1",
"video-react": "^0.13.1"
}
}
make sure to run: npm run build && npm run prod_start
Then you should have a production build of react running using next.js
Let me know if you got question.
You must launch next build at your root folder and not inside .next/
There are 3 ways todo it:-
way 1: use next build instead of npm run build
way 2: npm run build npm install -g serve serve -s build
more info: https://create-react-app.dev/docs/deployment/
way 3: after npm run build, Remove / from JS,CSS links from /static/index.html file. eg. replace these 2 lines
<script defer="defer" src="/static/js/main.aa87bc08.js"></script>
<link href="/static/css/main.073c9b0a.css" rel="stylesheet"/>
with these 2 lines
<script defer="defer" src="static/js/main.aa87bc08.js"></script>
<link href="static/css/main.073c9b0a.css" rel="stylesheet" />
now it even work on file:///D:/codes/ProjectName/build/index.html
tell me in the comments if none of the 3 ways work, I'll find, try & tell way 4, 5, etc.

Resources