AWS ECS Fargate同一任务内Laravel容器无法访问MariaDB问题求助
需求背景
我需要在AWS ECS Fargate上运行一套简单的LAMP应用。
遇到的问题与报错信息
我无法从同一ECS任务内的PHP(Laravel)容器访问MariaDB容器,通过ECS Exec执行php artisan migrate命令也会抛出相同错误。
根据社区资料显示,同一Fargate任务内的容器可以通过localhost通信,但我本地测试无法连通。
具体报错为:SQLSTATE[HY000] [2002] No such file or directory (SQL: ...
基础设施定义
Laravel和MariaDB容器均通过Dockerfile构建后托管在ECR中。
*当前配置存在部分可优化项,我优先希望先跑通核心流程,因此部分配置可能存在冗余。
Laravel-Dockerfile
FROM php:7.4.24-apache #install all the system dependencies and enable PHP modules RUN apt-get update \ && apt-get install -y zlib1g-dev \ && apt-get install -y zip unzip \ && apt-get -y install libzip-dev libonig-dev \ && docker-php-ext-install pdo_mysql mysqli zip \ && docker-php-ext-enable mysqli \ && a2enmod rewrite ENV TZ=Asia/Tokyo RUN apt-get update && apt-get install -y \ busybox-static \ && apt-get clean #install composer RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer ENV COMPOSER_ALLOW_SUPERUSER 1 ENV COMPOSER_HOME /composer ENV PATH $PATH:/composer/vendor/bin #set our application folder as an environment variable ENV APP_HOME /var/www/html #change uid and gid of apache to docker user uid/gid RUN usermod -u 1000 www-data && groupmod -g 1000 www-data COPY ./php/vhost.conf /etc/apache2/conf-enabled/vhost.conf # enable apache module rewrite RUN a2enmod rewrite #copy source files and run composer COPY . $APP_HOME RUN mkdir bootstrap/sessions #RUN mkdir storage/framework/sessions && \ # mkdir storage/framework/views && \ # mkdir storage/framework/cache # install all PHP dependencies RUN composer install --no-dev --no-interaction #change ownership of our applications RUN chown -R www-data:www-data $APP_HOME # chmod -R 0777 bootstrap && \ # chmod -R 0777 storage RUN mv .env.production .env EXPOSE 80
MariaDB-Dockerfile
FROM mariadb:10.4 ENV MYSQL_USER=dbuser \ MYSQL_PASSWORD=**** \ MYSQL_DATABASE=simplememo \ MYSQL_ROOT_PASSWORD=**** COPY ./init.sql /docker-entrypoint-initdb.d EXPOSE 3306
ECS任务定义
{ "ipcMode": null, "executionRoleArn": "arn:aws:iam::995962138333:role/ecsTaskExecusionRole", "containerDefinitions": [ { "dnsSearchDomains": null, "environmentFiles": null, "logConfiguration": { "logDriver": "awslogs", "secretOptions": null, "options": { "awslogs-group": "/ecs/fargate-laravel", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "ecs" } }, "entryPoint": null, "portMappings": [ { "hostPort": 80, "protocol": "tcp", "containerPort": 80 } ], "command": null, "linuxParameters": null, "cpu": 0, "environment": [ { "name": "DB_DATABASE", "value": "simplememo" }, { "name": "DB_HOST", "value": "localhost" }, { "name": "DB_PASSWORD", "value": "simplememodbuse" }, { "name": "DB_USER", "value": "dbuser" } ], "resourceRequirements": null, "ulimits": null, "dnsServers": null, "mountPoints": [], "workingDirectory": null, "secrets": null, "dockerSecurityOptions": null, "memory": null, "memoryReservation": 127, "volumesFrom": [], "stopTimeout": null, "image": "995962138333.dkr.ecr.ap-northeast-1.amazonaws.com/laravelecs:latest", "startTimeout": null, "firelensConfiguration": null, "dependsOn": null, "disableNetworking": null, "interactive": null, "healthCheck": null, "essential": true, "links": null, "hostname": null, "extraHosts": null, "pseudoTerminal": null, "user": null, "readonlyRootFilesystem": null, "dockerLabels": null, "systemControls": null, "privileged": null, "name": "laravel" }, { "dnsSearchDomains": null, "environmentFiles": null, "logConfiguration": { "logDriver": "awslogs", "secretOptions": null, "options": { "awslogs-group": "/ecs/fargate-laravel", "awslogs-region": "ap-northeast-1", "awslogs-stream-prefix": "ecs" } }, "entryPoint": null, "portMappings": [ { "hostPort": 3306, "protocol": "tcp", "containerPort": 3306 } ], "command": null, "linuxParameters": null, "cpu": 0, "environment": [], "resourceRequirements": null, "ulimits": null, "dnsServers": null, "mountPoints": [], "workingDirectory": null, "secrets": null, "dockerSecurityOptions": null, "memory": null, "memoryReservation": 128, "volumesFrom": [], "stopTimeout": null, "image": "995962138333.dkr.ecr.ap-northeast-1.amazonaws.com/mariadb:latest", "startTimeout": null, "firelensConfiguration": null, "dependsOn": null, "disableNetworking": null, "interactive": null, "healthCheck": null, "essential": true, "links": null, "hostname": null, "extraHosts": null, "pseudoTerminal": null, "user": null, "readonlyRootFilesystem": null, "dockerLabels": null, "systemControls": null, "privileged": null, "name": "mariadb" } ], "placementConstraints": [], "memory": "512", "taskRoleArn": "arn:aws:iam::995962138333:role/ecsTaskExecusionRole", "compatibilities": [ "EC2", "FARGATE" ], "taskDefinitionArn": "arn:aws:ecs:ap-northeast-1:995962138333:task-definition/fargate-laravel:4", "family": "fargate-laravel", "requiresAttributes": [ { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.logging-driver.awslogs" }, { "targetId": null, "targetType": null, "value": null, "name": "ecs.capability.execution-role-awslogs" }, { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.ecr-auth" }, { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.docker-remote-api.1.19" }, { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.docker-remote-api.1.21" }, { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.task-iam-role" }, { "targetId": null, "targetType": null, "value": null, "name": "ecs.capability.execution-role-ecr-pull" }, { "targetId": null, "targetType": null, "value": null, "name": "com.amazonaws.ecs.capability.docker-remote-api.1.18" }, { "targetId": null, "targetType": null, "value": null, "name": "ecs.capability.task-eni" } ], "pidMode": null, "requiresCompatibilities": [ "FARGATE" ], "networkMode": "awsvpc", "cpu": "256", "revision": 4, "status": "ACTIVE", "inferenceAccelerators": null, "proxyConfiguration": null, "volumes": [] }
已尝试的排查操作
- 将数据库连接的主机名改为127.0.0.1
- 确认MariaDB的Dockerfile中已配置EXPOSE 3306
- 登录Fargate上的MariaDB容器确认simplememo数据库已存在
- 从Laravel容器侧确认localhost:3306处于监听状态
- 尝试将DB_HOST设为0.0.0.0,依然无法连接
补充信息
- ECS集群:基于Fargate部署
- Fargate平台版本:1.4.0
- PHP版本:7.4
- Laravel版本:8.4
- MariaDB版本:10.4
已确认MariaDB服务正常监听端口,尝试多种配置均无法解决问题,恳请各位提供排查思路或解决方案,非常感谢。
解决方案
你遇到的SQLSTATE[HY000] [2002] No such file or directory报错是PHP的MySQL驱动默认逻辑导致的:当DB_HOST配置为localhost时,PHP会优先尝试通过Unix套接字文件连接数据库,而非TCP网络。同一Fargate任务内的容器仅共享网络命名空间,文件系统是完全隔离的,Laravel容器里自然找不到MariaDB容器内的套接字文件,就会抛出这个错误。
按以下步骤修改即可解决:
- 修正数据库连接配置
直接在ECS任务定义的Laravel容器环境变量里做两处修改:
- 将
DB_HOST的值从localhost改为127.0.0.1,强制走TCP连接 - 新增环境变量
DB_SOCKET,值设为空字符串"",禁用套接字连接逻辑
如果是直接修改.env文件,对应添加DB_SOCKET=即可。
- 补全容器启动依赖
你当前的任务定义没有配置启动顺序,可能出现Laravel容器启动完成时MariaDB还没完成初始化的情况,导致首次连接失败。在Laravel容器的定义段新增dependsOn配置:
"dependsOn": [ { "containerName": "mariadb", "condition": "STARTED" } ]
- 验证连通性
修改配置重新部署任务后,可以进入Laravel容器手动执行命令验证连通性:mysql -h127.0.0.1 -udbuser -psimplememodbuse simplememo
如果可以正常进入数据库命令行,说明配置已经生效,再执行php artisan migrate就不会报连接错误了。
额外优化建议
当前把MariaDB和应用放在同一个Fargate任务里的部署方式仅适合临时测试:任务重启、漂移时MariaDB容器的数据会全部丢失。生产环境建议将数据库替换为RDS for MariaDB,或者给MariaDB容器挂载EFS持久化存储数据。
内容的提问来源于stack exchange,提问作者chida
相关产品推荐
相关产品推荐

