Custom Deployment to Azure Websites

2024/11/13 9:26:56

I recently started using Gulp.js to package all my CSS and JavaScript into single files, which I then include in my web app. My web app is written in Python (using Flask).

I obviously don't want to track the Gulp output CSS and JS files using git (since they're build output files).

I deploy my website to Azure Websites using push to deploy. That is, I simply run git push azure master and Azure automatically figures out that I'm using Python, sets up virtualenv, installs pip dependencies and so on. This article describes how to set this up.

This process works great, but now that I've started using Gulp, I want to ensure that the concatenated JavaScript and CSS files are also produced on the server side whenever I deploy the website.

Moreover, in the future, I would like to have Azure run all the tests upon deployment, and only successfully deploy if they all pass.

Sadly, I have yet to find a satisfying solution for this workflow, since I cannot add custom steps to Azure's automatic deployment process.

I have tried writing a custom deployment script using Kudu (as suggested by this blog post), but doing so disables all the automatic steps Azure normally does; running azure site deploymentscript --python only generates a very basic Kudu deployment file which doesn't handle reading in the web.config file, setting up virtualenv or installing the dependencies. I found no documentation regarding how to do this myself; I have use the default, automatic Azure deployment script (which gets generated server-side when I push the code, so I cannot access it myself) because otherwise stuff like virtualenv and pip dependencies aren't handled.

Is there any workaround available so that I may customize my deployment script (e.g. to run Gulp) while still correctly deploying Flask?

Answer

Since Kudu is open source and available on GitHub, I have brought up this problem in its issue tracker (link, for anyone interested). The code owner vas very helpful and pointed me towards a solution.

  1. Access the site's Kudu Services at: yourwebsite.scm.azurewebsites.net.
  2. Click Tools > Download Deployment Script and get the deployment script Azure generated for your code (this isn't limited to Flask apps).
  3. (Optional) The script is a Windows batch script. I ported it to Bash, because I'm more familiar with it and Azure Websites supports it as well.
  4. Add custom stuff to your liking: build stuff using Gulp/Grunt, run tests and fail the deployment (exiting with nonzero error code) if any fail, etc. You should also remember to first check whether stuff like Gulp/Grunt is installed using npm and the appropriate package.json file.
    • note that you should only mark the deployment as failed before KuduSync has a chance to copy your new files from the repository, since otherwise they'll end up in your web root folder even though e.g. your tests have failed.

Here's the fragment of my code handling Gulp.js, for anyone who's interested. Look at the script generated by azure site deploymentscript --node for examples on how to select the correct Node and npm versions:

selectNodeVersion
echo "Invoking \"$NPM_CMD install\"..."
eval $NPM_CMD install
exitWithMessageOnError "Could not run 'npm install'.  Do you have the necessary privileges?"
echo "Finished npm install."# The path doesn't seem to get set OK.  Use this hack to run gulp.
GULP="node_modules/gulp/bin/gulp.js"echo "Running gulp..."
"$GULP" production
exitWithMessageOnError "Could not run 'gulp'.  Did 'npm install' run OK?"
echo "Finished gulp."

Don't forget to actually add a package.json file containing all the necessary Gulp dependencies to your project. Azure provides Node.js (and npm) but not Gulp.js. Hope this helps!

P.S.: Do note that this whole process is a bit hacky and that the completely correct way to do this is by using a continuous integration agent.

https://en.xdnf.cn/q/72178.html

Related Q&A

Python - Gspread Request Error 401

Im currently making a Discord-bot that connects to a Google-spreadsheet (gspread). But after Ive been running it for a while it starts to hand out errors and it cant connect to my gspread anymore (unle…

paramiko server mode port forwarding

I need to implement a ssh server using paramiko that only handles -R port forwarding requests like this:ssh -N -T -R 40005:destination_host:22 [email protected]So far from what i understand ill have to…

Pandas dataframe.hist() change title size on subplot?

I am manipulating DataFrame using pandas, Python. My data is 10000(rows) X 20(columns) and I am visualizing it, like this.df.hist(figsize=(150,150))However, if I make figsize bigger, each of subplots t…

Regex match back to a period or start of string

Id like to match a word, then get everything before it up to the first occurance of a period or the start of the string. For example, given this string and searching for the word "regex":s = …

Finding differences between strings

I have the following function that gets a source and a modified strings, and bolds the changed words in it.def appendBoldChanges(s1, s2):"Adds <b></b> tags to words that are changed&qu…

Python pandas: select 2nd smallest value in groupby

I have an example DataFrame like the following:import pandas as pd import numpy as np df = pd.DataFrame({ID:[1,2,2,2,3,3,], date:array([2000-01-01,2002-01-01,2010-01-01,2003-01-01,2004-01-01,2008-01-01…

How to disable SSL3 and weak ciphers with cherrypy builtin ssl module (python 3)

I have configured Cherrypy 3.8.0 with Python 3 to use SSL/TLS. However, I want to disable SSL3 to avoid POODLE. I searched through the documentation but I am unsure on how to implement it.I am using th…

cleaning big data using python

I have to clean a input data file in python. Due to typo error, the datafield may have strings instead of numbers. I would like to identify all fields which are a string and fill these with NaN using p…

Using the Python shell in Vi mode on Windows

I know that you can use the Python shell in Vi mode on Unix-like operating systems. For example, I have this line in my ~/.inputrc:set editing-mode viThis lets me use Vi-style editing inside the Python…

Calculate residual deviance from scikit-learn logistic regression model

Is there any way to calculate residual deviance of a scikit-learn logistic regression model? This is a standard output from R model summaries, but I couldnt find it any of sklearns documentation.