Service not found after install service node-windows - node.js

My install service script as below:
install_windows_service.js
require("dotenv").config();
var Service = require("node-windows").Service;
// Create a new service object
var svc = new Service({
name: "STUtility",
description: "The web app with STUtility tools.",
script: process.env.WORKING_DIRECTORY + "index.js",
nodeOptions: ["--harmony", "--max_old_space_size=4096"],
workingDirectory: process.env.WORKING_DIRECTORY,
allowServiceLogon: true,
env: {
name: "NODE_ENV",
value: "production",
},
});
// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on("install", function () {
svc.start();
console.log("install complete.");
console.log("The service exists: ", svc.exists);
});
// Just in case this file is run twice.
svc.on("alreadyinstalled", function () {
console.log("This service is already installed.");
});
// Listen for the "start" event and let us know when the
// process has actually started working.
svc.on("start", function () {
console.log(svc.name + " started!.");
});
svc.on("error", function () {
console.log("Something went wrong.");
});
svc.on("invalidinstallation ", function () {
console.log(" This service is detected but missing require files");
});
svc.install();
In terminal I run command:
node .\install_windows_service.js
Terminal show:
install complete. The service exists: true
But I cannot find out this service on Windows Services.

Related

Telegram bot doesn't run on heroku

Problem
My problem is that when trying to deploy bot on heroku I get r10 error boot timeout, but it works when running locally and I cant seem to find the fix for it
heroku logs
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 90 seconds of launch
Stopping process with SIGKILL
Process exited with status 137
State changed from starting to crashed
My code
process.env.NTBA_FIX_319 = 1
const TelegramBot = require('node-telegram-bot-api')
require('dotenv').config()
const token = process.env.TOKEN
const myInfo = process.env.INFO
const error = process.env.ERROR
const git = process.env.GIT
const bot = new TelegramBot(token, { polling: true })
bot.on('message', (msg) => {
const chatId = msg.chat.id
const name = msg.chat.first_name
const { text } = msg
if (text === '/start' || text === '/help') {
bot.sendMessage(chatId, `Hi ${name}! These are the commands below:`, {
reply_markup: {
keyboard: [
[
{ text: '/start' },
{ text: '/about' },
{ text: '/links' },
{ text: '/help' },
],
],
resize_keyboard: true,
one_time_keyboard: true,
},
})
} else if (text === '/about') {
bot.sendMessage(chatId, `${myInfo}`)
} else if (text === '/links') {
bot.sendMessage(chatId, `${git}`)
} else {
bot.sendMessage(chatId, `${error}`)
}
})
Dockerfile
FROM node:16.13.2-alpine
WORKDIR /Bot1
ENV PORT 88
COPY package.json /Bot1/package.json
RUN npm install
COPY . .
CMD ["node", "app.js"]
comands to deploy bot
heroku container:push web
heroku container:release web
You have deployed your code as a web process. web processes listen for HTTP requests and must bind to a port provided at runtime shortly after starting up.
Since your bot does not respond to HTTP requests it should not be deployed as a web process. A common name for such processes is worker.
First, remove the web container you have already deployed:
heroku container:rm web
Now, redeploy your code as a worker process:
heroku container:push worker
heroku container:release worker
You may need to scale your dynos after doing this. Something like
heroku ps:scale worker=1
should do the trick.

Start nestjs project as a Windows service

We used to start Angular and NestJS (based on node.js) projects using Docker containers. This solution was discontinued for various reasons, so we are looking for a way to start these projects at the start of the PC (or on a trigger) and restart the project automatically if a crash occurs.
node-windows
This package builds a Windows service from a node.js project. NestJS being based on node.js, starting it using node.js is done this way (while in the project's folder):
node PATH_TO_PROJECT\node_modules\#nestjs\cli\bin\nest.js start --config .\tsconfig.build.json
The script used:
const svc = new Service({
name: 'Test',
description: 'Test',
script:
'PATH_TO_PROJECT\\node_modules\\#nestjs\\cli\\bin\\nest.js',
scriptOptions: [
'start --watch --config PATH_TO_PROJECT\\tsconfig.build.json',
],
],
execPath: 'C:\\Program Files\\nodejs\\node.exe',
});
svc.on('install', function () {
console.log('installed');
svc.start();
});
svc.install();
The installation works as intended but in a browser, the server cannot be reached.
Questions
Is there a way to use node-windows for a NestJS project?
Is it possible to use an absolute path with the nest cli start command? (e.g nest start --config ABSOLUTE_PATH)
How would you start an Angular project the same way?
Thank you.
am use 'child_process' lib for run command
like this
server.js
const { exec } = require("child_process");
exec("npm run start", (error, stdout, stderr) => {
if (error) {
console.log(`error: ${error.message}`);
return;
}
if (stderr) {
console.log(`stderr: ${stderr}`);
return;
}
console.log(`stdout: ${stdout}`);
});
and use node-windows like this
var Service = require('node-windows').Service;
var serviceDetail = require('./servicename')();
console.log(serviceDetail);
// Create a new service object
var svc = new Service({
name: serviceDetail.name,
description: serviceDetail.detail,
script: './server.js'
});
console.log('start building up service name ' + serviceDetail.name);
// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
svc.start();
});
svc.install();

node-windows impersonate password issue

I'm running a file watcher app as a windows service (W10) with the following code used to install the service:
var Service = require('node-windows').Service;
const config = require('./SHR_modules/config');
// Create a new service object
var svc = new Service({
name:'SmartHR',
description: 'Smart HR file watcher',
script: require('path').join(__dirname,'watcher.js'),
workingDirectory: __dirname
});
// Listen for the "install" event, which indicates the
// process is available as a service.
svc.on('install',function(){
svc.start();
console.log('installed as user: ' + svc.logOnAs.account)
});
svc.on('uninstall',function(){
console.log('Uninstall complete.');
console.log('The service exists: ',svc.exists);
});
svc.logOnAs.domain = config.sqlServerLogin.domain;
svc.logOnAs.account = config.sqlServerLogin.user;
svc.logOnAs.password = config.sqlServerLogin.password;
svc.install();
//svc.uninstall();
Running the code as an administrator and the service does install properly, but it's stopped, so when I try to start it, the message is that the service can't start for the wrong password. Username and domain are correct. If I copy/paste the password into the Services Manager from my config.js, the service starts up and runs from now on.
Why the password (whatever it is) is not passed by that line:
svc.logOnAs.password = config.sqlServerLogin.password;
correctly?
The XML generator function in the winsw.js is missing one line for the service account.
Original code:
if (config.logOnAs) {
xml.push({
serviceaccount: [
{domain: config.logOnAs.domain || 'NT AUTHORITY'},
{user: config.logOnAs.account || 'LocalSystem'},
{password: config.logOnAs.password || ''},
]
});
}
Working code:
if (config.logOnAs) {
xml.push({
serviceaccount: [
{domain: config.logOnAs.domain || 'NT AUTHORITY'},
{user: config.logOnAs.account || 'LocalSystem'},
{password: config.logOnAs.password || ''},
{allowservicelogon: 'true'}
]
});
}
I'll commit that change to the projects git.

Restarting nodejs server on crashing in an electronjs app

I am building an electron app and using nodejs as the backend server within the app.
How can I auto-restart the nodejs server if it encounters a crash?
I am currently using pm2 and using the following code in electron's main.js file
var pm2 = require("pm2");
pm2.connect(function(err) {
if (err) {
console.error(err);
process.exit(2);
}
pm2.start(
{
name: "mydesktopapp",
script: "./server/server.js", // nodejs Script to be run
exec_mode: "cluster",
instances: 1,
max_memory_restart: "5000M", // Optional: Restarts your app if it reaches 5GB
noDaemonMode: true,
watch: true
},
function(err, apps) {
pm2.disconnect(); // Disconnects from PM2
console.error(`Unable to start PM2: ${err}`);
if (err) throw err;
}
);
});
But this does not seem to work, as its throwing the following error:
Unable to start PM2: null
How do you guys handle this?
Thanks

Integration tests sporadically timeout on Heroku hobby-dev

Since we do not get any helpful support from help.heroku.com we make the last try here.
We are developping a classic web app consisting of:
----- ----- ----
|WEB| <----> |API| <----> |DB|
----- ----- ----
We currently are working with the following Heroku Dynos/Datastores
Heroku Postgres: Hobby Basic
Heroku API Dyno: Hobby
Heroku WEB Dyno: Hobby
The tech stack is:
runtime: nodejs (4.4.0)
db: postgres (9.6.1)
testframework: jasminejs (2.5.1)
query builder: knexjs (0.10.0)
We recently moved to from self hosted docker environment to Heroku and configured the Herokus CI pipeline which works fine for unit testing - but not integration testing.
The tests sporadically fails with timeouts (in average every 3rd test of the same commit). This is not stable enough to build up CI/CD.
Here the error messages we get:
**************************************************
* Failures *
**************************************************
1) integration test collections repository create() should return AUTHENTICATION_REQUIRED if user is anonymous
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
2) integration test collections repository create() should return AUTHORIZATION_REQUIRED if user is not space MEMBER
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
3) integration test collections repository create() should return collection if user is space MEMBER
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
- Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
For testing purposes we configured knex connection pooling to use one connection only:
export default {
client: 'pg',
connection: DB_URL,
pool: {
max: 1,
min: 1
}
};
The typical integration test setup is:
describe('integration test', () => {
describe('collections repository create()', () => {
//////////////////////////////////////////////////////////////////////
//Before the test block is execute all fixtures are loaded into the DB
//////////////////////////////////////////////////////////////////////
beforeAll((callback) => {
seed(path.join(__dirname, 'fixtures'))
.then(callback)
.catch((error) => {
fail(error);
callback();
});
});
////////////////////////////////////////////////////////////////////////
//Truncate all data from the DB before the next test block gets executed
////////////////////////////////////////////////////////////////////////
afterAll(resetDB);
it('should return AUTHENTICATION_REQUIRED if user is anonymous', (callback) => {
testUtils.testAsync({
callback,
catchTest: (error) => {
expect(error).toEqual(jasmine.any(repositoryErrors.AUTHENTICATION_REQUIRED));
},
runAsync: create({ props: { space: { id: 1 } } })
});
});
it('should return AUTHORIZATION_REQUIRED if user is not space MEMBER', (callback) => {
testUtils.testAsync({
callback,
catchTest: (error) => {
expect(error).toEqual(jasmine.any(repositoryErrors.AUTHORIZATION_REQUIRED));
},
runAsync: create({ props: { space: { id: 1 } }, userId: 1 })
});
});
it('should return collection if user is space MEMBER', (callback) => {
testUtils.testAsync({
callback,
runAsync: create({ props: { space: { id: 1 } }, userId: 2 }),
thenTest: (outcome) => {
expect(outcome).toEqual({ id: '1' });
}
});
});
...
seed:
const tableOrder = [
'users',
'guidelines',
'collections',
'spaces',
'details',
'files',
'guidelinesAuthors',
'collectionsUsers',
'spacesUsers',
'guidelinesCollections',
'spacesCollections',
'guidelinesDetails',
'guidelinesFiles',
'comments',
'commentsReplies',
'notifications'
];
export default function seed(path) {
return db.raw('BEGIN;')
.then(() => {
return tableOrder.reduce((promise, table) => {
return promise
.then(() => slurp({ path, table }))
.then(() => {
updateIdSequence(table)
.catch((error) => {
// eslint-disable-next-line no-console
console.log(
`Updating id sequence for table '${table}' failed! Error: `,
error.message
);
});
});
}, Promise.resolve()).then(() => db.raw('COMMIT;'));
})
.catch((error) => {
// eslint-disable-next-line no-console
console.log('SEED DATA FAILED', error);
return db.raw('ROLLBACK;');
});
}
...
resetDB:
export default function resetDB(callback) {
const sql = 'BEGIN; '
+ 'SELECT truncateAllData(); '
+ 'SELECT restartSequences(); '
+ 'COMMIT;';
return db.raw(sql)
.then(callback)
.catch((error) => {
// eslint-disable-next-line no-console
console.log('TRUNCATE TABLES FAILED', error);
return db.raw('ROLLBACK;');
});
}
Until now, these test have been running on local machines (Linux/Mac) and Codeship without any problem.
After almost two weeks of trying to get this work we made zero progress on this issue. I can't see anything wrong with this configuration and I start to belive Heroku has a serious issue with the datastores...
Has anybody experienced similar issues on Heroku?
Any idea what we can try else to get this work?

Resources