Resolving Postgres connection errors in Django on Windows requires configuring the database host to use
host.docker.internal instead of
localhost. This special DNS name allows containers to reach services running on the host machine. By adjusting your
DATABASES setting and ensuring the Docker network is correctly configured, you can establish a stable link between your Django application and the local database instance.
Understanding the Network Barrier
When you run Django inside a Docker container, it operates in an isolated network environment separate from your Windows host. If you configure your Django settings to connect to
localhost or
127.0.0.1, the container attempts to find the database within its own internal loopback interface. Since Postgres is running on your Windows machine outside the container, this connection attempt fails with a "Connection refused" error. You must explicitly tell the container where the host machine lives on the network.
Docker provides a special hostname called
host.docker.internal that resolves to the internal IP address of the host machine. This feature is available on Docker Desktop for Windows and macOS. It simplifies development by allowing containers to access services like databases, caches, or APIs running directly on your PC without needing complex port mappings or custom network bridges.
Configuring Django Settings
The first step is to update your Django project's configuration file. Open the
settings.py file located in your project directory. Locate the
DATABASES dictionary, which defines how Django connects to your database backend.
You need to change the
HOST value from
localhost to
host.docker.internal. Ensure that the
PORT matches the one exposed by your Postgres container or service, which is typically
5432. The user and password should match the credentials you set up when initializing your Postgres instance.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'myuser',
'PASSWORD': 'mypassword',
'HOST': 'host.docker.internal', # Change this line
'PORT': '5432',
}
}
After making this change, save the file. This single modification directs all database queries from the Django container to the correct destination on your Windows host.
Ensuring Postgres Accessibility
Changing the Django setting is only half the solution. Your local Postgres installation must be configured to accept connections from external sources, including those coming from Docker containers. By default, Postgres might only listen for connections on
localhost or specific interfaces, blocking incoming requests from the Docker network.
Check your
postgresql.conf file. Look for the
listen_addresses parameter. It should include
* to listen on all available network interfaces, or specifically include the IP address associated with your Docker virtual network adapter. If it is set to
localhost, change it to
* and restart the Postgres service.
Next, examine the
pg_hba.conf file. This file controls client authentication. You need to ensure there is a rule that allows your Django user to connect from the Docker subnet. A common entry looks like this:
host mydatabase myuser 172.17.0.0/16 md5
This rule permits connections from the typical Docker bridge network range. Adjust the subnet if you are using a custom Docker network. After updating these files, restart the Postgres service to apply the changes.
Docker Compose Configuration
If you are using Docker Compose to manage your services, you may need to adjust the network settings. While
host.docker.internal usually works out of the box, some configurations require explicit network definitions. In your
docker-compose.yml file, ensure that your Django service is connected to the same network as any other services, or leave it on the default network to allow host resolution.
Sometimes, DNS resolution issues arise if the Docker Desktop version is outdated. Ensure you are running the latest version of Docker Desktop to guarantee support for
host.docker.internal. If you encounter persistent resolution failures, consider adding the hostname manually to the container's
/etc/hosts file via the
extra_hosts directive in your compose file, though this is rarely necessary on modern setups.
For more information on resolving similar network issues, see our guide on
Understanding Windows IP Address 'host.docker.internal'.
Verifying the Connection
Once you have updated both Django and Postgres configurations, rebuild your Docker containers to apply the new settings. Run the following command in your terminal:
docker-compose up --build
Start the Django server and attempt to run a migration or access the admin panel. If the connection is successful, you will see no errors during the startup process. You can also test connectivity from within the container using the
psql command if you have it installed in your image.
docker exec -it psql -h host.docker.internal -U myuser -d mydatabase
If this command connects successfully, your setup is complete. If it fails, check the Postgres logs on your Windows host for any rejection messages, which will indicate if the authentication or network rules are still too restrictive.
Frequently Asked Questions
Why does localhost work on my Mac but not Windows?
MacOS versions of Docker Desktop historically used different networking stacks that sometimes allowed direct localhost sharing. Windows uses Hyper-V or WSL2 backends that create distinct virtual networks, making
host.docker.internal essential for host-to-container communication.
Can I use the IP address instead of host.docker.internal?
Yes, you can use the internal IP address of your host, but it may change if your network configuration updates. Using
host.docker.internal is safer because Docker automatically resolves it to the current active IP, preventing broken links after reboots.
What if I get a permission denied error after changing settings?
This usually indicates that the
pg_hba.conf file does not allow connections from the Docker subnet. Verify that your authentication rule includes the Docker network CIDR block, typically
172.17.0.0/16 or
172.18.0.0/16, depending on your Docker setup.
Does this method work with PostgreSQL running in another container?
No,
host.docker.internal specifically targets the Windows host machine. If Postgres is running in a separate container linked via Docker Compose, you should use the service name defined in your
docker-compose.yml file as the host instead.
How do I troubleshoot if the connection still times out?
Check if your Windows Firewall is blocking incoming connections on port 5432. You may need to create an inbound rule allowing TCP traffic on this port for private and public networks to permit Docker containers to reach your local Postgres instance.