I am using DigitalOcean App Platform to deploy a Django app. The initial deployment worked fine, but I’ve attempted to use the bulk editor on the component-level environment variables, and since then, the deployment fails when executing dj_database_url.config(default=config('DATABASE_URL')
.
For debugging, I added this line to settings.py
:
print(f"[BUILD DEBUG] DATABASE_URL = {repr(os.environ.get('DATABASE_URL'))}")
This returns [BUILD DEBUG] DATABASE_URL = '${db.DATABASE_URL}'
in the build logs.
I don’t understand why the environment variable is not resolving. My app spec looks like this:
services:
- environment_slug: python
envs:
- key: DATABASE_URL
scope: RUN_AND_BUILD_TIME
value: ${db.DATABASE_URL}
Could this be a bug, or am I doing something wrong? Yes, my database is named correctly:
databases:
- engine: PG
name: db
The only thing that changed between my last deployment and this failed deployment, besides a few lines of code, is that I used the bulk editor to add new environment variables. Some of the existing environment variables were encrypted, but they look OK in the app spec.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Hi there,
I think that the ${db.DATABASE_URL}
reference isn’t resolved during the build phase, only at runtime. If I remember correctly, App Platform doesn’t expose database credentials during build to prevent issues like accidental schema changes or migrations that aren’t backward compatible.
If you’re using dj_database_url.config()
during build time (e.g., running migrations), it’ll fail because DATABASE_URL
is still just the literal string ${db.DATABASE_URL}
.
To fix this, make sure database access (like migrate
) happens at runtime, not during build.
Or, if absolutely needed, manually set a fallback DATABASE_URL
value for build purposes, just be cautious not to expose production credentials.
- Bobby
While this doesn’t really answer the question of why my DigitalOcean App only broke after using the bulk editor, I fixed my problem by wrapping my DATABASES
declaration in a try/except block:
database_url = config('DATABASE_URL', default=None, cast=str)
try:
DATABASES = {
'default': dj_database_url.config(
default=database_url, conn_max_age=600)
}
except Exception as e:
print(f"Failed to parse DATABASE_URL, using default SQLite. Reason: {e}")
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': BASE_DIR / 'db.sqlite3',
}
}
Although rudimentary, this works in both development (where DATABASE_URL
is absent from the environment variables) and in production.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
Sign up and get $200 in credit for your first 60 days with DigitalOcean.*
*This promotional offer applies to new accounts only.