Running a Node.js server and database on Azure - node.js

As a preface I am new to web development and have never published a site before.
I have built a website which runs fine locally and I want to publish it to the web using Azure.
The site uses a node.js server which I wrote myself (No express) which is connected to an SQLite3 database using the sqlite3 node module.
All I want to do is publish this site, I've tried using Azure to do so by using Azure command line tools to create a web app from the Git repo I have for the site.
I have a package.json file pointing to the server.js file which is the backend for the site, as well as serving files in the site it also returns data from an SQLite3 database I also have in the site folder. I also have the web.config file from this: https://github.com/projectkudu/kudu/wiki/Using-a-custom-web.config-for-Node-apps with the path to my server changed to match mine.
When I try to visit the site all I get is a blank screen, the application log gives this error: Error: SQLITE_CANTOPEN: unable to open database file
at Error (native)
So I'm guessing this means it has a problem having the DB built into the site in this way, if I comment out the database stuff it loads the site (minus the db content) just fine. When I try to test running the server in the azure console I get a "Bad Request" error, running on my own machine works fine.
My question is basically, how should I go about this goal of getting the site up given the challenges I've got? Is having an integrated db file completely the wrong approach or can I make it work? I've played around creating an azure DB but I cannot work out how to get the data from my db file into it. Are azure virtual machines the way to go, the advice I read was they're for more computationally intensive projects I'm only hosting a site?

I try to reproduce your issue on my side, and build a simple nodejs server with sqlite3 module on Azure Web Apps. But it works fine on my side, here are my test steps, you can try to follow my steps to fix your issue.
As to install sqlite3 requiring node-pre-gyp which is kind of Native Modules not supported via deployment task on Azure Web Apps. So we can install the sqlite3 module on local, and deploy the node_modules folder with the application togather to Azure.
As the nodejs runtime on Azure is in ia32 platform version. So we need to install with the command npm install sqlite3 --target_arch=ia32 on local.
Here is the code on my test:
var http = require("http");
var server = http.createServer(function(request, response) {
response.writeHead(200, {"Content-Type": "text/html"});
response.write("<!DOCTYPE html>");
response.write("<html>");
response.write("<head>");
response.write("<title>Hello World Page</title>");
response.write("</head>");
response.write("<body>");
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('test.db');
var data = [];
db.serialize(function() {
db.run("CREATE TABLE IF NOT EXISTS lorem (info TEXT)");
var stmt = db.prepare("INSERT INTO lorem VALUES (?)");
for (var i = 0; i < 10; i++) {
stmt.run("Ipsum " + i);
}
stmt.finalize();
db.each("SELECT * FROM lorem", function(err, row) {
data.push(row);
}, function() {
response.write(JSON.stringify(data));
response.write("</body>");
response.write("</html>");
response.end();
});
});
db.close();
});
server.listen(process.env.PORT || 1337);
Any further concern, please feel free to let me know.

Related

Simple way to configure NodeJS environment

I am really just getting into cloud stuff and have been creating Node JS apps as a hobby for a long time. I am using MongoDB as my database. I have now pushed my app on Heroku and am happy that it runs, but I've only realized some things like there is no local storage and no database without addons. So now I have a free Atlas (MongoDB) hosting so my Heroku app can use that as its database.
My app starts with a simple npm start which does the build stuff (like grunt) and then runs the node app. But how can I change the environment to be production vs deploy so that if I did something like npm start -prod it would use the cloud hosted database, but npm start -dev would use my PC's MongoDB instance?
This what I do -
Loading environment variables from an .env file and passing them to the Node.js runtime would be the ideal case.
const loadEnvironment = async function () {
fs.readFile('.env', 'utf8', function (err, data) {
if (err) {
return console.log(err);
}
return (data);
});
}; //loadEnvironment
For instance, file name .env which contains 'prod' or 'dev'. Handle db connections based on the env obtain from this file.

NodeJS deployment to A2Hosting subdomain?

Long story short, my buddy has an A2 account (hosting his main app on PHP). I wanted to get my hands dirty with Node (particularly the deployment process) and he said I could use his hosting so I've created a subdomain. I've got the subdomain setup and running a hello world script
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, {'Content-Type': 'text/plain'});
var message = 'Hello world!\n',
version = 'NodeJS ' + process.versions.node + '\n',
response = [message, version].join('\n');
res.end(response);
});
server.listen();
Does anyone have experience deploying node to A2? I'm still pretty new to Node but have enjoyed it so far! Forgive ignorance on the subject, I'm coming from a full stack PHP dev setup.
What I've done so far is work through the Heroku getting started tutorial and have a decent start on the site I'm working on. Locally works great and connecting to my db instance (MySQL). I'm using EJS for templating, etc.
I'm not really familiar yet with creating createServer() functions and such as the Heroku example doesn't seem to go through it but is doing "web: node index.js" from within the proc file.
Is there a way to get the configuration on A2 to run this type of deployment?

Is it possible to browserify the "tedious" module so that the nodejs program can be run in the browser?

I'm a beginner to Node.js and I'm currently building a Node.js program that accesses and queries a Microsoft Azure SQL database with the "tedious" module (see code below) and puts the data onto a html webpage. I want to run this code in a browser so I used browserify to bundle the modules together. However, when this code is run in Google Chrome, the following error is returned: require is not defined. Is there a fix? Is it even possible to use the tedious module in Chrome? If it isn't possible, do I need to use an intermediate server between the Node.js application and the webpage?
var Connection = require('tedious').Connection;
var config = {
userName: 'hackmatch',
password: 'hackvalley123!',
server: 'hackmatch.database.windows.net',
options: {encrypt: true, database: 'AdventureWorks'}
};
var connection = new Connection(config);
connection.on('connect', function(err) {
// If no error, then good to proceed.
console.log("Connected");
});
var Request = require('tedious').Request;
var TYPES = require('tedious').TYPES;
Thanks in advance for your help! :)
No. This module can only be used in Node.
tedious depends on the node.js net module to make a connection to the database server. This module has no equivalent on the browser, as web pages cannot make arbitrary network connections.
Even if it were possible to use this module in the browser, it'd be a terrible idea. You'd be allowing anyone on your web site to connect directly to your SQL server and run SQL queries. This can only end badly.

How to cache last loaded data on the client in Cordova app?

I'm building an app on Meteor and have been testing my app on my Android device. It works great. I'm publishing my data on the server and subscribing to it in the client.
But when I don't have data or the server is down, the mobile app shows no content. This makes sense as it can't load anything. But it must be possible to cache the last loaded data from the server so there is at least something to display in the mobile app when there is no connection.
I looked into appcache but that seems to be for assets as opposed to database content. Does anybody know how to make the Cordova version of a Meteor app cache the database locally so it will also work offline?
To cache our iPad application configuration we use localStorage. It's super easy to use and really worked out well for use.
localStorage.settings = settings; // data from server
and when the application starts:
var settings = null;
if( navigator.network.connection.type === Connection.NONE ) {
settings = localStorage.settings
} else {
// fetch settings from server
}
We've been running this implementation for over a year now without any issues.

Microsoft Azure node-sqlserver issues

Planning to build new project on Windows Azure Websites using node.js, I ran into issues with SQL Server module, that I just cant resolve:
I'm using downloaded binary of the module, with simple code from example, connecting to Azure hosted SQL Server:
var sql = require('node-sqlserver');
var http = require('http');
var conn_str = "Driver={SQL Server Native Client 10.0};Server=tcp:server.database.windows.net,1433;Database=database;Uid=user#server;Pwd=mypass;Encrypt=yes;Connection Timeout=30;";
var port = process.env.port||3000;
http.createServer(function (req, res) {
sql.query(conn_str, "SELECT * FROM testdb.testtable", function (err, results) {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.write("Got error :-( " + err);
res.end("");
return;
}
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(JSON.stringify(results));
});
}).listen(port);
The example works locally from my PC, it is able to connect to Azure SQL and retrieve rows, although I had to downgrade node to 0.6.19 to make it work, but it fails when I deploy it to Azure. When I try to access website, after long waiting time I receive:
iisnode encountered an error when processing the request.
HRESULT: 0x6d
HTTP status: 500
HTTP reason: Internal Server Error
You are receiving this HTTP 200 response because system.webServer/iisnode/#devErrorsEnabled configuration setting is 'true'.
In addition to the log of stdout and stderr of the node.exe process, consider using debugging and ETW traces to further diagnose the problem.
The node.exe process has not written any information to the stdout or stderr.
I tried to compile node-sqlserver module from source, and again it worked on my PC, with the same result on Azure. Also I verified that module binary gets deployed(I'm using git to deploy).
Any ideas?
Ok, what it turned out to be, is that SQL database and Websites where in different geo-regions, and despite "Make available to Azure Services" setting, Azure not able to connect to SQL server in different region. Had to move the database and it worked.

Resources