How to deploy a website using CouchDB on Windows Azure

This tutorial shows you how to create a web site and connect it to a CouchDB replica set, all hosted within Windows Azure. To do this, you use Microsoft WebMatrix 2 to create and publish your code to the Windows Azure web site.

Prerequisites

Windows Azure account
CouchDB instance running on one or more nodes; to set one up, click the following link: http://ossonazure.interoperabilitybridges.com/articles/couchdb-installer-for-windows-azure

The Installer creates ;one ;endpoint which is used both for the virtual machines to sync with each other and for the client to connect to the cluster. This endpoint ;is listed in your connectionstrings.json file. You can also use the command-line tools to run the virtual machine endpoint list command to get the external port to the CouchDB cluster. The CouchDB ;endpoint will be the "External Port" mapped to the "Local Port" 5984. You will need this port and the URL to the cluster for the connection strings.

Note: Windows Azure does not use the standard CouchDB port; you need to obtain this from the connectionstrings.json file. For this demo case, this is http://myvm36.cloudapp-preview.net:5991/

To view information about your CouchDB cluster, run Futon, the CouchDB administrative interface. To run Futon, go to this URL in your browser: http://<dns-name>.cloudapp-preview.net:<port>/_utils/

couch-futon

Create a web site

Next, create a web site to host your application. You can do this in the Windows Azure preview management portal by using one of the following methods:

  • Follow this tutorial on how to create and deploy a website.
  • Use the command-line tools to create one.
  • Use an existing web site you have already provisioned.

After your web site is provisioned, download the connectionsettings.json file for the web site. You can import this directly into Microsoft WebMatrix, which then publishes your code to your web site. In WebMatrix, click Open Remote Site.

WebMatrix1

Click Import publish settings and then browse to your downloaded publishsettings.json file. WebMatrix populates the required fields for you. Give your site a local name and you're ready to code.

WebMatrix2

Code the application and deploy

Paste the code from the bottom of this tutorial into your web page. Change the 'host' and 'port' values in the 'options' array to connect to your CouchDB cluster. You can find these values in the publishsettings.json file you downloaded earlier. After you have your code in place, you can publish the page to your web site easily using WebMatrix, or you can use a terminal client. When you navigate to it, you should see the following.

DemoScreenShot

This simple PHP app connects to a CouchDB cluster and uses a CouchSimple class to package and send requests to the database. It populates the database with a couple default entries and uses the getAll() function to retrieve and display the records.

Code

<?php
//Connection parameters to connect to the CouchDB deployment. This data can be found in the connectionstrings.json file.
$options['host'] = "myvm36.cloudapp-preview.net";
$options['port'] = 5991;
// Instantiate the CouchSimple class that will be used to make requests
$couch = new CouchSimple($options);
$connect = 0;
// Try to make a connection
try {
$resp = $couch->send("GET", "/");
$connect = 1;
}
catch (Exception $e) {
echo "Error:".$e->getMessage()." (errcode=".$e->getCode().")n";
exit(1);
}
// If the connection succeeds, put the demo/new data into CouchDB. If present, the 'send' returns "ok":false
if ($connect == 1 ){
// Create a new database "test"
$resp = $couch->send("PUT", "/test");
// Create some new documents in the database test
$resp = $couch->send("PUT", "/test/124", '{"title":"Blackbird", "artist":"The Beatles", "album":"The White Album"}');
$resp = $couch->send("PUT", "/test/125", '{"title":"Purple Haze", "artist":"Jimi Hendrix", "album":"Are You Experienced"}');
// If there is post data add the new song to the database
if ($_POST){
$sName = $_POST['title'];
$sArtist = $_POST['artist'];
$sAlbum = $_POST['album'];
$sID = str_replace(" ", "_", $sName); //Use the title as the ID (converting spaces to '_')
$sSend = array('title' => $sName, 'artist' => $sArtist, 'album' => $sAlbum, );
$sSend = json_encode($sSend);
$resp = $couch->send("PUT", "/test/$sID", $sSend);
}
}
// Function to get all results from the database and write them into the table
function getAll() {
global $options, $couch;
try {
$resp = $couch->send("GET", "/test/_all_docs");
$resp = json_decode($resp, true);
$item = $resp["rows"];
foreach($item as $item){
$item = $item["key"];
$resp = $couch->send("GET", ("/test/" . $item));
$resp = json_decode($resp, true);
echo "<tr><td>" . $resp["title"] . "</td><td>" . $resp["artist"] . "</td><td>" . $resp["album"] . "</td></tr>";
}
} catch (Exception $e) {
echo "Error:".$e->getMessage()." (errcode=".$e->getCode().")n";
exit(1);
}
}
// Class to run the CouchDB requests through
class CouchSimple {
function CouchSimple($options) {
foreach($options AS $key => $value) {
$this->$key = $value;
}
}
function send($method, $url, $post_data = NULL) {
$s = fsockopen($this->host, $this->port, $errno, $errstr);
if(!$s) {
echo "$errno: $errstrn";
return false;
}
$request = "$method $url HTTP/1.0rnHost: $this->hostrn";
if ($this->user) {
$request .= "Authorization: Basic ".base64_encode("$this->user:$this->pass")."rn";
}
if($post_data) {
$request .= "Content-Length: ".strlen($post_data)."rnrn";
$request .= "$post_datarn";
}
else {
$request .= "rn";
}
fwrite($s, $request);
$response = "";
while(!feof($s)) {
$response .= fgets($s);
}
list($this->headers, $this->body) = explode("rnrn", $response);
return $this->body;
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>OSS on Windows Azure - CouchDB with PHP</title>
</head>
<body>
<div width="100%" align="center">
<h1>CouchDB-on-Windows-Azure Music List</h1>
<p>Song list:</p>
<table cellpadding=4 cellspacing=0 border="1" bordercolor="black">
<tr>
<td>Title</td><td>Artist</td><td>Album</td>
</tr>
<?php
//Complete the table with the database contents
getAll();
?>
</table>
<p><hr width=70%></p>
<p>Enter new song:</p>
<form name="add" method="post" action="<?php echo $PHP_SELF;?>">
<table cellpadding=4 cellspacing=0 border="1" bordercolor=black>
<tr><td>Enter a song title: </td><td><input type="text" name="title" /></td></tr>
<tr><td>Enter the artist: </td><td><input type="text" name="artist" /></td></tr>
<tr><td>Enter the album: </td><td><input type="text" name="album" /></td></tr>
<tr><td> ;</td><td><input type="submit" value="Add Song" /></td></tr>
</table>
</form>
</div>
</body>
</html>