
Cloudgate is a lightning-fast, multi-threaded web application server for Node.js.
Cloudgate is a versatile server that serves multiple purposes:
Cloudgate was built with specific motivations:
wget -O - https://raw.githubusercontent.com/elestio/cloudgate/master/installBin.sh | bash
This version includes Node.js V18 and all the dependencies in the binary, so it can run on any linux x64 without requirements
you can then create a new app with:
cloudgate --create /path/to/create
and run your app with
cloudgate -r /path/to/create
apt install git
npm i @elestio/cloudgate -g --ignore-scripts
cd systemd
./install.sh
Check here for more details about usage
apt install -y docker.io
docker build -t cloudgate .
docker run -p 80:3000 -d cloudgate --restart always
Check here for more details about usage with docker
cd DB/MYSQL/
./startMYSQL.sh
cd SMTP/
./startPostfix.sh
cloudgate --create /path/to/create
you will then be able to choose a template app that will be created in the target folder provided Once your project is created you can run it like this:
cloudgate -r /path/to/create
Clone this repo including samples:
git clone https://github.com/elestio/cloudgate.git
Enter the cloned folder then install dependencies:
cd cloudgate
npm install
Your are now ready to run the samples below
run a sample app on the default port (3000):
cloudgate ./apps/CatchAll
Then open the site in your browser: http://127.0.0.1:3000/
Note: By default, cloudgate will use all the cores availables on your server, you can specify the number of cores to use with the option "-c"
eg: -c 4 means cloudgate will use 4 cores instead of all the cores availables
Note2: You can use relative or absolute path to point to your app folder
Start an app on port 80 with adminAPI activated:
sudo cloudgate -p80 ./apps/CatchAll --admin 1 --adminpath /CloudGateAdmin --admintoken 12345A000G
Here sudo is required if you are not root to bind port 80
Start an app on port 80 and also on port 443 with AutoSSL/letsencrypt:
sudo cloudgate ./apps/Static -p80 --ssl --sslport 443 --ssldomain www.mydomain.com
some parameters can be omitted:
sudo cloudgate ./apps/Static --ssldomain www.mydomain.com
Cloudgate will assume that if you indicate an ssldomain ssl is required, will be served on default port 443 and port 80 will be used because we need it to generate an ssl certificate with letsencrypt
In some occasions it can be usefull to bundle the source code of your app inside cloudgate binary: - Make a commercial version of your application without sources - Make a demo/evaluation/trial version of your app without sources - No need to install Node.js and npm to run the packaged application
To bundle your app inside cloudgate first you need to setup your dev env like this:
git clone https://github.com/elestio/cloudgate.git
cd cloudgate
npm install
Then copy your app source code inside /apps/ folder, you can also duplicate a folder inside apps and customize it to your needs
and finally run this to build your binary:
./buildBinary.sh
You binary will be generated in: /binaries/, you can try your binary including your app source code with:
cd binaries
./cloudgate -r /snapshot/cloudgate/apps/CatchAll/
Of course you should replace CatchAll by your own app folder.
## Reverse Proxy
Check our Reverse proxy example, this will proxy the web traffic from port 80 to the target configured in ./ReverseProxy/appconfig.json
sudo cloudgate ./apps/ReverseProxy -p80
Here is the relevant part of the appconfig.json
...
"apiEndpoints": {
"/*" : {
"skipPrefix": false,
"src": "https://youzeek.com/"
}
},
...
This rule capture /* and proxy it to the url indicated in the src attribute
## Run as a service
Install and run as a service with SystemD:
./systemd/install.sh
When installed with SystemD you can load more apps in cloudgate like this:
cloudgate --memstate /etc/cloudgate/memorystate.json --load /root/cloudgate/apps/Static
systemctl restart cloudgate
Then to unload an app from your cloudgate instance:
cloudgate --memstate /etc/cloudgate/memorystate.json --unload /root/cloudgate/apps/Static
systemctl restart cloudgate
To get the list of loaded apps from your cloudgate instance:
cloudgate --memstate /etc/cloudgate/memorystate.json --list
systemctl restart cloudgate
To create a new app from a template:
cloudgate --memstate /etc/cloudgate/memorystate.json --create /path/to/create/
Once the app is created you can go to the new folder, edit your app then load it with the --load command described above
git clone https://github.com/elestio/cloudgate.git
cd cloudgate
then make some changes in Dockerfile if needed then build the docker image
docker build -t cloudgate .
To run it once interactively:
docker run -it -p 80:3000 cloudgate
To run as a service in docker:
docker run -p 80:3000 -d cloudgate --restart always
ENV Variables:
| Var name | default value | details |
|---|---|---|
| THREADS | Number of CPU Threads to use, default to ALL | |
| PORT | 3000 | TCP port to use |
| APP_ROOT | folder containing your app (and appconfig.json) | |
| NODE_ROOT | path to folder containing node_modules | |
| OUTPUT_CACHE | 0 | Enable Caching of GET requests with 1 |
| IS_SPA | Enable SPA mode (redirect 404 to index.html) with 1 | |
| SSL | 0 | Enable SSL with 1 |
| SSL_CERT | optional path to your SSL cert fullchain | |
| SSL_KEY | optional path to your SSL private key | |
| SSL_DOMAIN | domain name for SSL | |
| SSL_PORT | 443 | TCP port for SSL |
| ADMIN | 0 | Enable Admin API/WS with 1 |
| ADMIN_PATH | path to listen (eg.: CloudGateAdmin) | |
| ADMIN_TOKEN | security token to protect your Admin | |
| VERBOSE | 0 | Enable verbose mode with 1 |
| WATCH | 0 | Enable file watch with 1 (auto invalidate cache) |
| MASTER | [Public IP, Local IP or *]:[Port]@[Token] | |
| SLAVE | [Master IP]:[Port]@[Token] |
When adminAPI is activated you can access the Websocket & REST API to control your cloudgate:
List apps running:
curl --compressed --location --request POST 'http://localhost:3000/CloudGateAdmin' \
--header 'Authorization: Bearer 12345A' \
--header 'Content-Type: text/plain' \
--data-raw '{"action": "list"}'
Load a local App:
curl --compressed --location --request POST 'http://localhost:3000/CloudGateAdmin' \
--header 'Authorization: Bearer 12345A' \
--header 'Content-Type: text/plain' \
--data-raw '{"action": "loadAppFromLocalPath", "appPath": "./apps/sample1/", }'
Load a Serverless app:
curl --compressed --location --request POST 'http://localhost:3000/CloudGateAdmin' \
--header 'Authorization: Bearer 12345A' \
--header 'Content-Type: text/plain' \
--data-raw '{
"action": "loadAppFromJSON",
"appID": "FILL_UNIQUE_IDENTIFIER_FOR_YOUR_APP",
"appConfig": {
"env": "PROD",
"version": "1.0.0",
"title": "Serverless sample",
"description": "This is a sample AWS Serverless app",
"domains": ["*"],
"publicFolder": "FILL_FOLDER_IN_S3_BUCKET",
"AWS": {
"region": "us-east-1",
"bucket": "FILL_YOUR_BUCKET_NAME",
"accessKeyId": "FILL_YOUR_AWS_ACCESS_KEY",
"secretAccessKey": "FILL_YOUR_AWS_SECRET_KEY"
},
"apiEndpoints": {
"/tests/simple": {
"src": "FILL_YOUR_DEPLOYED_LAMBDA_FUNCTION_NAME_1",
"handler": "index.handler"
},
"/tests/full": {
"src": "FILL_YOUR_DEPLOYED_LAMBDA_FUNCTION_NAME_2",
"handler": "index.handler"
}
}
unload an App:
curl --compressed --location --request POST 'http://localhost:3000/CloudGateAdmin' \
--header 'Authorization: Bearer 12345A' \
--header 'Content-Type: text/plain' \
--data-raw '{"action": "unloadApp", "appPath": "./apps/sample1/", }'
The API is described in postman/cloudgate.postman_collection.json
Check the sample app RemoteShell for more details about using Websocket to control your instance You can also try it with this command:
cloudgate -p3000 ./apps/CatchAll --admin 1 --adminpath /CloudGateAdmin --admintoken 12345A000G
Then open your browser on: http://127.0.0.1:3000/wsAdmin.html?token=12345A000G
Serve an app on port 3000 in cluster mode as the master with adminAPI activated:
cloudgate ./apps/CatchAll -p 3000 --admin 1 --adminpath /CloudGateAdmin --admintoken 12345A000G --master 0.0.0.0:8081@A_Random_Secret_Token_Here
Serve an app on port 3000 in cluster mode as a slave with adminAPI activated:
cloudgate ./apps/CatchAll -p 3000 --admin 1 --adminpath /CloudGateAdmin --admintoken 12345A000G --slave 0.0.0.0:8081@A_Random_Secret_Token_Here
Run your server in mono or multithread like described above then
Run benchmark in single core:
./benchmarks/single.sh
Run benchmark in multi core:
./benchmarks/multi.sh
PS: if you don't have WRK installed you can download the binary for linux with this command:
./download-WRK.sh
A special endpoint is available to benchmark the raw performance with no processing pipeline: http://localhost:3000/cloudgate/debug/raw
cloudgate [path] [options]
options:
[GENERAL]
-r [path] root folder for your app, this impact the chdir and from where your code is loaded when doing require()
-p --port Port to use [3000]
-oc --outputcache [0 or 1] Default is 0, disabled. When enabled this will cache all GET requests until file is changed on disk.
-c number of threads to use, eg: 2 to use 2 threads, by default it will use all cores available
-w --watch Activate file change watch [default: disabled]
-d --debug Activate the console logs for debugging
[ADMIN]
--admin 1 Enable Admin Remote API (default: disabled)
--adminpath /CloudGateAdmin Declare the virtual path of the admin api
--admintoken XXXXXXXX The admin token to use for authentication of the REST API & Websocket
[SSL]
--ssl Enable https.
--sslport SSL Port (default: 443)
--ssldomain Domain name on which you want to activate ssl (eg: test.com)
--sslcert optional path to your SSL cert. E.g: /etc/letsencrypt/live/yourdomain.com/cert.pem
--sslkey optional path to your SSL key. E.g: /etc/letsencrypt/live/yourdomain.com/privkey.pem
[CLUSTER]
--master [Public IP, Local IP or *]:[Port]@[Token] Declare this host as the master, Eg.: *:8081@000110b2-fb48-435c-a5b3-fce08c7f49da
--salve [Master IP or Domain]:[Port]@[Token] Declare this host as a slave connecting to a master, eg: --slave 192.168.0.100:8081@000110b2-fb48-435c-a5b3-fce08c7f49da
[APPS]
--list return an array of loaded apps path
--loadapp [path] Load the app located in the target path, the folder must contain appconfig.json
--unloadapp [path] Unload the app located in the target path
--create [path] Create a new app based on a template in the target path
To create a new App you can clone one of the samples in /apps folder of this repo
Another option is to create a new empty folder, and create a file named
$ claude mcp add cloudgate \
-- python -m otcore.mcp_server <graph>