Solving Container Communication Issues in Dokploy Projects

A detailed guide on why containers deployed in Dokploy cannot communicate with each other and how to resolve this common issue by configuring Docker Compose networks.

Problem Description

When deploying applications with Dokploy, you may encounter an issue where services within a project cannot communicate with each other.

For example, in a Dokploy project:

  • You created a MySQL database using Dokploy’s built-in database feature
  • You deployed a Ghost blog application using Docker Compose

At this point, the Ghost application’s logs will report that it cannot resolve the MySQL hostname, resulting in database connection failures.

Error: getaddrinfo ENOTFOUND xxx-mysql-7eegrt
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:66:26)

Root Cause

The fundamental reason for this issue is container network isolation.

In Dokploy:

  • MySQL containers deployed through the built-in database feature automatically join the dokploy-network network
  • Applications deployed using Docker Compose create a separate dedicated network by default, typically named <project-name>_default

Since the two containers are on different Docker networks, they cannot directly communicate with each other using container names or service names. It’s like two people on different local networks who cannot directly access each other.

Solution

The key to solving this problem is to make the Docker Compose deployed application join the dokploy-network.

Configuration Steps

In your Docker Compose configuration file, you need to make two modifications:

  1. Add network configuration to the service definition: In the application configuration under the services section, add the networks field to specify using dokploy-network
  2. Declare the external network: Add a networks section at the top level of the configuration file to declare dokploy-network as an external network

Complete Configuration Example

Using Ghost blog as an example, here’s the complete Docker Compose configuration:

services:
  ghost:
    image: ghost:5.129.0-alpine
    ports:
      - 2368
    environment:
      NODE_ENV: production
      url: https://xxx.com
      database__client: mysql
      database__connection__host: xxx-mysql-7eegrt
      database__connection__user: ghost
      database__connection__password: xxx
      database__connection__database: ghost
    volumes:
      - /root/xxx/data:/var/lib/ghost/content
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - dokploy-network

networks:
  dokploy-network:
    external: true

Configuration Explained

Service Network Configuration

services:
  ghost:
    # ... other configurations
    networks:
      - dokploy-network

Add the networks field in the service definition to specify which network(s) the container should join. Here we specify dokploy-network, so the Ghost container will connect to this network when it starts.

External Network Declaration

networks:
  dokploy-network:
    external: true

Declare the network configuration in the top-level networks section:

  • external: true indicates this is an external network, meaning it’s not created by the current Docker Compose file but already exists
  • Docker Compose will check if dokploy-network exists when starting; if it doesn’t exist, it will throw an error

Verifying Network Connectivity

After configuration, you can verify that the container has successfully joined the network using the following methods:

1. Inspect Container Network

docker inspect <container-name-or-ID> | grep -A 10 Networks

The output should include dokploy-network:

"Networks": {
    "dokploy-network": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": [
            "ghost",
            "xxx"
        ],
        ...
    }
}

2. Test Network Connectivity

Enter the Ghost container to test if it can resolve the MySQL hostname:

# Enter the container
docker exec -it <ghost-container-name> sh

# Test DNS resolution
ping xxx-mysql-7eegrt

# Test MySQL port connectivity
nc -zv xxx-mysql-7eegrt 3306

If you can resolve and connect normally, the network configuration is successful.

Additional Considerations

1. Database Hostname

Databases created in Dokploy typically have hostnames in the format <project-name>-<service-name>-<random-chars>. You can find the specific hostname in the Dokploy control panel.

2. Port Configuration

When containers are on the same Docker network:

  • Internal communication uses the container’s internal port (e.g., MySQL’s 3306)
  • External access requires the mapped host port

In the above configuration, ports: - 2368 maps the container’s port 2368 to a random host port, and Dokploy automatically handles routing for external access.

3. Multiple Network Configuration

If your application needs to connect to multiple networks, you can configure it like this:

services:
  myapp:
    networks:
      - dokploy-network
      - custom-network

networks:
  dokploy-network:
    external: true
  custom-network:
    driver: bridge

4. Network Isolation Best Practices

While placing all services on the same network solves communication issues, from a security perspective:

  • Production environments should divide networks based on service responsibilities
  • Only services that need to communicate should be on the same network
  • Sensitive services (like databases) should have limited network access scope

Summary

The container communication issue in Dokploy is essentially caused by Docker’s network isolation mechanism. By configuring Docker Compose to:

  1. Add networks: - dokploy-network in the service definition
  2. Declare dokploy-network as an external network

You can enable containers deployed in different ways to join the same network and communicate with each other. This is an important configuration detail to pay attention to when orchestrating containers in Dokploy.