Search code examples
djangoazureazure-web-app-service

Run management commands on Django server in a Linux hosted App Service in Azure. Anything other than cronjobs?


Please Excuse me if this question has been posted before.I have a linux hosted App Service in Azure running a Django server. I want to run a management command periodically on the server. I am somewhat of an inexperienced person as far as cloud and architechure goes. So please be as elaborate as possible, mentioning the reasoning behind your recomendations, so that I can learn more.

  • Tried using Cronjobs but it was not consistent and I did not have access to logs.

  • Can't use Webjobs since the app service is on a linux machine and webjobs aren't supported on linux machines.

  • Have read that funtions can be used. If so please point me in the right direction on how to setup and connect function to the App service and run command.

  • The app code base is implemented in github and I am using github action for CI/CD Integration.

Attaching below the yaml file generated in Azure portal

name: Build and deploy Python app to Azure Web App - AppName

on:
  push:
    branches:
      - prod
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Set up Python version
        uses: actions/setup-python@v1
        with:
          python-version: '3.11'

      - name: Create and start virtual environment
        run: |
          python -m venv venv
          source venv/bin/activate

      - name: Install dependencies
        run: pip install -r requirements.txt

      # Optional: Add step to run tests here (PyTest, Django test suites, etc.)

      - name: Upload artifact for deployment jobs
        uses: actions/upload-artifact@v2
        with:
          name: python-app
          path: |
            .
            !venv/

  deploy:
    runs-on: ubuntu-latest
    needs: build
    environment:
      name: 'Production'
      url: ${{ webapp-url }}

    steps:
      - name: Download artifact from build job
        uses: actions/download-artifact@v2
        with:
          name: python-app
          path: .

      - name: 'Deploy to Azure Web App'
        uses: azure/webapps-deploy@v2
        id: deploy-to-webapp
        with:
          app-name: 'AppName'
          slot-name: 'Production'
          publish-profile: ${{ <Appservice secret> }}


Solution

  • I deployed one Django app in Azure Web app and then ustilized Azure Functions to run one management command and integrated Azure Functions as API with Azure APIM service and added the APIM service Functions API to my Azure web app to perform the commands, Refer below:-

    I followed the MSDOC for deploying the Python Django web app with PostgreSQL
    to Azure App Service .

    • Change database details in settings .py
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql',
            'NAME': os.environ.get('DBNAME'),
            'HOST': os.environ.get('DBHOST'),
            'USER': os.environ.get('DBUSER'),
            'PASSWORD': os.environ.get('DBPASS'),
            'OPTIONS': {'sslmode': 'require'},
        }
    }
    
    
    
    • set SECRET_KEY and Database details in env before running the application

    Local:
    enter image description here

    enter image description here

    enter image description here

    Work Flow status:

    enter image description here

    • Add the env variable in Configuration and open SSH to perform migration operation.

    enter image description here

    enter image description here

    Now, I created one Azure Function that performs the management commands like below:-

    Run management commands on Azure function:

    • The code below creates a folder with a specified name sent in the HTTP request body
    def  main(req:  func.HttpRequest)  ->  func.HttpResponse:
    
    try:
    
    req_body = req.get_json()
    
    folder_name = req_body.get('folder_name',  'default_folder')
    
      
    
    if  not  folder_name:
    
    return  func.HttpResponse("Folder name is missing in the request body.",  status_code=400)
    
      
    
    os.makedirs(folder_name)
    
    return  func.HttpResponse(f"Folder '{folder_name}' created successfully.",  status_code=200)
    
    except  Exception  as  e:
    
    return  func.HttpResponse(f"Error creating folder: {str(e)}",  status_code=500)
    
    

    enter image description here

    enter image description here

    enter image description here

    enter image description here

    • Select the API created in the web app in API management

    enter image description here