EC2上Docker Compose配置DNS解决Laravel容器联网问题
问题描述
AWS EC2实例已运行Apache服务,部署Laravel Docker容器时遇到联网异常:
- Docker Compose配置
dns字段为8.8.8.8、8.8.4.4后,容器构建启动无报错,但无法访问互联网; - 直接执行
sudo docker run --dns 8.8.8.8 --dns 8.8.4.4 -it api_web:latest /bin/bash启动容器,联网功能正常; - 尝试通过
daemon.json配置全局DNS或使用host网络模式,均因端口冲突失败。
需在不干扰主机Apache的前提下,通过Docker Compose正确配置DNS实现容器联网。
现有配置文件
Dockerfile
# Base image as Ubuntu 22.04 FROM ubuntu:22.04 # Avoid prompts from apt. ENV DEBIAN_FRONTEND=noninteractive # Install curl and iputils-ping to check internet connectivity RUN apt-get update && apt-get install -y curl iputils-ping RUN curl -s https://api.ipify.org || exit 1 # Install required packages RUN apt-get install -y software-properties-common && \ add-apt-repository ppa:ondrej/php && \ apt-get update && apt-get install -y apache2 \ php8.1 php8.1-fpm php8.1-common php8.1-mysql php8.1-xml php8.1-xmlrpc php8.1-curl php8.1-gd php8.1-imagick php8.1-cli php8.1-dev php8.1-imap php8.1-mbstring php8.1-opcache php8.1-soap php8.1-zip php8.1-intl \ mariadb-server mariadb-client composer # Set your timezone RUN ln -fs /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime && dpkg-reconfigure --frontend noninteractive tzdata # Enable Apache mods RUN a2enmod rewrite ssl # Copy application source COPY . /var/www/html # Set the working directory WORKDIR /var/www/html # Remove composer.lock if present and install/update Composer dependencies RUN if [ -f composer.lock ]; then rm composer.lock; fi && \ composer install --no-interaction && \ composer update --no-interaction # Expose ports for web traffic EXPOSE 80 443 # Start Apache in the foreground CMD ["apache2ctl", "-D", "FOREGROUND"]
docker-compose.yml
version: '3.8' services: web: build: . ports: - "8080:80" - "8443:443" volumes: - /var/www/backend/api:/var/www/html - /etc/apache2/sites-available/api.com.br.conf:/etc/apache2/sites-available/000-default.conf - /etc/apache2/sites-available/api.com.br-le-ssl.conf:/etc/apache2/sites-available/000-default-le-ssl.conf command: > bash -c "composer update && apache2ctl -D FOREGROUND" environment: - APACHE_DOCUMENT_ROOT=/var/www/html/public dns: - 8.8.8.8 - 8.8.4.4
解决方案
方案1:自定义桥接网络并配置DNS
Docker Compose默认网络可能继承主机DNS配置,导致自定义DNS失效。显式创建桥接网络并配置DNS,确保容器使用指定的DNS服务器:
修改后的docker-compose.yml:
version: '3.8' # 自定义桥接网络,配置指定DNS networks: laravel_net: driver: bridge dns: - 8.8.8.8 - 8.8.4.4 services: web: build: . ports: - "8080:80" - "8443:443" volumes: - /var/www/backend/api:/var/www/html - /etc/apache2/sites-available/api.com.br.conf:/etc/apache2/sites-available/000-default.conf - /etc/apache2/sites-available/api.com.br-le-ssl.conf:/etc/apache2/sites-available/000-default-le-ssl.conf command: > bash -c "composer update && apache2ctl -D FOREGROUND" environment: - APACHE_DOCUMENT_ROOT=/var/www/html/public # 将容器加入自定义网络 networks: - laravel_net
操作步骤:
- 停止并清理旧容器和网络:
docker-compose down -v - 重新构建并启动:
docker-compose up --build -d - 进入容器验证DNS:
docker exec -it <容器名> cat /etc/resolv.conf
方案2:容器启动时强制修改DNS配置
如果方案1无效,可在容器启动命令中直接替换/etc/resolv.conf,强制设置指定DNS:
修改docker-compose.yml的command字段:
command: > bash -c "echo 'nameserver 8.8.8.8' > /etc/resolv.conf && echo 'nameserver 8.8.4.4' >> /etc/resolv.conf && composer update && apache2ctl -D FOREGROUND"
此方法绕过Compose的DNS配置逻辑,直接在容器内写入DNS配置,确保生效。
方案3:排查Docker Compose版本与缓存问题
- 检查Compose版本:执行
docker-compose --version,若版本低于v2.x,建议升级到最新稳定版; - 清理Compose缓存:执行
docker-compose build --no-cache重新构建镜像,避免旧缓存导致的网络配置异常。
额外优化建议
- Dockerfile优化:将多个RUN命令合并,减少镜像层数,同时避免构建阶段的网络重复请求;
- 拆分服务:将MariaDB拆分为独立的Compose服务,避免容器内运行多个进程,提升稳定性和可维护性;
- 依赖稳定:保留
composer.lock文件,避免每次构建都更新依赖,确保依赖版本稳定。
内容的提问来源于stack exchange,提问作者Marcius Leandro
相关产品推荐
相关产品推荐

