{"id":2174,"date":"2015-07-21T16:34:28","date_gmt":"2015-07-21T16:34:28","guid":{"rendered":"https:\/\/www.microsoft.com\/reallifecode\/index.php\/2015\/07\/21\/building-ember-apps-on-azure-websites\/"},"modified":"2015-07-21T16:34:28","modified_gmt":"2015-07-21T16:34:28","slug":"building-ember-apps-on-azure-websites","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/ise\/building-ember-apps-on-azure-websites\/","title":{"rendered":"Building Ember Apps on Azure Websites"},"content":{"rendered":"<p>Ember.js is one of the most popular frameworks for the development of ambitious web applications \u2013 developed initially as Sproutcore by Apple, it is used today in the Windows and Xbox One store, the Apple Music desktop app, at Netflix, Twitter\/Vine, LinkedIn, and many other companies working at the bleeding edge of web app development.<\/p>\n<p>An important part of Ember is the powerfl tool chain: A command line interface makes the development, testing and compilation dramatically easier. Since the whole tool chain is driven by Node.js, Azure Web Apps can be used to automatically pull the latest version of a web app from a code repository, compile the app, and deploy to a website.<\/p>\n<p>This case study describes how to deploy Ember Cli apps automatically to Azure Web Apps \u2013 and how we built the small automation tool, <a href=\"https:\/\/github.com\/felixrieseberg\/ember-cli-azure-deploy\">ember-cli-azure-deploy<\/a>. A smaller tutorial <a href=\"http:\/\/www.ember-cli.com\/user-guide\/#azure\">was also made available on the Ember Cli homepage<\/a>.<\/p>\n<h2 id=\"dont-commit-your-compilation\">Don\u2019t Commit your Compilation<\/h2>\n<p>It is a golden rule that one does not commit the compiled output of source code into a code repository. The rational is more than just code sanity \u2013 committing compiled output dramatically increases the size of a repository, makes the commit history confusing, and requires developer-driven compilation before every commit.<\/p>\n<p>In a perfect world, one would simply commit all the source code and instruct Azure Web Apps to automatically compile and deploy the output. While not impossible, this task does require some deeper understanding of the deployment mechanics in Azure Websites \u2013 a task that can be automated.<\/p>\n<h2 id=\"implementation-just-run-this-command\">Implementation: Just Run This Command<\/h2>\n<p>The engine behind Azure Websites, Kudu, is capable of running customized deployment commands. The flow is roughly this: When a new commit is made to the code repository (for instance on GitHub), Azure is notified by the repository via git hook and pulls the latest code. Once copied to the Web App\u2019s machine, a custom set of instructions can be run \u2013 when done, the output is copied to the wwwroot folder of the website.<\/p>\n<p>To successfully compile and run an Ember Web App, we simply need to customize the deployment. At the same time, we also have to ensure that Ember\u2019s deployment command works on Azure Web Apps, which does currently not fully support native modules \u2013 a task that involves running the installation of npm modules in multiple steps, ensuring that the versions of individual modules are compatible with Azure Web Apps, and rerouting stdin\/stdout\/stderr of the actual compilation.<\/p>\n<p>You may have noticed that this requires action in both the code repository as well as on Azure Web Apps \u2013 we have written a small tool named <a href=\"https:\/\/github.com\/felixrieseberg\/ember-cli-azure-deploy\">ember-cli-azure-deploy<\/a> that automates that task both on the developer\u2019s machine as well as on Azure Web App\u2019s servers.<\/p>\n<h3 id=\"orchestrating-the-deployment\">Orchestrating the Deployment<\/h3>\n<p>Let\u2019s take a look at some code, starting with the customized deployment. The deployment is driven by two files: A .deployment file telling Kudu which command to execute and a deploy.sh bash script that contains the actual set of instructions.<\/p>\n<p><strong>.deployment<\/strong><\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>[config]  \n command = bash deploy.sh\n<\/code><\/pre>\n<\/div>\n<p>The deployment bash script can be split up into four parts: First, we set up the environment \u2013 finding the right versions of Node.js and npm, making sure that Bower is installed, and ensuring that path variables are available.<\/p>\n<p><strong>deploy.sh<\/strong><\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code># Setup  \n # -----  \n echo Copy assets to $DEPLOYMENT_TEMP for build  \n tar cf - --exclude=node_modules --exclude=bower_components --exclude=dist --exclude=tmp --exclude=.git . | (cd $DEPLOYMENT_TEMP &amp;&amp; tar xvf - )  \n exitWithMessageOnError \"Failed to create and extract tarball\"  \n\necho Switch to the temp directory  \n cd $DEPLOYMENT_TEMP  \n\nif [[ -d node_modules ]]; then  \n   echo Removing node_modules folder  \n   rm -Rf node_modules  \n   exitWithMessageOnError \"node_modules removal failed\"  \n fi  \n\nSCRIPT_DIR=\"${BASH_SOURCE[0]%\\*}\"  \n SCRIPT_DIR=\"${SCRIPT_DIR%\/*}\"  \n ARTIFACTS=$SCRIPT_DIR\/..\/artifacts  \n KUDU_SYNC_CMD=${KUDU_SYNC_CMD\/\/\"}  \n NODE_EXE=\"$PROGRAMFILES\\nodejs\\0.10.32\\node.exe\"  \n NPM_CMD=\"\"$NODE_EXE\" \"$PROGRAMFILES\\npm\\1.4.28\\node_modules\\npm\\bin\\npm-cli.js\"\"  \n NODE_MODULES_DIR=\"$APPDATA\\npm\\node_modules\"  \n\nEMBER_PATH=\"$NODE_MODULES_DIR\\ember-cli\\bin\\ember\"  \n BOWER_PATH=\"$NODE_MODULES_DIR\\bower\\bin\\bower\"  \n AZUREDEPLOY_PATH=\"$NODE_MODULES_DIR\\ember-cli-azure-deploy\\bin\\azure-deploy\"  \n\nEMBER_CMD=\"\"$NODE_EXE\" \"$EMBER_PATH\"\"  \n BOWER_CMD=\"\"$NODE_EXE\" \"$BOWER_PATH\"\"  \n AZUREDEPLOY_CMD=\"\"$NODE_EXE\" \"$AZUREDEPLOY_PATH\"\"\n<\/code><\/pre>\n<\/div>\n<p>Once that is done, we can move on to install the requirements for Ember Cli. To avoid issues with outdated and native packages, we install certain Socket.io-related packages directly from GitHub, where various issues are already fixed (as opposed to npm, which only has older versions available). We also instruct npm to avoid bin links and optional dependencies: Instead of optimizing for fast build speeds and performance, we want to make the build and installation process as failsafe as possible.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code># Installing dependencies to take load of ember-cli install\n# -----  \n\neval $NPM_CMD install --no-optional --no-bin-links Automattic\/engine.io-client  \n eval $NPM_CMD install --no-optional --no-bin-links socket.io  \n eval $NPM_CMD install --no-optional --no-bin-links testem\n<\/code><\/pre>\n<\/div>\n<p>We can then move on to actually install ember-cli itself, as well as bower and the compilation helper ember-cli-azure-deploy:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>echo Installing ember-cli  \n eval $NPM_CMD install --no-optional --no-bin-links ember-cli  \n exitWithMessageOnError \"ember-cli failed\"  \n\necho Installing ember-cli-azure-deploy  \n eval $NPM_CMD install -g ember-cli-azure-deploy  \n exitWithMessageOnError \"ember-cli-azure-deploy failed\"  \n\nif [[ ! -e \"$BOWER_PATH\" ]]; then  \n   echo Installing bower  \n   eval $NPM_CMD install --global --no-optional --no-bin-links bower  \n   exitWithMessageOnError \"bower failed\"  \n else  \n   echo bower already installed, nothing to do  \n fi\n<\/code><\/pre>\n<\/div>\n<p>If that succeeds, we can move on to clean the package cache, install all the packages required by the web app, and kick off compilation:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>echo Cleaning Cache  \n eval $NPM_CMD cache clean  \n exitWithMessageOnError \"npm cache cleaning failed\"  \n\necho Installing npm modules  \n eval $NPM_CMD install --no-optional --no-bin-links  \n exitWithMessageOnError \"npm install failed\"  \n\necho Installing bower dependencies  \n eval $BOWER_CMD install  \n exitWithMessageOnError \"bower install failed\"  \n\necho Build the dist folder  \n eval $AZUREDEPLOY_CMD build  \n exitWithMessageOnError \"ember-cli-azure-deploy build failed\"  \n\necho Copy web.config to the dist folder  \n cp web.config dist\n<\/code><\/pre>\n<\/div>\n<p>You might notice that we don\u2019t call ember-cli directly, but instead have ember-cli-azure-deploy handle the actual build process. Azure Web Apps does not provide stdin, which is not actually required for a successful ember-cli build, but nevertheless throws an error. To avoid this issue, we simply call ember-cli with stdin explicitly disabled, which Node.js allows us to do:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>cp = exec('node ' + execPath + '\\ember build -prod', {  \n     cwd: currentFolder,  \n     stdout: true,  \n     stdin: false  \n }, function (err, stdout, stderr) {  \n     if (err) {  \n         return console.error(err);  \n     }  \n     console.log(stdout, stderr);  \n }.bind(this));\n<\/code><\/pre>\n<\/div>\n<h2 id=\"running-the-code-deploying-an-app-to-azure-web-apps\">Running the Code: Deploying an App to Azure Web Apps<\/h2>\n<p>Start by ensuring that you have Node.js, npm, Bower, and ember-cli installed on your machine. If you\u2019re only missing the node modules, you can simply install them with the following commands:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>npm install \u2013g bower  \nnpm install -g ember-cli\n<\/code><\/pre>\n<\/div>\n<p>Next, create a new application.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>ember new my-new-app\n<\/code><\/pre>\n<\/div>\n<p>Then, prepare your app for deployment to Azure by installing ember-cli-azure-deploy and letting it prepare your project:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>npm install --save-dev -g ember-cli-azure-deploy\nazure-deploy init\n<\/code><\/pre>\n<\/div>\n<p>Well done! Now, <a href=\"https:\/\/azure.microsoft.com\/en-us\/documentation\/articles\/web-sites-deploy\/\">simply deploy your project to Azure Web Apps \u2013 either using GitHub, VSO, Dropbox, or another method available<\/a>. Once the code is deployed, Azure Web Apps will automatically build and deploy your web app!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>How to deploy Ember CLI apps automatically to Azure Web Apps, and how we built a small automation tool.<\/p>\n","protected":false},"author":21345,"featured_media":984,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[10,16],"tags":[97,167],"class_list":["post-2174","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-azure-app-services","category-devops","tag-azure-web-apps","tag-ember"],"acf":[],"blog_post_summary":"<p>How to deploy Ember CLI apps automatically to Azure Web Apps, and how we built a small automation tool.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2174","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/users\/21345"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/comments?post=2174"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2174\/revisions"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media?parent=2174"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/categories?post=2174"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/tags?post=2174"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}