python-3.xazure-pipelinesgunicorndaemoncicd

How to deploy a Python controller via Azure devops pipeline


I am working on creating a basic azure pipeline which is expected to do following tasks:

  1. Pull Python code from github
  2. Run the python controller via gunicorn

deployment server is a Linux VM in private cloud (doesn't belong to azure) and agent is also running on the same server.

trigger:
  branches:
    include:
      - master
      - refs/tags/*
      - feature*

stages:
  - stage: Deploy
    condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/feature')))
    jobs:
      - job: 'RunDeploymentCommandJob'
        displayName: Deploying job
        pool:
          name: Agent-Pool
        steps:
          - script: |
              # Install dependencies if needed
              pip3 install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host=files.pythonhosted.org --no-cache-dir --user -r requirements.txt
              # Run the Python code
              /usr/local/bin/gunicorn -w 1 -b 0.0.0.0:8081 controller:app --daemon
            displayName: 'Run Python Code'

When Above pipeline completes it's execution, I don't find any gunicorn process running on server. Seems like dameon is getting stopped as soon as pipeline execution completes.

Without --daemon, I can see in pipeline logs that controller is successfully up and listening on 8081 but pipeline doesn't proceed to completion and keep waiting as gunicorn is running in foreground.

Could anyone suggest how this can be handled or if there's a better approach to automate the deployment of python app exposing REST APIs.

Thanks


Solution

  • When Above pipeline completes it's execution, I don't find any gunicorn process running on server. Seems like dameon is getting stopped as soon as pipeline execution completes.

    The cause of the issue could be that Finalize job in Azure Pipeline will clean the process after running the Pipeline tasks.

    For example:

    enter image description here

    When the pipeline completes, the gunicorn process will be cleaned up on sever.

    To avoid the Finalize job clean the process, you can set the variable: process.clean: false in your pipeline.

    For example:

    trigger:
      branches:
        include:
          - master
          - refs/tags/*
          - feature*
    
    stages:
      - stage: Deploy
        variables:
          process.clean: false
        condition: and(succeeded(), or(eq(variables['Build.SourceBranch'], 'refs/heads/master'), startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/feature')))
        jobs:
          - job: 'RunDeploymentCommandJob'
            displayName: Deploying job
            pool:
              name: Agent-Pool
            steps:
              - script: |
                  # Install dependencies if needed
                  pip3 install --trusted-host pypi.org --trusted-host pypi.python.org --trusted-host=files.pythonhosted.org --no-cache-dir --user -r requirements.txt
                  # Run the Python code
                  /usr/local/bin/gunicorn -w 1 -b 0.0.0.0:8081 controller:app 
                displayName: 'Run Python Code'
    

    Then you can remove the --daemon and check if the gunicorn process can keep active on server.