Image hosting built on Azure Blob Storage and Node.js
Ghost, the blogging platform that Azure.js is hosted on, provides an amazing writing and reading experience. It does not, unfortunately, come equipped with a native way to host files/images. I'd like to be able to include screenshots without needing to go through a third party like Imgur. Fortunately, we have Azure to step in for us.
In this article, we'll build a command line file uploader using Azure Blob Storage and Node.js.
All the screenshots in this article are hosted on Azure Blob Storage.
Azure Storage is a surprisingly powerful solution. It possesses an array of methods for logically storing data – tables, queues, file system and blobs. Each provides specialized strengths for data storage and balances read/write appropriately to the needs of the application.
Our needs are simple:
1. Upload images to a container that provides public read access.
2. Easily access the images that are uploaded via a URL endpoint.
Both Azure File Storage and Azure Blob Storage could be an appropriate match because each solution comes equipped with a REST interface to support our needs. I'm content without SMB access though, so we can narrow it down to Azure Blobs (not to mention File Storage doesn't have a Node SDK). The Microsoft Docs provide a pretty clean comparison table for deciding between these as well as an Azure Data Disk.
We can use the Azure Storage SDK and Node to build a simple command line uploader for images (or really anything else). Let's get started.
Create a resource group for Azure Blobs
Assuming you don't have a Resource Group to assign your Azure Blob Storage to, you can just create one easily enough with Azure CLI.
az group create --name azuredotjstesting -location southcentralus
Setup Azure Storage
Unfortunately, setting up a new Storage account on Azure CLI is a little wonky, so we'll be using the Azure portal to set it up. You can customize your storage with the appropriate security and high availability features during setup. The defaults should work fine.
Create a container
Our blobs will need a logical container. We'll contain all our blobs in a single container: imagecontainer. The container can be created with the SDK or Azure Portal.
When creating your container in the Azure Portal, be sure to select "Blob" for the access type. It enables public read access for the entire container.
Install the Azure Storage SDK and a UUID library
The Azure Storage SDK is available on Github here. We'll also want the ability to easily generate UUID to be used as our blob IDs (and make sure each URL endpoint we create is unique) - so we'll throw the uuid npm package into the mix.
npm install azure-storage
npm install uuid
Connect to Azure Storage
Connecting to Azure Storage is easy enough with Node. The createBlobService constructor takes the storage account name, a connection key and of course the Blob service endpoint to try and connect to. You can get the storage account name and connection key under "Access keys" in the Azure portal.
We will also be needing the built-in Node module Path to parse file names for the file extension as we create our UUIDs.
'use strict';
const azure = require('azure-storage');
const uuidv1 = require('uuid/v1');
const path = require('path');
const blobService = azure.createBlobService('azuredotjsblob',
'connection_key_string',
'blob_storage_endpoint');
Uploading the selected file with a unique blob ID
// We can construct a UUID for the blob file name and retain the original file extension using 'extName' and 'blobName' below together.
let container = 'imagecontainer',
upload = process.argv[2],
extName = path.extname(upload),
blobName = uuidv1() + extName;
function uploadToBlob() {
blobService.createBlockBlobFromLocalFile(container, blobName, upload, function (error, result) {
if (!error) {
let id = blobService.getUrl(container, blobName);
console.log(`${blobName} successfully uploaded to Azure Blob Storage. URL:`)
return console.log(id);
}
return console.error(error);
})
}
uploadToBlob();
The super cool result:
You can get a complete Gist of the article code here. Happy coding. : )