Reputation: 103
I want to deploy a Django DRF application to a azure App Service using artifacts (zip deployment) the artifact gets sucessfully uploaded from azure devops but the execution of the container fails since not all required packages are installed.
Since my python packages are managed with pipenv I use a custom startup.sh script to start my App Service the file looks like this:
python -m pip install --upgrade pip
pip install pipenv
pipenv install
pipenv run python manage.py migrate
pipenv run gunicorn --workers 2 --threads 4 --timeout 60 --access-logfile \
'-' --error-logfile '-' --bind=0.0.0.0:8000 \
--chdir=/home/site/wwwroot kez_backend.wsgi
and I set it in my CD pipeline like this:
but when I look at the logs of my App service the startup.sh script is not used and a custom one is create by oryx. Since oryx also creates a virtualenviroment and can't handle Pipfiles dependencys are missing.
Application Logs:
2024-10-23T22:34:29.046573859Z _____
2024-10-23T22:34:29.046642461Z / _ \ __________ _________ ____
2024-10-23T22:34:29.046646861Z / /_\ \\___ / | \_ __ \_/ __ \
2024-10-23T22:34:29.046650061Z / | \/ /| | /| | \/\ ___/
2024-10-23T22:34:29.046653661Z \____|__ /_____ \____/ |__| \___ >
2024-10-23T22:34:29.046656961Z \/ \/ \/
2024-10-23T22:34:29.046659861Z A P P S E R V I C E O N L I N U X
2024-10-23T22:34:29.046662861Z
2024-10-23T22:34:29.046665461Z Documentation: http://aka.ms/webapp-linux
2024-10-23T22:34:29.046668361Z Python 3.12.2
2024-10-23T22:34:29.046671161Z Note: Any data outside '/home' is not persisted
2024-10-23T22:34:33.941422531Z Starting OpenBSD Secure Shell server: sshd.
2024-10-23T22:34:33.970001621Z WEBSITES_INCLUDE_CLOUD_CERTS is not set to true.
2024-10-23T22:34:34.144228608Z App Command Line not configured, will attempt auto-detect
2024-10-23T22:34:34.154261080Z Launching oryx with: create-script -appPath /home/site/wwwroot -output /opt/startup/startup.sh -virtualEnvName antenv -defaultApp /opt/defaultsite
2024-10-23T22:34:34.213399194Z Found build manifest file at '/home/site/wwwroot/oryx-manifest.toml'. Deserializing it...
2024-10-23T22:34:34.243405908Z Output is compressed. Extracting it...
2024-10-23T22:34:34.243463509Z Build Operation ID: 35199fbeb863ba4e
2024-10-23T22:34:34.243468309Z Oryx Version: 0.2.20240501.1, Commit: f83f88d3cfb8bb6d3e2765e1dcd218eb0814a095, ReleaseTagName: 20240501.1
2024-10-23T22:34:34.273725828Z Extracting '/home/site/wwwroot/output.tar.gz' to directory '/tmp/8dcf3b1f033e19d'...
2024-10-23T22:34:37.850244587Z App path is set to '/tmp/8dcf3b1f033e19d'
2024-10-23T22:34:37.852137716Z Detected an app based on Django
2024-10-23T22:34:37.852158817Z Generating `gunicorn` command for 'kez_backend.wsgi'
2024-10-23T22:34:38.604526825Z Writing output script to '/opt/startup/startup.sh'
2024-10-23T22:34:38.776948231Z Using packages from virtual environment antenv located at /tmp/8dcf3b1f033e19d/antenv.
2024-10-23T22:34:38.776986631Z Updated PYTHONPATH to '/opt/startup/app_logs:/tmp/8dcf3b1f033e19d/antenv/lib/python3.12/site-packages'
2024-10-23T22:34:40.098806785Z [2024-10-23 22:34:40 +0000] [69] [INFO] Starting gunicorn 22.0.0
2024-10-23T22:34:40.166107042Z [2024-10-23 22:34:40 +0000] [69] [INFO] Listening at: http://0.0.0.0:8000 (69)
2024-10-23T22:34:40.166653651Z [2024-10-23 22:34:40 +0000] [69] [INFO] Using worker: sync
2024-10-23T22:34:40.195198099Z [2024-10-23 22:34:40 +0000] [72] [INFO] Booting worker with pid: 72
2024-10-23T22:34:40.255421245Z [2024-10-23 22:34:40 +0000] [72] [ERROR] Exception in worker process
2024-10-23T22:34:40.255452846Z Traceback (most recent call last):
2024-10-23T22:34:40.255457646Z File "/opt/python/3.12.2/lib/python3.12/site-packages/gunicorn/arbiter.py", line 609, in spawn_worker
2024-10-23T22:34:40.255479846Z worker.init_process()
2024-10-23T22:34:40.255483646Z File "/opt/python/3.12.2/lib/python3.12/site-packages/gunicorn/workers/base.py", line 134, in init_process
2024-10-23T22:34:40.255487046Z self.load_wsgi()
2024-10-23T22:34:40.255490246Z File "/opt/python/3.12.2/lib/python3.12/site-packages/gunicorn/workers/base.py", line 146, in load_wsgi
2024-10-23T22:34:40.255493646Z self.wsgi = self.app.wsgi()
2024-10-23T22:34:40.255496746Z ^^^^^^^^^^^^^^^
2024-10-23T22:34:40.255499946Z File "/opt/python/3.12.2/lib/python3.12/site-packages/gunicorn/app/base.py", line 67, in wsgi
2024-10-23T22:34:40.255503546Z self.callable = self.load()
2024-10-23T22:34:40.255506747Z ^^^^^^^^^^^
2024-10-23T22:34:40.255509947Z File "/opt/python/3.12.2/lib/python3.12/site-packages/gunicorn/app/wsgiapp.py", line 58, in load
2024-10-23T22:34:40.255513247Z return self.load_wsgiapp()
2024-10-23T22:34:40.255516447Z ^^^^^^^^^^^^^^^^^^^
2024-10-23T22:34:40.255519647Z File "/opt/python/3.12.2/lib/python3.12/site-packages/gunicorn/app/wsgiapp.py", line 48, in load_wsgiapp
2024-10-23T22:34:40.255522947Z return util.import_app(self.app_uri)
2024-10-23T22:34:40.255526147Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-23T22:34:40.255529547Z File "/opt/python/3.12.2/lib/python3.12/site-packages/gunicorn/util.py", line 371, in import_app
2024-10-23T22:34:40.255532947Z mod = importlib.import_module(module)
2024-10-23T22:34:40.255536247Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-23T22:34:40.255539447Z File "/opt/python/3.12.2/lib/python3.12/importlib/__init__.py", line 90, in import_module
2024-10-23T22:34:40.255542747Z return _bootstrap._gcd_import(name[level:], package, level)
2024-10-23T22:34:40.255557847Z ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2024-10-23T22:34:40.255561047Z File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
2024-10-23T22:34:40.255565047Z File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
2024-10-23T22:34:40.255629648Z File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
2024-10-23T22:34:40.255633249Z File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
2024-10-23T22:34:40.255639049Z File "<frozen importlib._bootstrap_external>", line 995, in exec_module
2024-10-23T22:34:40.255642349Z File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
2024-10-23T22:34:40.255645749Z File "/tmp/8dcf3b1f033e19d/kez_backend/wsgi.py", line 11, in <module>
2024-10-23T22:34:40.255649249Z from decouple import config
2024-10-23T22:34:40.255652449Z ModuleNotFoundError: No module named 'decouple'
2024-10-23T22:34:40.265307900Z [2024-10-23 22:34:40 +0000] [72] [INFO] Worker exiting (pid: 72)
2024-10-23T22:34:40.658926083Z [2024-10-23 22:34:40 +0000] [69] [ERROR] Worker (pid:72) exited with code 3
2024-10-23T22:34:40.667999326Z [2024-10-23 22:34:40 +0000] [69] [ERROR] Shutting down: Master
2024-10-23T22:34:40.669035242Z [2024-10-23 22:34:40 +0000] [69] [ERROR] Reason: Worker failed to boot.
Upvotes: 0
Views: 268
Reputation: 3413
I tried that using the env variables as described in the oryx documentation but it still gave me the same outcome
Initially, check the custom startup.sh
script is included in the artifact that you deploy to the App Service. This file should be located in the root directory of the project.
To tell the App Service to run the startup.sh
script at startup. Navigate to App Service dashboard, go to Configuration
startup.sh
script located at the root of the app directory adjust the path if the script is elsewhere.startup.sh:
#!/bin/bash
# Exit immediately if a command exits with a non-zero status
set -e
# Change to the app's directory (optional, depending on your project structure)
cd /home/site/wwwroot
# Install required dependencies
pip install -r requirements.txt
# Alternatively, install from Pipfile using pipenv (if your project uses Pipfile)
# pip install pipenv
# pipenv install --ignore-pipfile
# Install any missing packages explicitly
pip install python-decouple
# Run the application using Gunicorn with binding to port 8000
gunicorn --bind=0.0.0.0:8000 --timeout 600 myapp.wsgi:application
2024-10-23T22:34:40.255652449Z ModuleNotFoundError: No module named 'decouple'
decouple
package hasn’t been installed correctly in the environment. Add decouple
to the Pipfile
or requirements.txt
, and confirm it is being picked up in the deployment package.Check this logs cover installing dependencies, launching the application, and serving it with Gunicorn.
2024-10-26T12:00:00.000000Z INFO - Starting container for site
2024-10-26T12:00:00.500000Z INFO - Container initialized successfully
2024-10-26T12:00:00.600000Z INFO - Executing command: ./startup.sh
2024-10-26T12:00:01.000000Z INFO - Changing directory to /home/site/wwwroot
2024-10-26T12:00:01.100000Z INFO - Installing required packages from requirements.txt
2024-10-26T12:00:01.200000Z INFO - Collecting gunicorn==20.1.0
2024-10-26T12:00:01.300000Z INFO - Collecting python-decouple
2024-10-26T12:00:02.000000Z INFO - Successfully installed gunicorn-20.1.0 python-decouple-3.5
2024-10-26T12:00:02.100000Z INFO - All dependencies installed successfully
2024-10-26T12:00:02.200000Z INFO - Starting Gunicorn server with the command:
gunicorn --bind=0.0.0.0:8000 --timeout 600 myapp.wsgi:application
2024-10-26T12:00:02.300000Z INFO - [2024-10-26 12:00:02 +0000] [69] [INFO] Starting gunicorn 20.1.0
2024-10-26T12:00:02.400000Z INFO - [2024-10-26 12:00:02 +0000] [69] [INFO] Listening at: http://0.0.0.0:8000 (69)
2024-10-26T12:00:02.500000Z INFO - [2024-10-26 12:00:02 +0000] [69] [INFO] Using worker: sync
2024-10-26T12:00:02.600000Z INFO - [2024-10-26 12:00:02 +0000] [72] [INFO] Booting worker with pid: 72
2024-10-26T12:00:02.700000Z INFO - Application started successfully and is now listening on port 8000
2024-10-26T12:00:02.800000Z INFO - [2024-10-26 12:00:02 +0000] [72] [INFO] Worker is processing requests...
2024-10-26T12:00:03.000000Z INFO - [2024-10-26 12:00:03 +0000] [72] [INFO] GET /healthcheck 200 3ms
2024-10-26T12:00:04.000000Z INFO - [2024-10-26 12:00:04 +0000] [72] [INFO] POST /api/data 201 10ms
Upvotes: 1