11. Deployment and Development II: Heroku and Azure

In the previous chapter you looked at how to deploy your Node.js applications to servers and what strategies to use to monitor them and keep them running. However, you don’t always have access to your own server or may find that it’s not terribly cost-effective to maintain one. Thus in this chapter you’ll take a look at how you can use some of the application hosting environments available to run your applications for us.

While they’ll require that you make some changes to your application, they are often free to start with and will give you a production-quality environment in which to deploy your code. You’ll start by taking a look at Heroku, which supports Node.js as a first-class programming environment. You’ll see how to deploy your app to Heroku and then address a couple of problems that will come when working in cloud environments. You’ll then take a look at how this differs from deploying to Microsoft’s Azure platform. (Fortunately, it largely doesn’t!)

Deploying to Heroku

Heroku is an application deployment platform that originally started out supporting Ruby-on-Rails developers but has since expanded to all sorts of languages and platforms—most interestingly for you Node.js. Applications run in secure execution environments called dynos, which are not entirely unlike lightweight virtual machines. It’s extremely easy to get started with and will let you deploy free applications that, while not likely to be appropriate for high-traffic web sites, are plenty useful for smaller purposes and development. As your traffic and needs grow, you can scale your application to be given more processing power and dedicated server resources, which are available on a pay-as-you-go model.

Let’s work our way through the process of getting your photo albums application up and running on Heroku.

Before We Begin

You’ll need to do a couple of things before you begin deploying your application to Heroku.

Sign Up for a Heroku Account

Go to heroku.com and sign up for an account if you do not have one. Accounts are free and quick to get.

Download the Heroku CLI Tools

You’ll next need to download the Heroku CLI (command-line interface) tools (formerly called the Heroku Toolbelt) appropriate for your platform. You can find the installer for these at https://devcenter.heroku.com/articles/heroku-command-line. When you’re done, verify that the installation worked by typing heroku—the output should look something as follows:

hostname:simple_node_project marcw$ heroku
 Image    Add apps to this dashboard by favoriting them with heroku apps:favorites:add
See all add-ons with heroku addons
See all apps with heroku apps --all

See other CLI commands with heroku help. The display on your machine will be a little
different.

Get the Updated Photo Sharing App for Heroku

We have a special version of our photo sharing application for Heroku, which we’ll explain in greater detail in the next sections. However, you’ll want to clone this from GitHub by grabbing the repository at github.com/marcwan/NodePhotoSharingHeroku.git.

Preparing Your Deployment

Let’s get started, shall we?

1. Log In

Log in to Heroku as follows:

hostname:simple_node_project marcw$ heroku login
Enter your Heroku credentials.
Email: [email protected]
Password (typing will be hidden):
Logged in as [email protected]

2. Go to Your NodePhotoSharingHeroku Git Folder

Change into the directory for the repository you just pulled down from GitHub. I’ll assume it’s called photo_sharing_heroku/ from now on.

3. Look at the Changes We’ve Made

In order to make our application work on Heroku, we’ve had to make a few changes. Let’s take a look at what those are.

First and foremost, we’ve changed the directory hierarchy a little bit. We’ve moved our main script and its subfolders into the root folder. This will make it a bit easier to find things in the Heroku execution environment. Our folder structure now looks like the following:

Procfile
README.md
app.json
basic.html
data/
handlers/
local.config.json
package.json
schema.sql
server.js
static/
test.jpg
uploads/

All of our files and folders are still there, just laid out a bit differently.

There are two new files of note, however: Procfile and app.json. Procfile looks like this:

web: node server.js

Very simply, it tells Heroku how to run our (web) application: simply run node with the server.js script!

The app.json file is a bit more involved, as follows:

{
  "name": "Node.js Photo Sharing on Heroku",
  "description": "A Node.js app using Express 4",
  "repository": "https://github.com/marcwan/simple_node_project",
  "logo": "http://node-js-sample.herokuapp.com/node.svg",
  "keywords": ["node", "express", "static"],
  "image": "heroku/nodejs"
}

This file provides metadata for Heroku about your application, including the GitHub repository from which it is running.

We’ve made one other small change—if you look in package.json, you’ll see the following at the bottom now:

    "engines" : {
      "node" : "6.x"
    }

This will tell Heroku to use version 6.x of Node.js to run our application, which is great, because that’s what we’ve been developing with!

And that’s basically all we had to change (add) to get our application ready for Heroku.

Create and Deploy the Application on Heroku

In order to do anything with your application, you’ll need to create a Heroku app and then deploy it. You can then configure other missing parts which you’ll see in subsequent sections.

1. Create Your Heroku Application

To create your application, you run:

heroku create

This will give you an application name that is semi-random, like shrouded-earth-22708 below.

hostname:simple_node_project marcw$ heroku create
Creating app... done, shrouded-earth-22708
https://shrouded-earth-22708.herokuapp.com/ | https://git.heroku.com/ shrouded-
earth-22708.git
Git remote Heroku added

You can, if you want, give it your own name, and if it is not already taken, can use that instead. Deploy the application to set up everything you need in Heroku:

hostname:photo_sharing_heroku marcw$ git push heroku master
Counting objects: 65, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (60/60), done.
Writing objects: 100% (65/65), 74.46 KiB | 0 bytes/s, done.
Total 65 (delta 18), reused 0 (delta 0)
remote: Compressing source files... done.
remote: Building source:
remote:
remote: -----> Node.js app detected
remote:
remote: -----> Creating runtime environment
remote:
remote:        NPM_CONFIG_LOGLEVEL=error
remote:        NPM_CONFIG_PRODUCTION=true
remote:        NODE_ENV=production
remote:        NODE_MODULES_CACHE=true
remote:
remote: -----> Installing binaries
remote:        engines.node (package.json):  6.x
remote:        engines.npm (package.json):   unspecified (use default)
remote:
remote:        Resolving node version 6.x via semver.io...
remote:        Downloading and installing node 6.5.1...
remote:        Using default npm version: 3.10.3
remote:
remote: -----> Restoring cache
remote:        Skipping cache restore (new runtime signature)
remote:
remote: -----> Building dependencies
<<< I've deleted a lot of node package installation stuff here >>>
remote:
remote:
remote: -----> Discovering process types
remote:        Procfile declares types -> web
remote:
remote: -----> Compressing...
remote:        Done: 13.5M
remote: -----> Launching...
remote:        Released v3
remote:        https://shrouded-earth-27708.herokuapp.com/ deployed to Heroku
remote:
remote: Verifying deploy... done.
To https://git.heroku.com/shrouded-earth-27708.git
 * [new branch]      master -> master

2. Open and Test the Application in the Browser

Open the application in your browser by running:

heroku open

You should see a browser pop open with your application running in it! It will say there are no albums, and furthermore, if you try to do anything with it, it will break. Why? Because you haven’t configured the database yet! Let’s do that now.

3. Configure the ClearDB MySQL Database Add-On

Before you can start really using your application, you have to prepare your MySQL database. You don’t have a local database in a Heroku application, so you need to configure what’s called an “add-on” in Heroku. Fortunately, there’s a MySQL add-on called ClearDB that will let you work with a small database for free when starting out. Add that to your Heroku app now.

hostname:photo_sharing_heroku marcw$ heroku addons:create cleardb:ignite
Creating cleardb:ignite on shrouded-earth-27708... free
Created cleardb-metric-77672 as CLEARDB_DATABASE_URL
Use heroku addons:docs cleardb to view documentation

You now have a MySQL database ready for you to use. You’ll now need to get some critical information to update your local.config.json file: The server name, user name, password, and database name. You get this by running the following:

hostname:photo_sharing_heroku marcw$ heroku config | grep CLEARDB
CLEARDB_DATABASE_URL: mysql://bde4e0dd77d8d0:ce05cb42@us-cdbr-iron-east-08.cleardb.
net
/heroku_9039bbf50c4c7a9?reconnect=true

Windows users will use findstr instead of grep in the above command, but otherwise it’s the same.

You’ll see four things that are bold italic:

1. us-cdbr-iron-east-08.cleardb.net—the database server address.

2. heroku_9039bbf50c4c7a9—the database name.

3. bde4e0dd77d8d0—the user name.

4. ce05cb42—the password.

With this, you now have enough to update your local.config.json file with the database connection information, as follows:

{
    "config": {
        "db_config": {
            "host": "us-cdbr-iron-east-08.cleardb.net",
            "user": "bde4e0dd77d8d0",
            "password": "ce05cb42",
            "database": "heroku_9039bbf50c4c7a9",
            "pooled_connections": 125,
            "idle_timeout_millis": 30000
        },

        "static_content": "/static/"
    }
}

Now, you have to run the schema.sql file to create the contents of the database! You’ll change the top of the schema.sql file to look like the following:

DROP DATABASE IF EXISTS heroku_9039bbf50c4c7a9

CREATE DATABASE heroku_9039bbf50c4c7a9
    DEFAULT CHARACTER SET utf8
    DEFAULT COLLATE utf8_general_ci;

USE heroku_9039bbf50c4c7a9;

Now you can run the script with the following command:

mysql --host=us-cdbr-iron-east-08.cleardb.net --user=bde4e0dd77d8d0
      --password=ce05cb42 heroku_9039bbf50c4c7a9 < schema.sql

Now you have your database all setup!

Commit, redeploy, and open your application, as follows:

git commit -a -m "updated db conn info" && git push heroku master && heroku open

(The && in the above command is a way of joining multiple commands into one—the command after && is executed only if the previous command completes without any errors.)Indeed, you’ll use this command line (three commands at once) to quickly push and deploy your application all the time.

You’ll now see the same application, except that it will work! You can register, login, create an album, and then upload a photo.

We Have a Problem

We have a rather serious problem with your application, however. This is due to the rather ephemeral nature of Heroku dynos, the environment in which your applications run. These are temporary execution environments that Heroku manages for us. They do have a decent amount of disk space, but every time you restart one of these, this disk space is completely reset!

Thus, all photo files you have uploaded are deleted every time you restart the application! The database records for them are still there, but the actual images are gone! To see this in action, just make a quick change to your code somewhere, and then run the git commit/ git push / heroku open commands above. You’ll notice your image files are gone.

This is where you’ll need to use another Heroku add-on to handle cloud storage for us—you’ll keep all the images that users upload to your application in a remote file storage application. The one you’ll use is called Cloudinary, which is free for small amounts of files with very little traffic—perfect for your development environment!

To work with these, you’ll need to do the following things:

1. Add cloudinary to your Heroku application.

2. Update your package.json to include the Cloudinary uploader.

3. Update your album.js data class to use this instead of local file storage.

4. Update your album.js page bootstrapper (in static/content/abum.js) to use the Cloudinary URL instead of a local URL to static files on your server.

Let’s do these one by one.

1. Add Cloudinary to your Heroku Application

You’ll use the same command you used for adding CloudDB to add Cloudinary, as follows:

hostname:photo_sharing_heroku marcw$ heroku addons:create cloudinary
Creating cloudinary on • shrouded-earth-27708... free
Created cloudinary-rectangular-70140 as CLOUDINARY_URL
Use heroku addons:docs cloudinary to view documentation

If you want to see the configuration information for Cloudinary, you can just run the following command (Windows users, don’t forget to use findstr instead of grep):

heroku config | grep CLOUDINARY

But the good news is that you won’t need to use this at all; the cloudinary module will just work by using environment variables to figure out where to go.

2. Update Your package.json to Include Cloudinary

This step is pretty straightforward—you simply need to include a new dependency as follows:

    "dependences" : {
     ... etc ...
     "cloudinary" : "",
     ... etc ...
   }

You’ll see you just grab the latest version of the cloudinary module.

3. Update Your album.js Data Handler for Cloudinary

Basically, you need to modify data/album.js in two places to make it compatible with Cloudinary. First, in exports.create_album, you’ll remove all references to mkdir, since you won’t need album folders any more. So, you’ll get rid of the following lines: in create_album:

        // make sure the folder exists.
        function (results, fields, cb) {
            write_succeeded = true;
            fs.mkdir('.' + local.config.static_content
                     + "albums/", cb);
        },

You can just copy over data/cloudinary/album.js to data/album.js to save yourself having to type in all this. You’ll also note that the next function argument list changes because of the deletion of code.

Next, you need to get rid of the file copying in exports.add_photo_to_album. In the older version of add_photo_to_album, after the db.dbpool.query, you have the following code:

        // make sure the folder exists!!!!
        function (results, fields, cb) {
            write_succeeded = true;
            fs.mkdir(basepath, function () { cb(null); });
        },
        function (cb) {
            var pttth = basepath + photo_data.albumid + "/";
            fs.mkdir(pttth, function () { cb(null); });
        },

        // now copy the temp file to static content
        function (cb) {
            write_succeeded = true;
            var save_path = '.' + local.config.static_content + "albums/"
                + photo_data.albumid + "/" + base_fn;
            backhelp.file_copy(path_to_photo, save_path, true, cb);
        },

You’ll get rid of all of these, and instead add the following function to the async waterfall before the db.dbpool.query:

        function (cb) {
            cloudinary.uploader.upload(path_to_photo, function (results) {
                    cb(null, results);
                });
        },

        function (results, cb) {
            db.dbpool.query(
                "INSERT INTO Photos VALUES (?, ?, ?, ?)",
                [ photo_data.albumid, results.secure_url, photo_data.description,
                  photo_data.date ],
                cb);
        },

(You’ll probably also notice that you need to require cloudinary at the top of this file now since you’re using the module here!)

You’ll see that uploading a file to Cloudinary is as simple as calling cloudinary.uploader.upload with the path to the local file. Once it has uploaded, you’ll get the URL to refer to this file in your web applications back in the results. You’ll use the secure_url version (there’s also just url) since you should always plan to deploy HTTPS versions of your application.

You then update your SQL query to use that secure_url instead of a file path, which means you now have in the database everything you need to get at your pictures!

4. Update Your Album Page Bootstrapper

Your last task to make your application use cloud storage is to update the album.js album page bootstrapper to use this new URL instead of a constructed local file URL.

In the massage_album function, you’ll change the line:

var url = "/albums/" + a.name + "/" + p[i].filename;

to be simply:

var url = p[i].filename

Since the filename is just the complete URL.

And That’s It!

Without too much hassle, you’ve been able to take your photo sharing application and upload, deploy, and adapt it to the cloud execution world of Heroku. You’re still not quite done yet—you’ll definitely want to look at improving session storage, and configuring your application to handle more load and requests, but you’ve made a great start and without really having to know much about server execution environments yourselves!

Deploying to Microsoft Azure

If you’re a Windows user or simply more partial to Microsoft’s Azure cloud platform, you’re in luck—deploying Node.js applications to Azure isn’t a whole lot much more difficult than it was for you to deploy to Heroku above, and indeed you’ll be able to take advantage of some of the same add-ons such as CloudDB and Cloudinary to handle MySQL and image storage for us.

Before We Begin

We’ll need to do a couple of things before we begin deploying your application to Azure.

Sign Up for an Azure Account

Go to azure.microsoft.com and sign up for an account if you do not have one. They give you some free credit to start using and developing with the platform, which will be plenty for your purposes in this book. (Indeed, we didn’t use any of our balance while writing this book!) You will probably have to enter a phone number and credit card information, but your card won’t get charged until you scale beyond a certain level, which you won’t be doing here.

Download the Azure CLI Tools

There are command-line tools for Azure for most major platforms, including Windows, Mac OS X, and Linux. You will use the Windows ones here.

First, go and visit https:///azure.microsoft.com/en-us/documentation/articles/xplat-cli-install. From here click on the “Azure CLI” tab and then pick and download the version of the tools most appropriate for your platform.

To test if they’re working, run the following command in cmd.exe:

C:srcAzureTest> azure

You’ll probably see something similar to Figure 11.1. If not, check your installation and make sure you can see this screen.

Image

Figure 11.1 Running azure

Download the Updated Photo Sharing App for Azure

We have a special version of our Photo Sharing application for Azure, which we’ll explain in greater detail in the next sections. However, you’ll want to download (not clone) this from GitHub by grabbing the repository at github.com/marcwan/NodePhotoSharingAzure.git. You’ll see why you download instead of clone this in a little bit.

Preparing Your Deployment

Deploying to Azure is going to feel awfully familiar if you’ve already done the Heroku part of this chapter. If not, then just follow along with the instructions!

1. Login to Azure

To login to Azure, run the following command in cmd.exe:

C:srcAzureTest> azure login

info:   Executing command login
-info:  To sign in, use a web browser to open the page https://aka.ms/devicelogin.
Enter the code ABC123DEF to authenticate.

Follow the instructions in the browser and then switch back to your cmd.exe window. You should then see:

|info:   Added subscription Free Trial
+info:   login command OK

Of particular importance is the “Added subscription” line. If you do not see this in your output, lots of other things are going to fail with vague subscription errors. This is almost always because you did not complete the Microsoft Azure sign-up and verification process. Please go back and complete the full sign-up to Azure, and complete the phone and credit card verification. Then you can re-execute the azure login command to make sure it’s all okay.

2. Put Your Downloaded Git Source in a Folder

Create a directory on your local machine and unzip the source you downloaded from GitHub into it. I’ll assume it’s called C:srcphoto_sharing_azure from now on.

3. Look at the Changes We’ve Made

In order to make our application run more smoothly on Azure, we’ve had to make a few changes. Let’s take a look at what those are.

First and foremost, we’ve changed the directory hierarchy a little bit. We’ve moved our main script and its subfolders into the root folder. This will make it a bit easier to find things in the Azure execution environment. Our folder structure now looks as follows:

README.md
basic.html
data/
handlers/
local.config.json
package.json
schema.sql
server.js
static/
test.jpg
uploads/

All of our files and folders are still there, just laid out a bit differently.

Look in server.js, near the end. Instead of the following:

db.init();
app.listen(8080);

we now have the following:

var port = process.env.PORT || process.env.port || 5000;
db.init();
app.listen(port);

Azure will tell you what port to listen on via environment variables, which we can see via the process object in Node. Environment variables are usually system configuration settings that we can access within our application, and they tell you more about our execution environment.

We’ve made one other small change—if you look in package.json, you’ll see the following at the bottom now:

    "engines" : {
      "node" : "6.x"
    }

This will tell Azure to use version 6.x of Node.js to run our application, which is great, because that’s what we’ve been developing with!

Create and Deploy the Application on Azure

In order to do anything with your application, you’ll need to create an Azure app and then deploy it. You can then configure other missing parts which you’ll see in subsequent sections.

1. Create Your Azure Application

To create your application, you run:

azure site create --git marcwandphotosharingapp111

For this example, you’ll pick your own application name, so we’ve chosen something pretty unique for your photo sharing application.

Remember how you just downloaded your source code from GitHub before? You did this because Azure gives you your own Git repository that it manages for us, not using GitHub. That is what the --git flag does for us.

C:srcphoto_sharing_azure> azure site create --git marcwandphotosharingapp111
info:    Executing command site create
+ Getting sites
+ Getting locations
help:    Location:
  1) South Central US
  2) North Europe
  3) West Europe
  4) Southeast Asia
  5) East Asia
  6) West US
  7) East US
  8) Japan West
  9) Japan East
  10) East US 2
  11) North Central US
  12) Central US
  13) Brazil South
  14) Canada Central
  15) Canada East
  16) West Central US
  17) West US 2
  18) UK West
  19) UK South
: 3
info:    Creating a new web site at marcwandphotosharingapp111.azurewebsites.net
/info:    Created website at marcwandphotosharingapp111.azurewebsites.net
+
+ Getting locations
info:    Initializing remote Azure repository
+ Updating site information
info:    Remote azure repository initialized
+ Getting site information
+ Getting user information
info:    Executing 'git remote add azure https://marcwan_nt1@ marcwandphotosharing
app111.scm.azurewebsites.
net/marcwandawesome11111.git'
info:    A new remote, 'azure', has been added to your local git repository
info:    Use git locally to make changes to your site, commit, and then use 'git push
azure master'
to deploy to Azure
info:    site create command OK

And with that, you have your application created on Azure!

3. Deploy Your Application to Your Site

Let’s deploy the code to the server and open up the home page. First you’ll add all your files to the Git repository you created along with your project in the previous step and then push your changes to Azure. You’ll execute the following commands:

C:srcphoto_sharing_azure> git add .
C:srcphoto_sharing_azure> git commit -a -m "initial checkin"
C:srcphoto_sharing_azure> git push azure master

After a lengthy bit of output, your application should be ready to go. To view it, you now do:

C:srcphoto_sharing_azure> azure site browse

And a browser will pop up with your website in it. It will have no albums, and furthermore, nothing will work!

This is because you haven’t added database support to your application yet. We do that now.

3. Configure the ClearDB MySQL Database Add-On

Before you can start really using your application, you have to prepare your MySQL database. You don’t have a local database in an Azure application, so you need to configure what’s called a service. Fortunately, there’s a MySQL add-on called ClearDB (just as there was for Heroku above) that will let you work with a small database for free when starting out. Add that to your Azure app now.

You’ll need to do this via the web browser, so visit azure.microsoft.com again, and click on the “+ New” button in the top left. You’ll then get a search box into which you can type “ClearDB” (see Figure 11.2).

Image

Figure 11.2 Adding ClearDB

You’ll see a match and then you can click on that to go to the results page (see Figure 11.3) where “MySQL Database” by publisher “ClearDB” will be an option. Click on that and then click “Create” to create your database. Give it a name, like “marcwand_photo_sharing_1”, choose “Free Trial” for subscription, “Shared” for database type, and then create a new resource group called “learning_node_resources.” For location, pick something appropriate (I chose West Europe since that’s closest to where I am), and then choose Mercury for the pricing tier and accept the legal terms (see Figure 11.4).

Image

Figure 11.3 Choosing ClearDB

Image

Figure 11.4 Setting ClearDB parameters

You then click “Create” again, and your database will soon be ready to go! It’ll take a few minutes for the initialization to complete, but once it does, you’ll be able to click into your new database to see the parameters you’ll need to make the connection.

You’ll see your connection parameters in a panel like that shown in Figure 11.5. You’ll want to specify the hostname, username, and password. (Your database name is the one you chose above, marcwand_photo_sharing_1.)

Image

Figure 11.5 Your connection parameters

With this, you now have enough to update your local.config.json file with the database connection information, as follows:

{
    "config": {
        "db_config": {
            "host": "us-cdbr-iron-east-08.cleardb.net",
            "user": "53c8ab8ffe",
            "password": "488ae",
            "database": "marcwand_photo_sharing_1",
            "pooled_connections": 125,
            "idle_timeout_millis": 30000
        },

        "static_content": "/static/"
    }
}

Now, you have to run the schema.sql file to create the contents of the database! You’ll change the top of the schema.sql file to look as follows:

DROP DATABASE IF EXISTS marcwand_photo_sharing_1

CREATE DATABASE marcwan_photo_sharing_1
    DEFAULT CHARACTER SET utf8
    DEFAULT COLLATE utf8_general_ci;

USE marcwand_photo_sharing_1;

Now you can run the script with the following command:

C:Usersmarcwan> mysql --host= us-cdbr-iron-east-08.cleardb.net --user=53c8ab8ffe
--password=488ae marcwand_photo_sharing_1 < schema.sql

Now you have your database all setup!

Commit and redeploy your application, as follows:

C:srcphoto_sharing_azure> git commit -a -m "updates"
C:srcphoto_sharing_azure> git push azure master

We Have a Problem (and Déja Vu!)

Much like for the Heroku-deployed version of your application above, we have a rather serious problem with your application, however. The problem is caused by the rather ephemeral nature of an Azure execution environment, the environment in which your applications run. You cannot rely on the disk space backing these environments not to change or be erased periodically.

Thus, all photo files you have uploaded can disappear at inconvenient times! The database records for them are still there, but the actual images will not be.

You’ll use another service to handle image storage for us—you’ll keep all the images that users upload to your application in a remote file storage application. The one you’ll use is called Cloudinary, and is free for small amounts of files with very little traffic; perfect for your development environment!

To work with these, you’ll need to do the following things:

1. Create a Cloudinary (free) account.

2. Update your package.json to include the Cloudinary uploader.

3. Update server.js with your connection information.

4. Update your album.js data class to use this instead of local file storage.

5. Update your album.js page bootstrapper (in static/content/abum.js) to use the Cloudinary URL instead of a local URL to static files on your server.

Let’s do these one by one.

1. Create a (Free) Cloudinary Account

While there once was a service in the Azure marketplace for Cloudinary, it no longer appears to be there. Fortunately, that won’t stop you from using Cloudinary in your photo sharing application—you just have to visit cloudinary.com and sign up for a free account. Once you’ve done that, you’ll need to remember three things from the Cloudinary dashboard:

1. Cloud name

2. API Key

3. API Secret

You’ll use all of these in step 3 below. You can see an example of the Cloudinary dashboard / console where you’d get these values in Figure 11.6.

Image

Figure 11.6 Your Cloudinary parameters

2. Update Your package.json to Include Cloudinary

This step is pretty straightforward—you simply need to include a new dependency as follows:

    "dependences" : {
     ... etc ...
     "cloudinary" : "",
     ... etc ...
   }

You’ll see you just grab the latest version of the cloudinary module.

3. Update server.js with Your Connection Information

Remember those three values you saved when you created your Cloudinary account? You need those now. Modify your server.js file to require the cloudinary module at the very top, and then add the following:

cloudinary.config({
    cloud_name: "SAVED_CLOUD_NAME",
    api_key: "SAVED_API_KEY",
    api_secret: "SAVED_API_SECRET"
});

4. Update Your album.js Data Handler for Cloudinary

Basically, you need to modify data/album.js in two places to make it compatible with Cloudinary. First, in exports.create_album, you’ll remove all references to mkdir, since you won’t need album folders any more. So, you’ll get rid of the following lines: in create_album:

        // make sure the folder exists.
        function (results, fields, cb) {
            write_succeeded = true;
            fs.mkdir('.' + local.config.static_content
                     + "albums/", cb);
        },

You can just copy over data/cloudinary/album.js to data/album.js to save yourself having to type in all this. You’ll also note that the next function argument list changes because of the deletion of code.

Next, you need to get rid of the file copying in exports.add_photo_to_album. In the older version of add_photo_to_album, after the db.dbpool.query, you have the following code:

        // make sure the folder exists!!!!
        function (results, fields, cb) {
            write_succeeded = true;
            fs.mkdir(basepath, function () { cb(null); });
        },
        function (cb) {
            var pttth = basepath + photo_data.albumid + "/";
            fs.mkdir(pttth, function () { cb(null); });
        },

        // now copy the temp file to static content
        function (cb) {
            write_succeeded = true;
            var save_path = '.' + local.config.static_content + "albums/"
                + photo_data.albumid + "/" + base_fn;
            backhelp.file_copy(path_to_photo, save_path, true, cb);
        },

You’ll get rid of all of these, and instead, add the following function to the async waterfall before the db.dbpool.query:

        function (cb) {
            cloudinary.uploader.upload(path_to_photo, function (results) {
                    cb(null, results);
                });
        },

        function (results, cb) {
            db.dbpool.query(
                "INSERT INTO Photos VALUES (?, ?, ?, ?)",
                [ photo_data.albumid, results.secure_url, photo_data.description,
                  photo_data.date ],
                cb);
        },

(You’ll probably also notice that you need to require cloudinary at the top of this file now since you’re using the module here!)

You’ll see that uploading a file to Cloudinary is as simple as calling cloudinary.uploader.upload with the path to the local file. Once it has uploaded, the results will return to you the URL you’ll need to refer to the file in your web application. You’ll use the secure_url version (there’s also just url), since you should always plan to deploy HTTPS versions of your application.

You then update your SQL query to use that secure_url instead of a file path, which means you now have in the database everything you need to get at your pictures!

5. Update Your Album Page Bootstrapper

Your last task to make your application use cloud storage is to update the album.js Album page bootstrapper to use this new URL instead of a constructed local file URL.

In the massage_album function, you’ll change the line:

var url = "/albums/" + a.name + "/" + p[i].filename;

to be simply:

var url = p[i].filename

Since the filename is just the complete URL.

And That’s It!

Recommit, and then execute:

C:srcphoto_sharing_azure> git commit -a -m "cloudinary updates"
C:srcphoto_sharing_azure> git push azure master

Running azure site browse should now show you a perfectly working web application with persistent file storage and a working database!

Microsoft Azure provides a robust cloud platform for you to deploy your Node.js applications, and in this part of the book, you’ve seen that it’s not particularly difficult to modify your application to work with Azure.

Summary

In this chapter you’ve taken the MySQL version of your photo sharing application and deployed it to two different cloud platforms, Heroku and Microsoft Azure. The process for doing so was pretty straightforward for both and remarkably similar! You’re even able to use most of the same services for things like databases and image storage on the backend! This will give you maximum flexibility later when you want to scale and grow your servers.

In the next chapter, you’re going to change gears briefly and see how you can use Node.js not just to develop powerful web applications but also to do synchronous tasks that lend themselves to doing command-line programming and scripting.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset