`export DATABASE_URL` not working as expected

I’m working through the testdriven.io Django REST Framework and Docker tutorial. In the Heroku deployment step I’m trying to configure Heroku locally and it’s not respecting the export statement I’m trying to run in CLI:

export DATABASE_URL=postgresql://foo:bar@ec2-107-20-230-70.compute-1.amazonaws.com:5432/datn10dvjpjut9

When I then try to spin up the container:

docker run --name django-tdd -e "PORT=8765" -p 8008:8765 registry.heroku.com/radiant-sea-33261/web:latest

I get:

[2024-10-17 00:42:36 +0000] [7] [INFO] Starting gunicorn 22.0.0
[2024-10-17 00:42:36 +0000] [7] [INFO] Listening at: http://0.0.0.0:8765 (7)
[2024-10-17 00:42:36 +0000] [7] [INFO] Using worker: sync
[2024-10-17 00:42:36 +0000] [8] [INFO] Booting worker with pid: 8
WARNING:root:No DATABASE_URL environment variable set, and so no databases setup

I’m on Windows 11 with WSL. Running export in the Linux terminal does show a DATABASE_URL entry. Does this have something to do with WSL with Docker Desktop (installed on Windows) to communicate with my Linux shell?

Note that the connection strings and DB names are just the examples copy/pasted from the tutorial, those are not my actual connection strings.

It sounds like the issue might be due to how environment variables are passed between WSL (Windows Subsystem for Linux) and Docker Desktop on Windows. While you’re setting the DATABASE_URL environment variable in your WSL session using export, Docker Desktop, which runs natively on Windows, might not be able to pick up on environment variables set in WSL.

Here’s what you can try to resolve this:

Solution 1: Pass the DATABASE_URL Directly in the Docker Command

Instead of relying on the export statement, try passing the DATABASE_URL directly when running the container:

docker run --name django-tdd -e "PORT=8765" -e "DATABASE_URL=postgresql://foo:bar@ec2-107-20-230-70.compute-1.amazonaws.com:5432/datn10dvjpjut9" -p 8008:8765 registry.heroku.com/radiant-sea-33261/web:latest

This ensures that DATABASE_URL is available inside the container, bypassing any issues with environment variable propagation from WSL to Docker.

Solution 2: Use a .env File

You can create a .env file with the environment variables and pass it to Docker. Here’s how:

  1. Create a .env file in your project directory:
DATABASE_URL=postgresql://foo:bar@ec2-107-20-230-70.compute-1.amazonaws.com:5432/datn10dvjpjut9
  1. Run Docker with the --env-file flag:
docker run --name django-tdd --env-file .env -e "PORT=8765" -p 8008:8765 registry.heroku.com/radiant-sea-33261/web:latest

Solution 3: Ensure Proper WSL and Docker Communication

Since Docker Desktop runs natively on Windows but uses WSL for Linux-based environments, there can sometimes be issues with passing environment variables.

  • Make sure that Docker is properly configured to work with WSL by enabling the integration with your WSL distro in Docker Desktop:
    1. Open Docker Desktop.
    2. Go to Settings > Resources > WSL Integration.
    3. Ensure your WSL distribution is checked for Docker integration.

Solution 4: Set the Environment Variable on Docker

You can also set the DATABASE_URL environment variable for Docker directly from Windows:

set DATABASE_URL=postgresql://foo:bar@ec2-107-20-230-70.compute-1.amazonaws.com:5432/datn10dvjpjut9
docker run --name django-tdd -e "PORT=8765" -e "DATABASE_URL=$DATABASE_URL" -p 8008:8765 registry.heroku.com/radiant-sea-33261/web:latest

Let me know if any of these solutions work or if you need further assistance!