I have the below Dockerfile:
# Use NodeJS base image
FROM node:12
# Create app directory
#RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install app dependencies
# A wildcard is used to ensure both package.json AND package-lock.json are copied
# where available (npm#5+)
COPY package*.json /usr/src/app/
COPY src/. /usr/src/app # this is to copy contents of src/ one level up otherwise they aren't recognised
RUN npm install
# Bundle app source
COPY . /usr/src/app/
#RUN rm -f /usr/src/app/src/*
EXPOSE 8080
# Define the Docker image's behavior at runtime
CMD ["node", "server.js"]
But on running the docker image after a successful build, below error appears:
internal/modules/cjs/loader.js:965
throw err;
^
Error: Cannot find module '/usr/src/app/server.js'
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:962:15)
at Function.Module._load (internal/modules/cjs/loader.js:838:27)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:71:12)
at internal/main/run_main_module.js:17:47 {
code: 'MODULE_NOT_FOUND',
requireStack: []
}
Since I have a server.ts file and docker is somehow looking for server.js. On changing the extension, its unable to import other typescript files. Below is my server.ts:
import cors from 'cors';
import express from 'express';
import {sequelize} from './sequelize';
import {IndexRouter} from './controllers/v0/index.router';
import bodyParser from 'body-parser';
import {config} from './config/config';
import {V0_FEED_MODELS} from './controllers/v0/model.index';
(async () => {
await sequelize.addModels(V0_FEED_MODELS);
//await sequelize.addModels(V0_USER_MODELS);
await sequelize.sync();
const app = express();
const port = process.env.PORT || 8080;
app.use(bodyParser.json());
app.use(cors({
allowedHeaders: [
'Origin', 'X-Requested-With',
'Content-Type', 'Accept',
'X-Access-Token', 'Authorization',
],
methods: 'GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE',
origin: config.url,
}));
app.use('/api/v0/', IndexRouter);
// Root URI call
app.get( '/', async ( req, res ) => {
res.send( '/api/v0/' );
} );
// Start the Server
app.listen( port, () => {
console.log( `server running ${config.url}` );
console.log( `press CTRL+C to stop server` );
} );
})();
Why is docker picking up server.js automatically? where can I configure the docker to do otherwise?
FROM node:12
WORKDIR /usr/src/app
COPY . .
RUN npm install
EXPOSE 8080
CMD ["node", "server.js"]
I think this is what you are trying to do. It should work fine. If you're trying to do anything else please let me know.
Related
I'm trying to use the execFile command from child_process to run an executable. In my local computer/environment, everything works flawlessly, but when I try to run the app through the packaged .exe file generated by pkg, I get an ENOENT error:
Therefore I checked the command with fs.exists(), but it returns true. So I'm unsure how to fix this, since I'm wondering if its my build configuration, or a compatibility error/issue with how pkg's snapshot system works. Any help, workarounds, etc, would be appreciated :) !
index.js
const { execFile } = require("child_process");
const fs = require("fs");
const execDirectory = path.join(__dirname, "./executables");
const determineActiveWindows = async (appDataDirectory) => {
const command = `${execDirectory}\\determineActiveWindows.exe`;
console.log("file exists", fs.existsSync(command));
console.log("command", command);
execFile(
command,
["--appDataDirectory", appDataDirectory],
(err, stdout, sterr) => {
if (err) console.error(err);
if (stdout) console.log(stdout);
if (sterr) console.error(sterr);
}
);
};
Error in command line:
file exists true
command C:\snapshot\MinimizeWindows\build\app\executables\determineActiveWindows.exe
Error: spawn C:\snapshot\MinimizeWindows\build\app\executables\determineActiveWindows.exe ENOENT
at Process.ChildProcess._handle.onexit (node:internal/child_process:283:19)
at onErrorNT (node:internal/child_process:478:16)
at processTicksAndRejections (node:internal/process/task_queues:83:21)
at process.runNextTicks [as _tickCallback] (node:internal/process/task_queues:65:3)
at Function.runMain (pkg/prelude/bootstrap.js:1984:13)
at node:internal/main/run_main_module:17:47 {
errno: -4058,
code: 'ENOENT',
syscall: 'spawn C:\\snapshot\\MinimizeWindows\\build\\app\\executables\\determineActiveWindows.exe',
path: 'C:\\snapshot\\MinimizeWindows\\build\\app\\executables\\determineActiveWindows.exe',
spawnargs: [
'--appDataDirectory',
'appName'
],
cmd: 'C:\\snapshot\\MinimizeWindows\\build\\app\\executables\\determineActiveWindows.exe --appDataDirectory appName'
}
build directory structure
-build
---app
------executables
---------determineActiveWindows.exe
------index.js
pkg command
pkg -c package.json build/app/index.js
package.json pkg config
"pkg": {
"targets": ["node16-win-x64"],
"scripts": "build/**/*.js",
"assets": "build/**/*",
"outputPath": "dist"
}
Don't use path.join when you need to reference an external file that is not packaged into the exe at build time, pkg is overriding it.
From error we see: C:\\snapshot
'C:\\snapshot\\MinimizeWindows\\build\\app\\executables\\determineActiveWindows.exe --appDataDirectory appName'
I have a monorepo with the following folder structure.
packages/
- server
- src
- index.js
- build
- lib1
- lib2
My node server uses express and graphql, with a very simple setup.
index.js
const start = async () => {
const server = new ApolloServer({
schema: clientSchema,
tracing: true,
introspection: process.env.NODE_ENV !== "production",
});
await server.start()
const app = express();
app.use(express.json({limit: '10mb'}));
app.use(express.urlencoded({limit: '10mb', extended: true}));
server.applyMiddleware({ app });
app.listen({ port }, () =>
console.log(`🚀 Server ready at http://localhost:${port}${server.graphqlPath}`)
);
}
I am using babel to transpile the node server using a .babelrc file with the following config
{
"presets": ["#babel/preset-env"],
"plugins": ["#babel/plugin-transform-runtime"]
}
lib1 and lib2 are packages using import and export syntax.
When I build the node server using something like babel -d ./build ./src and then start the server using node ./build/index.js
I am presented with the error SyntaxError: Cannot use import statement outside a module for one of the files in package/lib1.
Now I have gotten this to work by changing index.js in the server package to be like the example below however im finding the server uses a lot of memory and takes a long time when initially starting up which makes my Heroku server cost really expensive as it will crash due to memory quotas going past 1GB.
require('#babel/register')({
presets: ['#babel/preset-env'],
ignore: ['node_modules'],
plugins: [
"#babel/plugin-transform-runtime"
]
});
// Import the rest of our application.
module.exports = require('./server.js');
I try to run the following script:
In terminal I have written: node server, but I got an error message:
Error: Cannot find module 'express'
at Function.Module._resolveFilename (module.js:555:15)
at Function.Module._load (module.js:482:25)
at Module.require (module.js:604:17)
at require (internal/module.js:11:18)
at Object. (/home/jwisniowski/Desktop/PROJEKTY/UJ_API_PEP/shop-app/server.js:1:79)
at Module._compile (module.js:660:30)
at Object.Module._extensions..js (module.js:671:10)
at Module.load (module.js:573:32)
at tryModuleLoad (module.js:513:12)
at Function.Module._load (module.js:505:3)
sever.js
const express = require('express')
const app = express()
const port = process.env.PORT || 3000
const fs = require('fs')
const api_endpoint = process.env.API_ENDPOINT || "http://localhost:8081/application-orchestration/v1"
fs.writeFileSync(
__dirname + '/application-web/config/env.js',
'var api_endpoint = "' + api_endpoint + '";'
);
app.use(express.static('./'))
app.get('/', (request, response) => {
response.send('Hello from Express!')
})
app.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`server is listening on ${port}`)
})
make sure you have express in your package.json and do npm install.
or
npm install express -s
delete your node_modules folder, make sure that you have express in your package.json, and do npm install.
You might have to install express globally ,
npm install -g express --save
OR
Install express locally to your project
npm install express --save
I have a current app that I'm updating to use the Express Node.js library. I have updated the Grunt.js tasks to use the grunt-express-server package. Part of my code is trying access the contents of a JSON file (see directory structure below). It runs the server just fine, but when I try to access any static file I get the following error:
Error: ENOENT: no such file or directory, open 'static/test.json'
at Error (native)
at Object.fs.openSync (fs.js:549:18)
at Object.fs.readFileSync (fs.js:397:15)
at /Users/owen/src/projects/node-express-cannot-get/build/index.js:13:32
at Layer.handle [as handle_request] (/Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/layer.js:95:5)
at next (/Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/route.js:131:13)
at Route.dispatch (/Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/route.js:112:3)
at Layer.handle [as handle_request] (/Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/layer.js:95:5)
at /Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/index.js:277:22
at Function.process_params (/Users/owen/src/projects/node-express-cannot-get/node_modules/express/lib/router/index.js:330:12)
I think this may have something to do with my directory structure and where the Express server is being run from. My Grunt tasks copy all my source files from a folder called src (which contains my index.js) to a folder called build and then runs the server from the Gruntfile which is in the root directory. If I cd into the build folder and run index.js directly (node index.js), the error goes away. However, running it via the Grunt task produces the error.
How can I fix this issue without changing my directory structure? Is there a way to make the Grunt Express Server task change where it's being run from? Or is there another cause to this issue?
Please see my directory sturcture and code samples below:
Directory structure (after Grunt tasks have completed)
/
build/
static/
test.json
index.js
node_modules/
src/
static/
test.json
index.js
Gruntfile.js
package.json
Gruntfile.js
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
grunt.config.merge({
clean: {
dev: ['build']
},
mkdir: {
build: {
options: {
mode: 0755,
create: ['build']
}
}
},
copy: {
dev: {
files: [{
expand: true,
cwd: 'src',
src: ['index.js', 'static/**/*'],
dest: 'build'
}]
}
},
express: {
dev: {
options: {
'script': 'build/index.js',
'port': 2000
}
}
},
watch: {
index: {
files: ['index.js'],
tasks: ['clean', 'mkdir', 'copy']
}
}
});
grunt.registerTask('default', [
'clean:dev',
'mkdir:build',
'copy:dev',
'express:dev',
'watch:index'
]);
};
src/index.js
var express = require('express');
var path = require('path');
var fs = require('fs');
var app = express();
app.set('port', (process.env.PORT || 2000));
app.use('/', express.static(path.join(__dirname, '/')));
app.get('/', function (req, res) {
configurationPath = 'static/test.json';
// I beleive this is where the problem happens...
var configurationJSON = fs.readFileSync([configurationPath].join("")).toString();
console.log('configurationJSON', configurationJSON);
res.send('Hello world');
});
app.listen(app.get('port'), function () {
console.log('It\'s all go on port: ' + app.get('port') );
});
The call to readFileSync in index.js is failing because it's passed a relative path - 'static/test.json' - and the current directory is not what you think it is.
The current directory is the directory with the package.json in it - not the build directory.
If you use __dirname - as you've done with the static middleware - it should solve your problem:
var configurationPath = path.join(__dirname, 'static/test.json');
I'm trying to incorporate es6 in my server side code. Using babel-node works when running the server , however i'm having trouble compiling es6 to es5 code when running mocha tests.
This is my folder structure
I have a server.js which starts up a worker.js file(which has the express server)
the server.js file
import {SocketCluster} from 'socketcluster';
const socketCluster = new SocketCluster({
workers:1,
brokers:1,
port: 3000,
appName:null,
workerController: __dirname + '/worker.js',
brokerController: __dirname + '/broker.js',
socketChannelLimit: 1000,
crashWorkerOnError: true
})
the worker.js file
export const run = (worker) => {
console.log(' >> worker PID: ',process.pid);
const app = express();
const httpServer = worker.httpServer;
const scServer = worker.scServer;
app.use(cookieParser())
httpServer.on('request', app);
app.get('/',(req,res) => {
console.log('recieved')
res.send('Hello world')
})
}
When running the server manually , it works with the below script
"start": "nodemon server/server.js --exec babel-node"
however , when i try running the test file with mocha i get an 'unexpected token "export" error'
(function (exports, require, module, __filename, __dirname) { export const run = (broker) => {
^^^^^^
SyntaxError: Unexpected token export
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:511:25)
at Object.Module._extensions..js (module.js:550:10)
at Module.load (module.js:456:32)
at tryModuleLoad (module.js:415:12)
at Function.Module._load (module.js:407:3)
at Module.require (module.js:466:17)
at require (internal/module.js:20:19)
at initBrokerServer (/home/avernus/Desktop/projects/node-sc-react/node_modules/sc-broker/server.js:178:25)
at process.<anonymous> (/home/avernus/Desktop/projects/node-sc-react/node_modules/sc-broker/server.js:498:9)
this is the script to start the mocha tests
"test": "mocha test/server/*.js --compilers js:babel-register"
am i missing something else?
this is the test file
import server from '../../server/server';
import http from 'http';
import assert from 'assert';
import {expect} from 'chai';
describe('Express server',() =>{
it('should return "Hello World"',() => {
http.get('http://127.0.0.1:3000',(res) => {
expect(res).to.contain('wtf world')
})
})
})
You need to transpile test scripts from ES2015 to ES5 using Babel before passing it to mocha to run the tests. You can do it as follows adding/editing test script in package.json
...
"scripts": {
"test": "mocha --compilers js:babel-core/register --recursive"
},
...
Update:
Mocha deprecated the --compiler flag. Please check this page for more information. The new npm script should look like below
...
"scripts": {
"test": "mocha --require babel-register --recursive"
},
...
Turns out i need to specify an initController in my server.js file to ensure that all files are compiled by babel. This is a problem specific to the websocket framework i'm using.