You just set up a new self-hosted app on your Canadian Web Hosting Cloud VPS. You followed the tutorial step by step. Docker Compose is running. And then you see it in the logs:

Error: connect ECONNREFUSED 127.0.0.1:5432
Can't connect to MySQL server on '127.0.0.1' (61)
FATAL: no PostgreSQL user configured for this application
could not translate host name "db" to address: Temporary failure in name resolution

Your app is running, but it can’t reach its database. This is the single most common failure mode for self-hosted applications, and it has many possible causes. In this guide, we will walk through each one systematically so you can get back up and running fast.

Quick Fix: Most Common Cause

Eight times out of ten, the database container simply is not running:

docker ps --filter "name=db" --filter "name=database" --filter "name=postgres" --filter "name=mysql" --filter "name=mariadb"

If nothing appears, check all containers — not just running ones:

docker ps -a | grep -E 'db|database|postgres|mysql|mariadb|sqlite'

If the container exists but has status Exited, try restarting it:

docker start <container_name>

Then check the database container logs for the real cause:

docker logs <container_name> --tail 50

If the container does not exist at all, check your docker-compose.yml — the database service definition may have been omitted or commented out. Run docker compose up -d from the project directory to recreate it.

Root Causes

If the quick fix did not resolve it, work through these causes in order. The most common problems come first.

Database service not defined in docker-compose.yml

More often than you would think: the database section is simply missing from the Docker Compose file. Many self-hosted apps expect you to bring your own database — they do not ship with one pre-configured.

How to confirm:

grep -A 20 'services:' docker-compose.yml | grep -E 'image:|depends_on:'
# Does any line reference postgres, mysql, mariadb, or a database image?

The fix: Add a database service to your docker-compose.yml. Here is a typical PostgreSQL example:

services:
  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: myapp
      POSTGRES_PASSWORD: changeme
      POSTGRES_DB: myapp
    volumes:
      - pgdata:/var/lib/postgresql/data
    restart: unless-stopped

volumes:
  pgdata:

Then recreate your stack: docker compose up -d.

Wrong hostname or port in the app configuration

This is the second most common cause. The database is running fine, but the app is looking for it at the wrong address.

How to confirm: Check the app environment variables or configuration file for database connection settings:

grep -i -A 5 'DATABASE|DB_HOST|DB_PORT|MYSQL_HOST|PGHOST' .env
grep -i -A 5 'DATABASE|DB_HOST|DB_PORT|MYSQL_HOST|PGHOST' docker-compose.yml

The key rule: When the database runs in a Docker container on the same network, use the service name as the hostname, not localhost or 127.0.0.1.

Database location Hostname to use Default port
Same Docker Compose network db (or whatever the service is named) 5432 / 3306
Same Docker network (separate compose file) Container name or network alias 5432 / 3306
Host machine (not containerized) host.docker.internal 5432 / 3306
Remote server IP address or hostname 5432 / 3306

The fix: Update the DATABASE_HOST or DB_HOST variable in your .env file to the correct hostname, then restart the stack with docker compose up -d.

Port conflict — another service is using the database port

If you are running multiple self-hosted apps, two of them may be trying to bind the same database port on the host.

How to confirm:

sudo lsof -i :5432
# If PostgreSQL is already running on the host, this port is taken

sudo lsof -i :3306
# If MySQL/MariaDB is already running, this port is taken

The fix: Change the published port in your compose file — map the container port to a different host port:

services:
  db:
    image: postgres:16-alpine
    ports:
      - "5433:5432"   # host port 5433 ? container port 5432
    # ...

Then update the app config to use localhost:5433 instead of localhost:5432.

Firewall blocking the connection

If the database is on a different server or uses a non-standard port, a firewall rule may be silently dropping the connection.

How to confirm: From the app server, try to reach the database port using nc or telnet:

nc -zv <db_host> 5432
# Connection refused = no service listening OR firewall drop
# Connection timed out = firewall is likely dropping packets

telnet <db_host> 5432
# Similar result

The fix: On the database server, allow the app server IP through the firewall:

sudo ufw allow from <app_server_ip> to any port 5432 proto tcp
# Or for a wider rule:
sudo ufw allow 5432/tcp  # ?? Only if the database firewall protects internal traffic

For CWH Cloud VPS customers, firewall rules can be managed through the VPS control panel or via UFW on the server itself.

Database credentials are wrong

The app has the wrong username, password, or database name. This often happens when you copy credentials from a different project or the environment file was edited incorrectly.

How to confirm: Try connecting directly with the credentials from your app config:

# PostgreSQL
PGPASSWORD=your_password psql -h localhost -U your_user -d your_db -c "SELECT 1"

# MySQL / MariaDB
mysql -h localhost -u your_user -pyour_password your_db -e "SELECT 1"

# SQLite
sqlite3 /path/to/database.db "SELECT 1;"

If the connection succeeds but the app still fails, the app may be using cached credentials — restart the app container: docker compose restart <app_service>.

The fix: Reset the database password:

# PostgreSQL in Docker
docker exec -it <db_container> psql -U postgres -c "ALTER USER myapp WITH PASSWORD 'new_password';"

# MySQL / MariaDB in Docker
docker exec -it <db_container> mysql -u root -p -e "ALTER USER 'myapp'@'%' IDENTIFIED BY 'new_password'; FLUSH PRIVILEGES;"

Then update the password in your app’s .env file and restart.

Disk space full — database cannot write

Databases are write-heavy. When the disk fills up, the database process crashes or refuses new connections.

How to confirm:

df -h
# Look for 100% usage on the partition where your database data lives

docker logs <db_container> --tail 30 | grep -i 'disk|space|no space|write|panic'

The fix: Free up space:

# Remove unused Docker data (this reclaims the most space fastest)
docker system prune -af --volumes

# Clear old database logs
sudo journalctl --vacuum-time=3d

# Rotate and compress PostgreSQL WAL files
docker exec <db_container> psql -U postgres -c "CHECKPOINT;"

If you are running out of space repeatedly, consider upgrading your CWH Cloud VPS plan to a larger disk size, or moving the database data directory to a dedicated volume.

Container networking issue — wrong Docker network

Each Docker Compose project creates its own network by default. Two apps in different projects cannot communicate over db hostnames unless they share a network.

How to confirm:

# Check which network the app container is on
docker inspect <app_container> --format '{{json .NetworkSettings.Networks}}'

# Check which network the DB container is on
docker inspect <db_container> --format '{{json .NetworkSettings.Networks}}'

# Are they on the same network?

The fix: Make both containers share the same Docker network:

# Create a shared network
docker network create shared-apps

# In your docker-compose.yml for the app:
services:
  app:
    networks:
      - shared-apps

networks:
  shared-apps:
    external: true

# In your database docker-compose.yml:
services:
  db:
    networks:
      - shared-apps

networks:
  shared-apps:
    external: true

Then use the database container name as the hostname from the app container.

Diagnostic Flowchart

Not sure which cause applies to you? Follow this decision tree:

  1. Check if the database container exists: docker ps -a | grep -E 'db|database|postgres|mysql|mariadb|sqlite'
    ? No container found? The service is missing from your compose file. See “Database service not defined.”
    ? Container found but exited? Check its logs: docker logs db --tail 50. Go to step 2.
    ? Container running? Go to step 3.
  2. Read the database container logs. Look for error messages about disk space, authentication failures, or configuration errors.
    ? Disk space error? See “Disk space full.”
    ? Auth error? See “Database credentials are wrong.”
    ? Other error? Search the message; it is likely a version-specific issue.
  3. Test connectivity from the app container: docker exec <app_container> nc -zv db 5432
    ? Connection refused? The DB is running but the port is wrong or firewalled. Go to step 4.
    ? Timeout? Firewall or network issue. See “Firewall blocking” or “Container networking.”
    ? Connected successfully? Go to step 5.
  4. Verify hostname resolution: docker exec <app_container> getent hosts db
    ? No result or wrong IP? See “Wrong hostname or port.”
    ? Correct IP? See “Port conflict” or “Firewall blocking.”
  5. Test credentials directly: Try connecting to the database with the app’s credentials from the app container or host.
    ? Login fails? See “Database credentials are wrong.”
    ? Login succeeds but app still broken? Restart the app container. If it still fails, check the app logs for additional context.

Prevention

Once your database connection is restored, take these steps to prevent it from breaking again:

  • Use Docker Compose healthchecks — make the app wait for the database to be ready before starting:
services:
  app:
    depends_on:
      db:
        condition: service_healthy
  db:
    image: postgres:16-alpine
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
  • Set up disk monitoring — use Netdata or Uptime Kuma to alert you when disk usage exceeds 80%. We covered these tools in Monitoring Stacks for Small Teams and our detailed comparison.
  • Automate database backups — set up pg_dump or mysqldump as a daily cron job with CloudSafe Backup for offsite storage.
  • Pin database image versions — use image: postgres:16-alpine instead of postgres:latest to avoid breaking changes from unexpected version upgrades.
  • Use environment variable files — keep all database connection settings in a single .env file referenced by docker-compose.yml, and version-control it (with secrets redacted).

When to Escalate

Some database issues run deeper than configuration. Contact Canadian Web Hosting Managed Support if:

  • Your database server will not start even after restarting the VPS
  • You suspect data corruption (the database crashes on SELECT queries that used to work)
  • The database service uses 100% CPU for extended periods with no obvious cause
  • You need to restore from a backup and are unsure of the procedure
  • Your VPS disk has failed or the filesystem reports I/O errors

CWH’s expert support team handles server-level issues, hardware diagnostics, and emergency restore operations — available 24/7 for managed server customers.

Related Issues

If your database connection problem is accompanied by other symptoms, these guides may help:

For app-specific database setup, refer to the individual tutorial for your tool: Cal.com, Vaultwarden, or Matomo — each includes the exact database configuration required.

If your container enters a restart loop due to database connection issues, our Docker Container Keeps Restarting: Diagnosis and Fix Guide covers this exact scenario.