pip install for Azure web app with custom deploy script

44 views Asked by At

I'm pushing a Flask web app to azure from a local git repo. The app has a .deployment file that points to scripts/deploy.sh that runs an npm run build action and copies the generated build to the app's static folder.

The azure docs suggest that placing requirements.txt at the top of the repo will automatically run pip install -r requirements.txt. I can't see any evidence that this command is running and I wonder if the custom deployment script overrides it. If I explicitly call this command in the file, I see:

scripts/deploy.sh: line 20: pip: command not found

This seems to be because the container built at deployment has its own virtual environment. How do I convince the deployment process to run pip install in the virtual environment?

Application log after build and launch:

2024-03-27T04:38:07.838468802Z: [INFO]  Updated PYTHONPATH to '/opt/startup/app_logs:/tmp/8dc4df81676606a/antenv/lib/python3.10/site-packages'
2024-03-27T04:38:07.914410500Z: [ERROR]  Traceback (most recent call last):
2024-03-27T04:38:07.915612203Z: [ERROR]    File "/tmp/8dc4df81676606a/backend/app.py", line 6, in <module>
2024-03-27T04:38:07.916790406Z: [ERROR]      from dotenv import load_dotenv
2024-03-27T04:38:07.917807108Z: [ERROR]  ModuleNotFoundError: No module named 'dotenv'Ending Log Tail of existing logs ---Starting Live Log Stream ---

EDIT: specifying python3-dotenv instead of python-dotenv did not resolve the issue. Neither did setting SCM_DO_BUILD_DURING_DEPLOYMENT.

1

There are 1 answers

1
Pravallika KV On

Activate the virtual environment by adding below commands in the deployment script deploy.sh:

source <path_to_virtualenv/bin/activate> (i.e.,source antenv/bin/activate)

pip install -r <path_of_requirements.txt>

I have created a flask application and used below code:

from  dotenv  import  load_dotenv
load_dotenv()
  • Created virtual environment(env) to install the packages using the commands:
py -m venv env
.\env\Scripts\activate

Folder Structure:

│   .gitignore
│   app.py
│   CHANGELOG.md
│   CONTRIBUTING.md
│   LICENSE.md
│   README.md
│   requirements.txt
├───.github
├───env
├───static
└───templates
  • Deployed the application to Azure App Service using Local GIT.
(env) C:\Users\uname\flaskapp>git push azure main:master
Enumerating objects: 125, done.
Counting objects: 100% (125/125), done.
Delta compression using up to 8 threads
Compressing objects: 100% (63/63), done.
Writing objects: 100% (125/125), 785.30 KiB | 39.26 MiB/s, done.
Total 125 (delta 56), reused 125 (delta 56), pack-reused 0 (from 0)
remote: Resolving deltas: 100% (56/56), done.
remote: Deploy Async
remote: Updating branch 'master'.
remote: Updating submodules.
remote: Preparing deployment for commit id '223b3cf48e'.
remote: PreDeployment: context.CleanOutputPath False
remote: PreDeployment: context.OutputPath /home/site/wwwroot
remote: Repository path is /home/site/repository
remote: Running oryx build...
remote: Operation performed by Microsoft Oryx, https://github.com/Microsoft/Oryx
remote: You can report issues at https://github.com/Microsoft/Oryx/issues
remote:
remote: Oryx Version: 0.2.20230508.1, Commit: 7fe2bf39b357dd68572b438a85ca50b5ecfb4592, ReleaseTagName: 20230508.1
remote:
remote: Build Operation ID: 006694baf2ca5e2b
remote: Repository Commit : 223b3cf48eb78f055f670202ead044e98ab0360a
remote: OS Type           : bullseye
remote: Image Type        : githubactions
remote:
remote: Detecting platforms...
remote: Detected following platforms:
remote:   python: 3.11.8
remote: Version '3.11.8' of platform 'python' is not installed. Generating script to install it...
remote:
remote: Using intermediate directory '/tmp/8dc4efcb326576d'.
remote:
remote: Copying files to the intermediate directory...
remote: Done in 0 sec(s).
remote:
remote: Source directory     : /tmp/8dc4efcb326576d
remote: Destination directory: /home/site/wwwroot
remote: Downloading and extracting 'python' version '3.11.8' to '/tmp/oryx/platforms/python/3.11.8'...
remote: Detected image debian flavor: bullseye.
remote: Downloaded in 2 sec(s).
remote: Verifying checksum...
remote: Extracting contents...
remote: performing sha512 checksum for: python...
remote: Done in 6 sec(s).
remote:
remote: image detector file exists, platform is python..
remote: OS detector file exists, OS is bullseye..
remote: Python Version: /tmp/oryx/platforms/python/3.11.8/bin/python3.11
remote: Creating directory for command manifest file if it does not exist
remote: Removing existing manifest file
remote: Python Virtual Environment: antenv
remote: Creating virtual environment...
remote: Activating virtual environment...
remote: Running pip install...
remote: [07:57:35+0000] Collecting Flask==2.2.2 (from -r requirements.txt (line 1))
remote: [07:57:35+0000]   Downloading Flask-2.2.2-py3-none-any.whl.metadata (3.9 kB)
remote: [07:57:35+0000] Collecting gunicorn (from -r requirements.txt (line 2))
remote: [07:57:35+0000]   Downloading gunicorn-21.2.0-py3-none-any.whl.metadata (4.1 kB)
remote: [07:57:35+0000] Collecting Werkzeug==2.2.2 (from -r requirements.txt (line 3))
remote: [07:57:35+0000]   Downloading Werkzeug-2.2.2-py3-none-any.whl.metadata (4.4 kB)
remote: [07:57:35+0000] Collecting Jinja2>=3.0 (from Flask==2.2.2->-r requirements.txt (line 1))
remote: [07:57:35+0000]   Downloading Jinja2-3.1.3-py3-none-any.whl.metadata (3.3 kB)
remote: [07:57:35+0000] Collecting itsdangerous>=2.0 (from Flask==2.2.2->-r requirements.txt (line 1))
remote: [07:57:35+0000]   Downloading itsdangerous-2.1.2-py3-none-any.whl.metadata (2.9 kB)
remote: [07:57:35+0000] Collecting click>=8.0 (from Flask==2.2.2->-r requirements.txt (line 1))
remote: [07:57:35+0000]   Downloading click-8.1.7-py3-none-any.whl.metadata (3.0 kB)
remote: [07:57:35+0000] Collecting MarkupSafe>=2.1.1 (from Werkzeug==2.2.2->-r requirements.txt (line 3))
remote: [07:57:35+0000]   Downloading MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.0 kB)
remote: [07:57:35+0000] Collecting packaging (from gunicorn->-r requirements.txt (line 2))
remote: [07:57:35+0000]   Downloading packaging-24.0-py3-none-any.whl.metadata (3.2 kB)
remote: [07:57:35+0000] Downloading Flask-2.2.2-py3-none-any.whl (101 kB)
remote: [07:57:35+0000]    ΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöü 101.5/101.5 kB 28.3 MB/s eta 0:00:00
remote: [07:57:35+0000] Downloading Werkzeug-2.2.2-py3-none-any.whl (232 kB)
remote: [07:57:35+0000]    ΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöü 232.7/232.7 kB 75.6 MB/s eta 0:00:00
remote: [07:57:35+0000] Downloading gunicorn-21.2.0-py3-none-any.whl (80 kB)
remote: [07:57:35+0000]    ━━━━━━━━━━━━━━━━━━━━��━━━━━━━━━━━━━━━━━━━ 80.2/80.2 kB 35.6 MB/s eta 0:00:00
remote: [07:57:35+0000] Downloading click-8.1.7-py3-none-any.whl (97 kB)
remote: [07:57:35+0000]    ΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöü 97.9/97.9 kB 41.5 MB/s eta 0:00:00
remote: [07:57:35+0000] Downloading itsdangerous-2.1.2-py3-none-any.whl (15 kB)
remote: [07:57:35+0000] Downloading Jinja2-3.1.3-py3-none-any.whl (133 kB)
remote: [07:57:35+0000]    ΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöü 133.2/133.2 kB 51.0 MB/s eta 0:00:00
remote: [07:57:35+0000] Downloading MarkupSafe-2.1.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (28 kB)
remote: [07:57:35+0000] Downloading packaging-24.0-py3-none-any.whl (53 kB)
remote: [07:57:35+0000]    ΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöüΓöü 53.5/53.5 kB 17.6 MB/s eta 0:00:00
remote: [07:57:35+0000] Installing collected packages: packaging, MarkupSafe, itsdangerous, click, Werkzeug, Jinja2, gunicorn, Flask
remote: [07:57:36+0000] Successfully installed Flask-2.2.2 Jinja2-3.1.3 MarkupSafe-2.1.5 Werkzeug-2.2.2 click-8.1.7 gunicorn-21.2.0 itsdangerous-2.1.2 packaging-24.0
remote: Not a vso image, so not writing build commands
remote: Preparing output...
remote:
remote: Copying files to destination directory '/tmp/_preCompressedDestinationDir'...
remote: Done in 0 sec(s).
remote: Compressing content of directory '/tmp/_preCompressedDestinationDir'...
remote: Copied the compressed output to '/home/site/wwwroot'
remote:
remote: Removing existing manifest file
remote: Creating a manifest file...
remote: Manifest file created.
remote: Copying .ostype to manifest output directory.
remote:
remote: Done in 13 sec(s).
remote: Running post deployment command(s)...
remote:
remote: Generating summary of Oryx build
remote: Parsing the build logs
remote: Found 0 issue(s)
remote:
remote: Build Summary :
remote: ===============
remote: Errors (0)
remote: Warnings (0)
remote:
remote: Triggering recycle (preview mode disabled).
remote: Deployment successful. deployer =  deploymentPath =
remote: Deployment Logs : 'https://kpflaskapp.scm.azurewebsites.net/newui/jsonviewer?view_url=/api/deployments/223b3cf48eb78f055f670202ead044e98ab0360a/log'
To https://kpflaskapp.scm.azurewebsites.net:443/kpflaskapp.git
 * [new branch]      main -> master

App Service Logs:

2024-03-28T09:30:53.366091831Z Documentation: http://aka.ms/webapp-linux
2024-03-28T09:30:53.366095719Z Python 3.11.7
2024-03-28T09:30:53.366099887Z Note: Any data outside '/home' is not persisted
2024-03-28T09:30:53.857082966Z Starting OpenBSD Secure Shell server: sshd.
2024-03-28T09:30:53.876787582Z App Command Line not configured, will attempt auto-detect
2024-03-28T09:30:53.876977196Z Launching oryx with: create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite
2024-03-28T09:30:53.936844682Z Found build manifest file at '/home/site/wwwroot/oryx-manifest.toml'. Deserializing it...
2024-03-28T09:30:53.939444394Z Build Operation ID: 006694baf2ca5e2b
2024-03-28T09:30:53.940956897Z Output is compressed. Extracting it...
2024-03-28T09:30:53.940981173Z Oryx Version: 0.2.20240127.1, Commit: 4b7f2dffcc69c214f9806d67a85ec8926e2393e1, ReleaseTagName: 20240127.1
2024-03-28T09:30:53.942382458Z Extracting '/home/site/wwwroot/output.tar.gz' to directory '/tmp/8dc4efcb326576d'...
2024-03-28T09:30:54.520441476Z App path is set to '/tmp/8dc4efcb326576d'
2024-03-28T09:30:54.553473156Z Detected an app based on Flask
2024-03-28T09:30:54.553544960Z Generating `gunicorn` command for 'app:app'
2024-03-28T09:30:54.555519014Z Writing output script to '/opt/startup/startup.sh'
2024-03-28T09:30:54.584079610Z Using packages from virtual environment antenv located at /tmp/8dc4efcb326576d/antenv.
2024-03-28T09:30:54.584102352Z Updated PYTHONPATH to '/opt/startup/app_logs:/tmp/8dc4efcb326576d/antenv/lib/python3.11/site-packages'
2024-03-28T09:30:54.842338343Z [2024-03-28 09:30:54 +0000] [73] [INFO] Starting gunicorn 21.2.0
2024-03-28T09:30:54.854736676Z [2024-03-28 09:30:54 +0000] [73] [INFO] Listening at: http://0.0.0.0:8000 (73)
2024-03-28T09:30:54.854796869Z [2024-03-28 09:30:54 +0000] [73] [INFO] Using worker: sync
2024-03-28T09:30:54.858336021Z [2024-03-28 09:30:54 +0000] [76] [INFO] Booting worker with pid: 76
2024-03-28T09:30:55.499981679Z 172.16.0.1 - - [28/Mar/2024:09:30:55 +0000] "GET /robots933456.txt HTTP/1.1" 404 207 "-" "HealthCheck/1.0"
2024-03-28T09:30:56.121392969Z Request for index page received
2024-03-28T09:30:56.121424398Z 172.16.0.1 - - [28/Mar/2024:09:30:56 +0000] "GET / HTTP/1.1" 200 1469 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0"
2024-03-28T09:30:56.543593372Z 172.16.0.1 - - [28/Mar/2024:09:30:56 +0000] "GET /static/bootstrap/css/bootstrap.min.css HTTP/1.1" 200 0 "https://kpflaskapp.azurewebsites.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0"
2024-03-28T09:30:56.547191577Z 172.16.0.1 - - [28/Mar/2024:09:30:56 +0000] "GET /static/images/azure-icon.svg HTTP/1.1" 200 0 "https://kpflaskapp.azurewebsites.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0"
2024-03-28T09:30:57.350264488Z Request for index page received
2024-03-28T09:30:57.350299212Z 172.16.0.1 - - [28/Mar/2024:09:30:57 +0000] "GET / HTTP/1.1" 200 1469 "-" "AlwaysOn"
2024-03-28T09:30:57.896618043Z 172.16.0.1 - - [28/Mar/2024:09:30:57 +0000] "GET /static/favicon.ico HTTP/1.1" 200 0 "https://kpflaskapp.azurewebsites.net/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0 Safari/537.36 Edg/123.0.0.0"
2024-03-28T09:31:07.346168021Z Request for index page received2024-03-28T09:31:07.346213867Z 172.16.0.1 - - [28/Mar/2024:09:31:07 +0000] "GET / HTTP/1.1" 200 1469 "-" "AlwaysOn"

Response:

enter image description here