I have built an app with an Django back-end, a React front-end and a Postgres database, and I am in the process of deploying them to Azure for the first time.
Key actions I have taken:
- used django-webpack-loader and webpack-bundle-tracker, so my front and back-end code can be deployed as one app
- set up Django app in Azure using the App service
- migrated my postgres database into Azure using the Azure Database for PostgreSQL flexible server
Current outputs:
- deployed code successfully using github continuous deployment
- set my database, allowed_hosts, secreet_key and port values in application settings
- successfully migrated my django folders into the Azure environment using the Web SSH in the Azure portal
My issue:
When I visit my url, the page times out, with 'Application Error'. I'm troubleshooting the error in the logs, which return the output below.
I have noticed two potential errors:
- Within the error logs - TypeError: expected str, bytes or os.PathLike object, not PosixPath
- When I run python manage.py runserver in the SSH, it returns 'port 8000 is already in use'. After killing and exiting processes on that port, it still remains. I am able to access the server when I run python manage.py runserver 9000, but still get no results.
Azure Error logs:
/home/LogFiles/2023_01_20_lw0sdlwk0000X9_default_docker.log (https://-test.scm.azurewebsites.net/api/vfs/LogFiles/2023_01_20_lw0sdlwk0000X9_default_docker.log)
2023-01-20T10:10:15.109452667Z File "<frozen importlib._bootstrap_external>", line 850, in exec_module
2023-01-20T10:10:15.109456467Z File "<frozen importlib._bootstrap>", line 228, in _call_with_frames_removed
2023-01-20T10:10:15.109460067Z File "/tmp/8dafa589514f05f/project/settings.py", line 94, in <module>
2023-01-20T10:10:15.109463967Z 'DIRS': [os.path.join(BASE_DIR, 'client')
2023-01-20T10:10:15.109467367Z File "/opt/python/3.9.7/lib/python3.9/posixpath.py", line 76, in join
2023-01-20T10:10:15.109471167Z a = os.fspath(a)
2023-01-20T10:10:15.109474567Z TypeError: expected str, bytes or os.PathLike object, not PosixPath
2023-01-20T10:10:15.109478267Z [2023-01-20 10:10:15 0000] [122] [INFO] Worker exiting (pid: 122)
2023-01-20T10:10:15.227401497Z mkdir() got an unexpected keyword argument 'exist_ok'
/home/LogFiles/2023_01_20_lw0sdlwk0000X9_docker.log (https://-test.scm.azurewebsites.net/api/vfs/LogFiles/2023_01_20_lw0sdlwk0000X9_docker.log)
2023-01-20T10:05:20.883Z INFO - Stopping site -test because it failed during startup.
2023-01-20T10:09:33.036Z INFO - Starting container for site
2023-01-20T10:09:33.037Z INFO - docker run -d --expose=8000 --name-test_1_547d9150 -e WEBSITES_PORT=8000 -e WEBSITE_SITE_NAME=-test -e WEBSITE_AUTH_ENABLED=False -e PORT=8000 -e WEBSITE_ROLE_INSTANCE_ID=0 -e WEBSITE_HOSTNAME=-test.azurewebsites.net -e WEBSITE_INSTANCE_ID=xyz -e HTTP_LOGGING_ENABLED=1 -e WEBSITE_USE_DIAGNOSTIC_SERVER=True appsvc/python:3.9_20221128.12.tuxprod
2023-01-20T10:09:36.544Z INFO - Initiating warmup request to container-test_1_547d9150 for site-test
2023-01-20T10:09:52.315Z INFO - Waiting for response to warmup request for container -test_1_547d9150. Elapsed time = 15.7713165 sec
2023-01-20T10:10:08.131Z INFO - Waiting for response to warmup request for container -test_1_547d9150. Elapsed time = 31.5870197 sec
2023-01-20T10:13:47.693Z ERROR - Container -test_1_547d9150 for site-test did not start within expected time limit. Elapsed time = 251.1494362 sec
2023-01-20T10:13:47.733Z ERROR - Container -test_1_547d9150 didn't respond to HTTP pings on port: 8000, failing site start. See container logs for debugging.
2023-01-20T10:13:47.753Z INFO - Stopping site -test because it failed during startup.
/home/LogFiles/AppServiceAppLogs_Feature_Installer/startup_0.log (https://-test.scm.azurewebsites.net/api/vfs/LogFiles/AppServiceAppLogs_Feature_Installer/startup_0.log)
2023-01-20 09:45:55,527 [Thread-1 ] [DEBUG] : Did not find any previously bound socket
2023-01-20 09:55:42,312 [MainThread] [DEBUG] : Initializating AppServiceAppLogging
2023-01-20 09:55:42,316 [MainThread] [DEBUG] : Initialized AppServiceAppLogging
2023-01-20 09:55:42,359 [Thread-1 ] [DEBUG] : Did not find any previously bound socket
2023-01-20 10:05:11,655 [MainThread] [DEBUG] : Initializating AppServiceAppLogging
2023-01-20 10:05:11,658 [MainThread] [DEBUG] : Initialized AppServiceAppLogging
2023-01-20 10:05:11,706 [Thread-1 ] [DEBUG] : Did not find any previously bound socket
2023-01-20 10:10:08,028 [MainThread] [DEBUG] : Initializating AppServiceAppLogging
2023-01-20 10:10:08,030 [MainThread] [DEBUG] : Initialized AppServiceAppLogging
2023-01-20 10:10:08,039 [Thread-1 ] [DEBUG] : Did not find any previously bound socket
Django Settings.py file:
from pathlib import Path
import environ
import os
env = environ.Env()
environ.Env.read_env()
BASE_DIR = Path(__file__).resolve().parent.parent
SECRET_KEY = env('SECRET_KEY')
DEBUG = False
ALLOWED_HOSTS = [env('ALLOWED_HOSTS')]
# Application definition
INSTALLED_APPS = [
'whitenoise.runserver_nostatic',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'webpack_loader',
'rest_framework',
'jwt_auth',
'etc etc',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
ROOT_URLCONF = 'project.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'client')
]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
print('templates ->', TEMPLATES)
WSGI_APPLICATION = 'project.wsgi.application'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': env('DBNAME'),
'HOST': env('DBHOST'),
'PORT': 5432,
'USER': env('DBUSER'),
'PASSWORD': env('DBPASS')
}
}
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_TZ = True
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, "client", "build", "static"),
)
print('static-files ->', STATICFILES_DIRS)
STATIC_ROOT = (
os.path.join(BASE_DIR, "static")
)
print('static-root ->', STATIC_ROOT)
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
AUTH_USER_MODEL = 'jwt_auth.User'
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': (
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
),
'DEFAULT_AUTHENTICATION_CLASSES': (
'jwt_auth.authentication.JWTAuthentication',
),
}
WEBPACK_LOADER = {
'DEFAULT': {
'CACHE': not DEBUG,
'STATS_FILE': os.path.join(BASE_DIR, 'webpack-stats.json'),
'POLL_INTERVAL': 0.1,
'IGNORE': [r'. \.hot-update.js', r'. \.map'],
}
}
CodePudding user response:
Hm, here's a similar repository, the result of the cookiecutter-django project, that I successfully deployed to Azure: https://github.com/pamelafox/cookiecutter-django-output/
Here's the settings file: https://github.com/pamelafox/cookiecutter-django-output/blob/main/config/settings/base.py
It doesn't use os.path.join() and instead uses the "/" as a join operator. For example:
APPS_DIR = ROOT_DIR / "my_awesome_project"
From my reading of the os.path.join() docs, its not clear to me that it should work with a Path() object. It's interesting that it works locally but not on production, but perhaps you're using a different Python version locally than on production?
Perhaps you could try "/" path formation instead.
Here's a post I wrote recently with general tips for debugging Django apps on Azure App Service:
http://blog.pamelafox.org/2023/01/tips-for-debugging-django-app.html
CodePudding user response:
Solved for anyone with a similar error:
Replaced this:
STATIC_ROOT = ( os.path.join(BASE_DIR, "static") )
With:
STATIC_ROOT = ( BASE_DIR.as_posix() '/static' )
As per Pamela's response, os.path.join does not appear to be supported in production or on some Python versions.