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.
Related
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).
I wrote a custom node for node red and everything is working fine.
Now I need to put everything in a docker container. Node red is running and the dependency is installed, but the nodes do not show up on the interface. I do not get any error messages, even when I not include the files, what causes an error on the standalone version.
My package.json:
{
"name": "boolean_nodes",
"version": "1.0.0",
"description": "Nodes for boolean operation.",
"dependencies": {
"node-red": "*",
"node-red-contrib-home-assistant-websocket": "*",
"mqtt": "*"
},
"scripts": {
"start": "node-red"
},
"author": "",
"license": "ISC",
"node-red": {
"nodes": {
"BOOL-Switch": "./data/bool/switch/bool_switch.js",
"BOOL-AND": "./data/bool/and/bool_and.js",
"BOOL-OR": "./data/bool/or/bool_or.js",
"ML-Interface": "mlinterface.js"
}
}
}
My dockerfile:
FROM nodered/node-red
# Copy package.json to the WORKDIR so npm builds all
# of your added nodes modules for Node-RED
COPY package.json .
RUN npm install --unsafe-perm --no-update-notifier --no-fund --only=production
# Copy _your_ Node-RED project files into place
COPY /data/bool/switch/bool_switch.js /data/bool/switch/bool_switch.js
COPY /data/bool/switch/bool_switch.html /data/bool/switch/bool_switch.html
COPY /data/bool/and/bool_and.js /data/bool/and/bool_and.js
COPY /data/bool/and/bool_and.html /data/bool/and/bool_and.html
COPY /data/bool/or/bool_or.js /data/bool/or/bool_or.js
COPY /data/bool/or/bool_or.html /data/bool/or/bool_or.html
If experimented with diffrent paths for the files but that does not cause any different behavior.
How do I get may plugin in the container?
Normally you'd package your node as an npm module and then npm install it.
In this instance, you can still load what we call 'local' nodes which aren't packaged properly. By default Node-RED will look under the nodes directory of node-red user directory.
In the docker image, /data is used as the user directory.
So you should be copying your files somewhere under /data/nodes/
I have my NodeJS app wrote using TypeScript and based on the Express framework. I want to host it in GCP cloud with gcloud app deploy command.
So, first of all, I build my TS sources to JavaScript -is that the correct way of doing it?.
Then from the build (with JS source code) folder I'm trying to run npm start command and it works successfully and I'm also able to check it with Preview:
.
It works well. So far, so good.
Then I run gcloud app deploy from the build folder (with built to JS sources) and I didn't see any errors during deploy.
But afterward, I receive a 500 error on each request whenever I'm trying to reach the deployed app. I've taken a look into a log and I see next error:
Error: Cannot find module 'express'
What seems to be the problem?
I tried the next commands in the build folder:
npm install
npm install express --save
npm install -g express
sudo apt-get install node-express
Nothing works for me.
Here is my package.json file:
{
"name": "full-node",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "tsc",
"dev": "node -r ts-node/register ./src/server.ts",
"debug": "ts-node --inspect ./src/server.ts",
"start": "node build/server.js",
"prod": "npm run build && npm run start"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"ts-node": "^7.0.1",
"typescript": "^3.0.1"
},
"dependencies": {
"#types/lodash": "^4.14.116",
"body-parser": "^1.18.3",
"connect": "^3.6.6",
"cors": "^2.8.4",
"crypto": "^1.0.1",
"express": "^4.16.3",
"firebase-admin": "^6.0.0",
"lodash": "^4.17.10"
}
}
Any idea what I'm missed? Is this the correct way to deploy an app wrote with TypeScript to GCP cloud?
app.yaml:
# [START app_yaml]
runtime: nodejs8
# [END app_yaml]
since you are running gcloud app deploy from within the build folder,probably the package.json is not deployed as npm install is run first by app engine there is no way express could be missing.you can go to gcp console and under app engine view the version and then under diagnose you can view the source(the files that were actually deployed to app engine).keep in mind that this is only possible for the standard version and not the flex.I can see from your app.yaml you are using the standard.If some files are missing then go to your app root directory and in your .gcloudignore file you can ignore the files/folders you do not want to deploy.then run gcloud app deploy from within the root directory of your project
The problem was pretty simple. Seems like gcloud app deploy use npm run build & npm run start commands to start application somewhere inside. To host Node.Js wrote on TS first we need to build it to simple JS using tsc command. Then in the build folder rewrite package.json file to use correct commands. Look at my start command: "start": "node build/server.js". I was using it inside build folder as well so that's mean gcloud command was searching in /build/build/ folder. I've changed start command to "start": "node server.js" and then all works well.
I looked at the following question before asking this one but I believe mine is different because I am not using Docker: Nextjs fails to find valid build in the '.next' directory in production node_env
I also tried this approach of removing the '.next' folder but still get the same issue.
After fixing a host of other issues, I am down to one I cannot seem to resolve. When I try to deploy to Heroku I keep getting the following error:
node server.js
Could not find a valid build in the '.next' directory! Try building your app with 'next build' before starting the server.
Here is my package.json file:
{
"name": "StarterApp",
"version": "1.0.0",
"engines": {
"node": "10.4.1"
},
"description": "",
"main": "index.js",
"scripts": {
"test": "mocha",
"dev": "node server.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"express": "4.16.3",
"fs-extra": "^5.0.0",
"ganache-cli": "^6.1.3",
"mocha": "^5.2.0",
"next": "^4.2.3",
"next-routes": "^1.4.2",
"node-gyp": "^3.7.0",
"react": "^16.4.1",
"react-dom": "^16.4.1",
"rebuild": "^0.1.2",
"semantic-ui-css": "^2.3.2",
"semantic-ui-react": "^0.79.1",
"sha3": "^1.2.2",
"solc": "^0.4.24",
"truffle-hdwallet-provider": "0.0.3",
"web3": "^1.0.0-beta.34"
}
}
Server.js file:
const { createServer } = require('http');
const next = require('next');
const app = next({
dev: process.env.NODE_ENV !== 'production'
});
const routes = require('./routes');
const handler = routes.getRequestHandler(app);
app.prepare().then(() => {
createServer(handler).listen(5000, (err) => {
if (err) throw err;
console.log('Ready on localhost:5000');
});
});
The app deploys without issue locally but I get this error when deploying to Heroku. What am I doing wrong?
npm run build
then
npm run start
solved my problem.
First
npm run-script build
Then
npm run start
Just see the error carefully:
Error: Could not find a production build in the 'E:\Developer's Area\weatherteller\.next' directory. Try building your app with 'next build' before s at Server.readBuildId (E:\Developer's Area\weatherteller\node_modules\next\dist\next-server\server\next-server.js:146:355)
at new Server (E:\Developer's Area\weatherteller\node_modules\next\dist\next-server\server\next-server.js:3:120)
at createServer (E:\Developer's Area\weatherteller\node_modules\next\dist\server\next.js:2:638)
at start (E:\Developer's Area\weatherteller\node_modules\next\dist\server\lib\start-server.js:1:323)
at nextStart (E:\Developer's Area\weatherteller\node_modules\next\dist\cli\next-start.js:19:125)
at E:\Developer's Area\weatherteller\node_modules\next\dist\bin\next:27:115
while running
npm start
It's not able to locate the production build which is required to launch the next app. While creating next app using
npm install next react react-dom --save
.next folder was not created so you need to create the .next folder first using
npm build
which will consist of all your production build files.
After npm build the folder will be created and you can run your app using
npm start
Also, make sure these scripts are in your next app
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
Hope this resolves your error 😀😀
I had the same issue once.
First, remove package-lock.json or yarn.lock files and node_modules folder and make sure you install all the packages again with the yarn command.
I had to run yarn build first and then the yarn start command was working fine afterward.
Also if the currently used port is taken by another app you will have issues running your dev environment. You can easily fix that by going into the package.json file and modifying the "dev" script like this: "dev": PORT=7080 next dev".
Also possibly you are mixing Next.js with React because in Next.js you should use yarn dev to start your project for development instead of yarn start.
I hope this was helpful to you.
NextJS building may be (depending on your project size), be extremely large, something that can cost you money during deploys.
You can apply the following to your package.json
{
"script": {
"build": "next build",
"heroku-postbuild": "npm run build",
"start": "next start"
}
}
I was getting this error when trying to start a production server from the build directory after setting.
distDir: 'build',
actual error
Error: Could not find a production build in the '/home/username/awesome-app/build/build' directory. Try building your app with 'next build' before starting the production server. https://nextjs.org/docs/messages/production-start-no-build-id
and my start command
$ next start build
so I moved the next build directory to another directory named build and it works, and if you are using environment variable put that file inside the build directory.
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.