DNS from the container to the external database is not working

DNS from the container to the external database is not working.
The cause seems to be in the DockerSwarm network, but I can’t pinpoint it, so could you please let me know if you know the cause?

I would like to run a Laravel application using DockerSwarm. The structure is
Laravel container (php8.2-apache) in DockerSwarm (in EC2)
mysql on planetscale
These are two simple applications.
Below is a part of the .env and I am unable to resolve the domain name from the container as in the following error.

SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo for ap-northeast.connect.psdb.cloud failed: temporary failure in name resolution

DB_CONNECTION=mysql
DB_HOST=ap-northeast.connect.psdb.cloud
DB_PORT=3306
MYSQL_ATTR_SSL_CA=/etc/ssl/cert.pem

The Laravel container image resides in AWS ECR and running this image with

 docker run -p 80:80 myimage:latest 

works correctly.

Considering all of this, I think something is wrong with DockerSwarm.
Here is the compose.yml

version: '3.8'

services:
  app:
    image: 995962138333.dkr.ecr.ap-northeast-1.amazonaws.com/myimage:latest
    networks:
      - laravel
    ports:
      - "80:80"
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 30s
      restart_policy:
        condition: on-failure
networks:
  laravel:

■Dockerfile

FROM php:8.2-apache

WORKDIR /var/www
ENV APACHE_RUN_USER www-data
ENV APACHE_RUN_GROUP www-data

RUN apt-get update && apt-get install -y \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip \
    git \
    curl

RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

COPY . /var/www
COPY simple-swarm/sites-available /etc/apache2/sites-available
COPY simple-swarm/cacert.pem /etc/ssl/cert.pem
COPY .env.production /var/www/.env

ENV COMPOSER_ALLOW_SUPERUSER 1 
RUN composer install

RUN chown -R www-data:www-data /var/www
EXPOSE 9000

add…
docker network ls

[ec2-user@3 ~]$ docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
e06a1f7ec57f   bridge            bridge    local
2utb4ar7gh6s   cook_laravel      overlay   swarm
884db2d4b786   docker_gwbridge   bridge    local
4e1501e338e7   host              host      local
s0z1txyeyhib   ingress           overlay   swarm
69a0f3aca927   none              null      local

Have you checked that it is a network issue or “just” DNS issue? You could try to ping an external IP address and set a custom DNS server for the swarm container. In case of Docker Compose a built-in DNS server is used to resolve internal domain names and forward the rest of the requests to hosts’s DNS server. I guess swarm is no different, so if some firewall rules forbid accessing the DNS server from the swarm network, DNS resolution will fail.

In case you want to debug and your container doesn’t have ping and nslookup, nicolaka/netshoot can be used for debugging.

1 Like

Sorry, I forgot the following.

I have determined that it is a DNS problem with the following results

curl **. **. ***. ** (IP address)

→ result returned correctly

apt update -y

from container bash to install ping failed.

Also curl to my website fails.

root@f0b74df6a0f3:/var/www# curl https://uchida.link/
curl: (6) Could not resolve host: uchida.link

Thanks for the advice.
I don’t know much about DNS for compose and swarm, so I will look into it and try to set it up.

In docker-compose.yml

dns: 8.8.8.8

version: '3.8'

services:
  app:
    image: 995962138333.dkr.ecr.ap-northeast-1.amazonaws.com/myimage:latest
    networks:
      - laravel
    ports:
      - "80:80"
    dns: 8.8.8.8
    deploy:
      replicas: 3
      update_config:
        parallelism: 1
        delay: 30s
      restart_policy:
        condition: on-failure
networks:
  laravel:

to the name resolution of the external host.
Thanks to your advice I was able to solve this problem quickly.
Thank you very much.