So here is my guide. I hope it will help others!
Steps for launching a new web app under Azure:
0. Login to Azure
Goto Azure portal https://portal.azure.com/ and sign-in using your Microsoft account.
1. Create a resource group:
- Home > create a resource > Resource group
- fill in: subscription(Free Trial), name (something with
_resgrp
), Region (e.g. West Europe)
2. DB:
- Home > create a resource > create Azure Cosmos DB > Azure Cosmos DB for MongoDB
- fill in: subscription(Free Trial), resource group (see above), account name (something with _db), Region (West Europe), [create]
- goto
Home > db account > connection strings
, copy line marked "PRIMARY CONNECTION STRING" and keep it aside.
3. App:
- Home > create a resource > create Web App
- fill in: subscription(Free Trial), resource group (see above), name (will appear in the site url!),
publish: code, run time stack: python 3.9, region: West Europe, plan: Basic B1 ($13/mon), [create]
- Home > our-web-app > configuration > Application settings > Connection strings
click "New Connection strings" and set
MYDB
with the connection string from step 2.
4. Code:
We will use a nice "to-do list" minimalist app published by Prashant Shahi. Thank you Prashant!
from app import app
if __name__ == '__main__':
app.run()
- Create go.sh with the following code. These commands are will setup the environment and then start gunicorn to respond to web requests. Some of these commands are used for debug only.
# azure webapp: called under sh from /opt/startup/startup.sh
set -x
ls -la
pip install -r /home/site/wwwroot/requirements.txt
echo "$(pwd) $(date)"
ps aux
gunicorn --bind=0.0.0.0 --log-level=debug --timeout 600 wsgi:app
edit app.py:
- replace first 3 lines about db connection with: (btw, MYDB comes from steps 3)
CON_STR = os.environ['CUSTOMCONNSTR_MYDB']
client = MongoClient(CON_STR) #Configure the connection to the database
- after app = Flask(name) add these lines for logging:
if __name__ != '__main__':
gunicorn_logger = logging.getLogger('gunicorn.error')
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
- add first line under def about(): #clicking [about] in the app will dump environment vars to the logs)
app.logger.debug('\n'.join([f'{k}={os.environ[k]}' for k in os.environ.keys()]))
5. Ftp:
- Home > our-web-app > Deployment Center > FTPS Ceredentials
- Open FileZilla, top-left icon, [new site]
- copy paste from web to FileZilla: FTPS endpoint into host, user to username, password to password, [connect]
- upload the content (not the parent!) of the folder from step 4 to the remote path /site/wwwroot
6. Launch:
- Home > our-web-app > configuration > General settings > Startup Command
- paste this:
sh -c "cp go.sh go_.sh && . go_.sh"
7. Test:
- Browse to https://[our-web-app].azurewebsites.net
8. Logging / debugging:
az login
# turn on container logging (run once):
az webapp log config --name [our-web-app] --resource-group [our-step1-group] --docker-container-logging filesystem
# tail the logs:
az webapp log tail --name [our-web-app] --resource-group [our-step1-group]
9. Kudu SCM management for the app
(must be logged into Azure for these to work):
- Show file/dir: https://[our-web-app].scm.azurewebsites.net/api/vfs/site/[path]
- Downloads full site: https://[our-web-app].scm.azurewebsites.net/api/zip/site/wwwroot
- Status: https://[our-web-app].scm.azurewebsites.net/Env
- SSH: https://[our-web-app].scm.azurewebsites.net/webssh/host
- Bash: https://[our-web-app].scm.azurewebsites.net/DebugConsole
- More on REST API here: https://github.com/projectkudu/kudu/wiki/REST-API
10. Notes:
I don't recommend on using automatic deployment from GitHub / BitBucket, unless you have Azure's support available. We encountered many difficulties with that.
Any comments are most welcome.