I have deployed a Django webapp on Vercel which uses a PlanetScale database. I have stored the PlanetScale connection strings as environment variables in Vercel. Django seems to be able to see the env variables; however, I am getting a FileNotFoundError
for the CA cert path which was provided by PlanetScale. This is causing a server error that takes the app completely offline. This CA path was working previously when stored in a .env file. I have since attempted to replace the .env file and that no longer works either. Nothing else has changed in the project so I am at a loss as how to get this connection established again. Any help would be greatly appreciated.
I will provide the error stack and settings below:
Error:
[ERROR] 2023-06-20T20:00:18.077Z 06fecc12-d46a-4f4f-9cf7-c00e50c42fb4 Internal Server Error: /
Traceback (most recent call last):
File "/var/task/django/core/handlers/exception.py", line 56, in inner
response = get_response(request)
File "/var/task/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/var/task/main/views.py", line 21, in home
currUser = AuthUser.objects.get(username=request.user)
File "/var/task/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/var/task/django/db/models/query.py", line 646, in get
num = len(clone)
File "/var/task/django/db/models/query.py", line 376, in __len__
self._fetch_all()
File "/var/task/django/db/models/query.py", line 1867, in _fetch_all
self._result_cache = list(self._iterable_class(self))
File "/var/task/django/db/models/query.py", line 87, in __iter__
results = compiler.execute_sql(
File "/var/task/django/db/models/sql/compiler.py", line 1396, in execute_sql
cursor = self.connection.cursor()
File "/var/task/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/var/task/django/db/backends/base/base.py", line 323, in cursor
return self._cursor()
File "/var/task/django/db/backends/base/base.py", line 299, in _cursor
self.ensure_connection()
File "/var/task/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/var/task/django/db/backends/base/base.py", line 282, in ensure_connection
self.connect()
File "/var/task/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/var/task/django/db/backends/base/base.py", line 263, in connect
self.connection = self.get_new_connection(conn_params)
File "/var/task/django/utils/asyncio.py", line 26, in inner
return func(*args, **kwargs)
File "/var/task/django/db/backends/mysql/base.py", line 247, in get_new_connection
connection = Database.connect(**conn_params)
File "/var/task/pymysql/connections.py", line 284, in __init__
self.ctx = self._create_ssl_ctx(ssl)
File "/var/task/pymysql/connections.py", line 367, in _create_ssl_ctx
ctx = ssl.create_default_context(cafile=ca, capath=capath)
File "/var/lang/lib/python3.9/ssl.py", line 746, in create_default_context
context.load_verify_locations(cafile, capath, cadata)
FileNotFoundError: [Errno 2] No such file or directory
settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ.get('MYSQL_DB_NAME'),
'HOST': os.environ.get('MYSQL_DB_HOST'),
'PORT': os.environ.get('MYSQL_DB_PORT'),
'USER': os.environ.get('MYSQL_DB_USER'),
'PASSWORD': os.environ.get('MYSQL_DB_PASSWORD'),
'OPTIONS': {'ssl': {'ca': os.environ.get('MYSQL_ATTR_SSL_CA')}},
}
}
Vercel Environment Variables
MYSQL_DB_NAME=<DBNAME>
MYSQL_DB_USER=<PS_USER>
MYSQL_DB_PASSWORD=<PS_PASSWORD>
MYSQL_DB_HOST=<PS_HOST>
MYSQL_DB_PORT=3306
MYSQL_ATTR_SSL_CA=/etc/ssl/certs/ca-certificates.crt
I have a feeling because I transferred the environment variables into Vercel, it is appending something unintended to the beginning of the CA path, but since my app can't build and debug is off, I cant see what is being passed.