Deploying Yeoman generated app in Azure.

Finally I decided to take a plunge into cloud by signing up with Azure. I have been working on SPA application using AngularJS. I decided to try hosting the application in Azure. There are lot materials out there on how to build and deploy SPA into Azure. I am really impressed with the documentation and help available out there to accomplish this task. Since I haven’t written any blog in a year, I thought I will take this opportunity to write a blog about my experience and few things I found along the way.

Build a web application using Yeoman:

I am a lazy programmer so if there are things that make my development easy I will take that route. To get started, I took Yeoman’s help on generating the seed project so that I do not need to worry about the directory structure etc., Yeoman help wire up everything for me. There are ton help on the web, just in case if you haven’t used it. Not to repeat the whole steps, here is one of the site which explains how to get started.Before you go any further, make sure the starter application is working locally by running

grunt serve

If the starter page doesn’t show up then you have problems with the yeoman setup and fix the problem before you proceed.

Source code repository:

Next is source code repository. I decided to use bit bucket for this task. it is free and for me it serve the purpose incredibly. I highly recommend to check it out, in case if you haven’t heard or use it. It has excellent tutorials on how to add an existing project and create new repo.

Hosting:

Next stop is Azure. Create your account and login into Azure portal.Here is a good video on how to add a new web app in Azure from Azure Fridays. Follow the video, you will be able to create a new web application in seconds.

Now that we have all the infrastructure and code ready to go, lets take about how do we go about deploying. Deploying is little tricky at least for me because I was using Web Storm for my development (not visual studio). Here are few things I had to do to make this process automated.

Modify deployment Script:

When you create SPA you will end up using ‘npm’ and ‘bower’ packages. We need to make sure, when we deploy all those packages will be installed in the azure. This is the first hurdle. Azure uses Kudu engine for deployment. So we need to add two files to our project to enable azure deployment and they are

.deployment

deploy.cmd

in the root directory of the project. Even for that there is help. Follow this link and it will help you create those files. The script, it generated will add all the npm packages (as of this writing) but not bower, so you need to modify the deploy.cmd to add bower packages during the deployment. Open deploy.cmd and add the following lines after “::3 npm install” if condition.

:: 4. Select node version
IF EXIST "%DEPLOYMENT_TARGET%\bower.json" (
  pushd "%DEPLOYMENT_TARGET%"
  call bower install
  IF !ERRORLEVEL! NEQ 0 goto error
  popd
)

This will help Azure deployment to add both npm and bower packages in the web site.

You will not deploy the whole file structure Yeoman created as the web site since it has lot of things they are intended for development like testing. You do not want to distribute that code to production and also you will want do all the goodies like linting, minification and uglyfying and trim down the code to small distribution package. Fortunately for us, grunt helps us with this. To do that, we run the following in cmd line.

grunt build

This will create a new directory ‘dist‘ in the directory structure this is what we need to deploy to azure. Couple of ways we can deploy this and I went the the route of creating a branch for deployment and setup continuous deployment from that branch. But remember since Bower packages will not be installed by default we need make sure bower install runs along with deployment that means we need modified deployment file and also the json files distributed along with the ‘dist’ directory. So I added four highlighted statements to the copy task before deploying the dist subtree to branch.

// Copies remaining files to places other tasks can use
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: '<%= yeoman.app %>',
          dest: '<%= yeoman.dist %>',
          src: [
            '*.{ico,png,txt}',
            '.htaccess',
            '*.html',
            'images/{,*/}*.{webp}',
            'styles/fonts/{,*/}*.*'
          ],
        }, {
          expand: true,
          cwd: '.tmp/images',
          dest: '<%= yeoman.dist %>/images',
          src: ['generated/*']
        }, {
          expand: true,
          cwd: 'bower_components/bootstrap/dist',
          src: 'fonts/*',
          dest: '<%= yeoman.dist %>'
        },
          { cwd: '', src: "deploy.cmd", dest: 'dist/deploy.cmd' },
          { cwd: '', src: ".deployment", dest: 'dist/.deployment' },
          { cwd: '', src: "bower.json", dest: 'dist/bower.json' },
          { cwd: '', src: "package.json", dest: 'dist/package.json' }
        ]
      },
      styles: {
        expand: true,
        cwd: '<%= yeoman.app %>/styles',
        dest: '.tmp/styles/',
        src: '{,*/}*.css'
      }
    },

That is it, with all these steps now I can easily build and deploy to azure easily.

If you think there is a better way to do this, I would love to hear from you.


		
Advertisements