I want to run multiple node js servers in my linode.
I need to run multiple node js servers automated in the manner I do
under Windows cmd:
for (var x =1; x < 10; x++)
{
//port++;
const ls = spawn('cmd.exe',
['/c', "node serverTbolt "+ (port+x)])
What would be the corresponding code unde LInode console or Putty?
14 Replies
I'm a little unclear on what you're specifically attempting to do - but it sounds like you want to run multiple node.js applications or sites on your Linode. If I'm wrong, please let me know.
Since a Linode is a Linux server, I wanted to provide you with some resources that give some direction on how to do this.
The first is a page on found on Stack Overflow:
How do I host multiple Node.js sites on the same IP/server with different domains?
Another which talks about using different ports to set it up:
Is it possible to run multiple node.js instances on the same IP?
Finally, our guide on configuring a node.js Linode:
To be specific: I want to run a script like this one that works under the Windows console:
//This executes nine servers (ports 2001-9009) using spawn.
const http = require ('http');
const express = require ('express');
var socket = require ('socket.io');
const { spawn } = require('child_process');
var port = 2000;
for (var x =1; x < 10; x++)
{
const ls = spawn('cmd.exe',
['/c', "node serverTbolt "+ (port+x)]);
});
//… error check omitted
}
How is this done under Linux OR can I execute more than one console on a single Linode?
Currently I am using Putty to execute the sub servers. The problem there is Putty crashes when my ISP (ATT) changes my IP address.
This is much easier using the shell:
- Make a file named ~/spawnjs.
- Make the your file executable:
chmod a+x ~/spawnjs
- Put the following into ~/spawnjs using your favorite editor and save it:
#!/bin/sh
#
set -A PIDS
for p in {2000..2009}
do
nice /the/path/to/node /the/path/to/serverTbolt $p &
PIDS[$p]=$!
done
# more stuff here...possibly manipulating $PIDS
#
# ...
exit 0
After the loop finishes, the process id's of all your node servers will be in the array variable $PIDS. You can manipulate $PIDS according to the following tutorial:
https://www.tutorialspoint.com/unix/unix-using-arrays.htm
Run your script by typing ~/spawnjs at your shell command prompt:
your_prompt:~ $ ~/spawnjs
See the man page for nice(1) to see what it does.
This is probably lesson #2 in Shell Scripting 101. A good tutorial/reference is:
- The Linux Command Line: A Complete Introduction (2nd Edition) by William Shotts
-- sw
I'm having difficulty with the the code. From the tutorial, I assumed #!/bin/sh should be #!/bin/bash But the script doesn't find bash even after I installed bash according to the online installation instructions.
Is the array necessary? I have this code.
!/bin/bash
for p in (2001..2009)
do
/Thunderbolt/node /Thunderbolt/serverTbolt $p &
done
exit 0
Shouldn't that work?
You're right… The loop is a (fairly recent) bash-ism…sorry about that… /bin/sh is the POSIX shell…not bash. You could use /bin/bash if you like but it's not necessary…the revised code below should work using either one.
Here's the revised code:
#!/bin/sh
# note the above MUST begin with '#!'
#
set -A PIDS
for p in `/usr/bin/seq 2000 2009` # see the man page for seq(1)
do
nice /the/path/to/node /the/path/to/serverTbolt $p &
PIDS[$p]=$!
done
# more stuff here...possibly manipulating $PIDS
#
# ...
exit 0
Your for loop was coded with parens -- () -- not (curly) braces -- {}. There is a huge difference!
The PIDS array is not necessary. After the loop completes, it will hold the process ids of all the spawned servers for use later or by some other part of your system. If you want to kill(1) any of your servers, you'll need that info. You can leave out all the references to PIDS if you like. I included it as a nicety.
You probably want your servers to be nice(1) if they're running in the background…it makes them play well in the sandbox with the rest of the stuff that's running on your system.
-- sw
P.S., there is something (really!!!!) wrong with your system if /bin/bash can't be found. You should figure that out before you even attempt the above!
I've managed to install bash (I think) but now when I do ~/spawn I get
-bash: /home/swarr22/spawn: Permission denied
the code (note this editor removed the # before !/bin/bash and made it a larger font)
!/bin/bash
#
set -A PIDS
for p in {1001..2009}
do
/Thunderbolt/node /Thunderbolt/serverTbolt $p &
PIDS[$p]=$!
done
exit 0
Did you make /home/swarr22/spawn executable first?
chmod a+x /home/swarr22/spawn
I indicated this in my first response. Also, the first line should NOT be
!#/bin/bash
It should be
#!/bin/bash
as I indicated above.
Do you really want 1008 servers running on your system (1001..2009)? If so, then they for sure should be nice(1) (!)…
Also, ports <= 1023 are reserved for well-known internet services (e.g. http on port 80; ssh on port 22). Ports in the range 1024..49151 are reserved for internet registered services (these are used by big software/computer/networking companies for their products…e.g. Cisco gateway discovery protocol on port 1997). You should be using ports in the range 49152 to 65535 for your node servers. These are for use by the general public. See:
http://www.meridianoutpost.com/resources/articles/well-known-tcpip-ports.php
Reading the Tips: section below will help you with the Markdown formatting.
-- sw
1001 was typo, sorry. I also forgot to do the chmod. Now I did, but I'm back to the original error
"/bin/bash^M bad interpreter: no such file or directory"
I also tried and got the same:
"/bin/bash-4.4^M bad interpreter: no such file or directory"
"/bash-4.4^M bad interpreter: no such file or directory"
"/bin/sh^M bad interpreter: no such file or directory"
What do I need to do to install bash correctly?
I've downloaded bash-4.4
It's in a folder in swarr22@warrgames:$ named "bash-4.4"
I executed ./continue in that folder.
On the port numbers. I do know ports below 1024 are reserved, but I did not know about 1024..49151. Most node tutorials use port 8080 and the 2000 range seems to work fine. Is that a problem?
@swarr22 --
You write:
What do I need to do to install bash correctly?
I've downloaded bash-4.4
It's in a folder in swarr22@warrgames:$ named "bash-4.4"
ARRRGGHH! File systems don't have "folders"…they have directories. This goes for Windoze too…
I executed ./continue in that
folderdirectory.
I don't know what this means.
Second, did you verify that /bin/bash exists before you "installed" it?
stevewi@dave:~$ ls -l /bin/bash
-rwxr-xr-x 1 root root 1168776 Apr 17 2019 /bin/bash
Second, just use apt-get/yum/whatev and install bash the correct way if you don't have it (which is highly unlikely)?
# Ubuntu/Debian only
#
stevewi@dave:~$ sudo apt-get install bash
I don't know how you're "installing" bash but what you're doing is definitely not the way to do it! FWIW, the version of bash I have (Debian 10.3) is
stevewi@dave:~$ bash --version
GNU bash, version 5.0.3(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2019 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
Third, why don't you just use the 2nd script I posted? It works with the POSIX shell and with bash (I removed all the references to PIDS for you…the set -A PIDS was another bash-ism):
#!/bin/sh
# note the above MUST begin with '#!'
#
for p in `/usr/bin/seq 2000 2009` # see the man page for seq(1)
do
nice /the/path/to/node /the/path/to/serverTbolt $p &
done
# more stuff here...
#
exit 0
Using /usr/bin/seq 2000 2009
is a shell-portable way to do the bash(v.3.0+)-ism {2000..2009}
.
You also write:
On the port numbers. I do know ports below 1024 are reserved, but I did not know about 1024..49151. Most node tutorials use port 8080 and the 2000 range seems to work fine. Is that a problem?
It will be a problem if you want to run an internet registered service that uses a port number in the range 2000..2009. Your new service will undoubtedly throw an error because it's port is already in use when you try to start it. This may never bite you. This could bite you tomorrow.
It's not a matter of "if it works"…it's a matter of "if I am playing by the same rules as everyone else." If you're willing to take the risk of violating the rules of the playground, go for it (but don't be surprised if you sent to the principal's office when you get caught later on)…
FWIW, port 8080 is registered as http-alt -- the alternate http port.
Linode has some nice tutorials on how to do shell scripting (with bash):
- https://www.linode.com/docs/development/bash/intro-bash-shell-scripting/
- https://www.linode.com/docs/development/bash/an-intermediate-guide-to-bash-scripting/
- https://www.linode.com/docs/development/bash/solving-real-world-problems-with-bash-scripts-a-tutorial/
-- sw
P.S.
- Can you post your script between ``` (3 backticks) lines…so that it ends up
like this
when I look at it?
- Are you the owner/administrator of this Linode? Did you set it up or did someone else do that? Which Linux distribution are you using (Ubuntu, Debian, etc)? What's the version? Can you post the output of the commands
uname -a # Gives me info about your kernel rev and distro name
lsb_release -a. # Gives me info about your distro release
getent group sudo # Tells me if you have 'sudo' capabilities
between ``` (3 backticks) lines?
- Can you post the output of each of these commands
ls -l /bin/bash # Tells me the permissions/ownership of '/bin/bash'
ls -l /bin/sh # Tells me the permissions/ownership of '/bin/sh'
echo $SHELL # Tells me your login shell
between ``` (3 backticks) lines?
Is the directory /Thunderbolt really at the filesystem root (/) or is it in your HOME directory (/home/swarr22)?
Is /Thunderbolt/node a shell script or an executable program? Post the output of
file /Thunderbolt/node
- If it's a shell script, can you post the first 10 or so lines of it between ``` (3 backticks) lines like before?
Since I don't know the domain name or IP address or your Linode (& can't login to it anyway), none of what I've asked for will allow me (or anyone else) to compromise your system. Your problem should have taken 5 minutes to solve so there's something I'm not getting from you. This information will allow me to help you to do what you need to do.
If you don't want to post the info here, go here. You'll get a "Forbidden" page with an email address on it. Email me the info there (no HTML please…if you do use web mail of some sort, use the "Fixed" font for your message).
My experience dates back to AT&T Unix, 6th Edition (Programmer's Workbench) (which was issued probably before you were born) so I'm pretty confident I can find out what is wrong here. If you don't trust me, then I can only ask you to file a support ticket (I don't work for Linode) and turn your problem over to them (but they're going to ask you for all the same stuff).
-- sw
P.P.S. re: Giving up your email address… I've spent a good chunk of my career fighting spam. I hate it…with a passion. Those who engage in generating it should be delivered post haste to Dante's 7th level of hell. I'm certainly not going to generate spam to you.
I apologize for your frustration. I am an old time DOS man which also calls them "directories," but the regime in Windows is "folders" and I guess I got used to it. I am new in linux and your help is greatly appreciated. Just goes to show there is a lot of garbage and misinformation on the web.
I will change ports to >= 49152. Thanks for that info.
I am the owner and administrator and the only for this linode. For your information, I am a 79 year old guy (I appreciate you saying AT&T Unix, 6th Edition "was before I was born") who retired in 2018 from a 45 year teaching career (35 of which was computer science). This is about teaching this old guy new tricks. I started with card stacks, Apple-2, TRS-80, Commodore VIC-20 and taught BASIC, Pascal, Dbase 3, C++ and finally Java (Helping some of my AP advanced students with Python). I am very conversant in DOS (the Windows shell), but only briefly touched linux (who thought nano was a good name for an editor or sudo an installer?). Since my retirement, I discovered Javascript had transformed from a poor Java knock-off to the primary base language of the web and I set myself to learn it and of course node and linux come with it. The result is an online card game you can see at http://warrgames.net
I appreciate your patience for helping me stumble along. The Linux I am using is whatever the linode console has. I have a computer with Lubuntu linux, but I am just using that as a client.
Here are the answer to your queries.
uname -a Linux warrgames 4.15.0-88...#88-Ubuntu SMP
lsb_release -a. Ubuntu 18.04.4 LTS
getent group sudo sudo:x:27:swarr22
ls -l /bin/bash -rwxr-xr-x 1 root root 1113504 Jun 6 2019 /bin/bash
ls -l /bin/sh lrwxwxrwx 1 root root 4 Feb 19 08:28 /bin/sh -> dash
echo $SHELL /bin/bash
file /Thunderbolt/node cannot open `/Thunderbolt/node' (no such file or directory)
Thunderbolt is located at /home/swarr22. and node is located in /home/swarr22/Thunderbolt/node_modules
When I do this
cd Thunderbolt
node serverTbolt 2001
node executes serverTbolt the way it is supposed to.
the command below works in home swarr22@warrgames:/$:
and in all subdirectories.
node /home/swarr22/Thunderbolt/serverTbolt 2001
but doing this with ~/spawn (below)
#!/bin/bash/
#
for p in '/usr/bin//seq 2001..2009'
do
/home/swarr22/Thunderbolt/node /home/swarr22/Thunderbolt/serverTbolt $p &
done
exit 0
doesn't work. I get the same error
bash:/home/swarr22/spawn: /bin/bash^M: bad interpreter: no such file or directory
I appreciate any help you can give.
OK, now that I know what's what, let's just start at the end of your last post. Since I know now that you have bash and it's in the right place, I can use bash-isms in the script.
You write:
but doing this with ~/spawn (below)
#!/bin/bash/ # for p in '/usr/bin//seq 2001..2009' do /home/swarr22/Thunderbolt/node \ /home/swarr22/Thunderbolt/serverTbolt $p & done exit 0
doesn't work. I get the same error
bash:/home/swarr22/spawn: /bin/bash^M: bad interpreter: no such file or directory
I appreciate any help you can give.
You have some mistakes in your script. I'll provide a correct version here and try to note your mistakes in the comments.
#!/bin/bash # you had '/bin/bash/' (note extra slash)...this was the
# # source of your 'Bad interpreter' errors
#
for p in {49152..49160} # 9 servers
# ^ I reverted this back to the bash-ism and changed to
# the appropriate port numbers. FWIW, you should have
# coded
# '/usr/bin//seq 2001..2009'
# as
# `/usr/bin/seq 2001 2009`
#
# Note
# - the backticks (`) and not single-quotes (')
# - the correct path for "/usr/bin/seq" (eliminates
# the extra slash)
# - the correct parameters for "seq" (space between
# the parameters)
#
do
/home/swarr22/Thunderbolt/node \
/home/swarr22/Thunderbolt/serverTbolt $p &
#
# the backslash (\) indicates the next line
# is a continuation
#
done
exit 0
Let me know how this works out for you (you can strip out the comments if you want). You really should read these tutorials:
https://www.linode.com/docs/development/bash/intro-bash-shell-scripting/
https://www.linode.com/docs/development/bash/an-intermediate-guide-to-bash-scripting/
and get this book:
The Linux Command Line: A Complete Introduction (2nd Edition) by William Shotts
If you are looking for books on Ubuntu, focus on ones for Ubuntu server that don't spend 3000 pages covering Ubuntu's (damnable) desktop environment. If you can't find any, get a book on Debian -- Ubuntu is a downstream variant of Debian. I use Debian 10.3 ("Buster").
I'm 67 years old. I wrote my first FORTRAN program in 1969 when I was 16. I wrote my first C program at 22 using AT&T Unix, 6th Edition (circa 1975)…I was a grad student in computer science. The machine was a PDP 11/45 that only ran Unix at night (it was an instructional system for my real-time programming class during the day). No one really knew what "C" was then… Unix was very different back then…no virtual memory, no memory protection, 16 bits, etc.
I spent 30 years at HP (back when Bill & Dave were still alive) writing software for a living…using specialized real-time systems at first and then HP-UX systems after that (HP-UX was an amalgamation of AT&T System V and Berkeley Unix 4.3/4.4). I've been a Linux user since the mid-1990s (since kernel version 2.0.0). I much prefer FreeBSD…it's not controlled by a single person (Linus) and subject to his whims. It's much better-engineered and has much better peer review, IMHO…and has a much more rigorous review process for security issues.
-- sw
The error #!/bin/bash/ was not in the script. It was only in the message to you. The error persists.
ls -l /bin/bash
-rwxr-xr-x 1 root root 1113504 Jun 6 2019 /bin/bash
Seems to say bash is installed correctly, but it still gives the error message.
I cd .. twice to the root and type ls /bin bash
It shows /bin/bash
I type ls -l /bin/bash
it shows: -rwxr-xr-x 1 root root 1113504 Jun 6 2019 /bin/bash
What now?
Well… now I'm completely vexed… I tested this on my Linode and it worked perfectly. I put echo in front of the command to start your node servers (since I don't have it) and commented out the & of each command to not run the echo in the background. It worked perfectly.
Would you be willing to take this offline? The email address on the web page I mentioned a couple of posts back is still there. Email me privately and we can arrange a better communication mechanism than bb posts to diagnose this problem. This is something really simple…
-- sw
I took your advice and read the first tutorial and on a whim I did the Hello world app and it worked. So I redid the spawn script as spawn.sh (I don't think the extension matters) exactly the same as the spawn and it worked too! There must have been an invisible character somewhere. If you figure it out let me know. My email is swarr2@hotmail.com
This is the main reason I love programming so much. You bang your head against the wall over and over and nothing works, but when it finally does it is tremendously euphoric.
Thanks so much for your help.