Symfony多容器项目执行Makefile初始化时MySQL连接被拒绝
解决Docker环境下Symfony初始化数据库连接拒绝问题
问题描述
我有一个包含React、PHP-Apache、MySQL数据库和PHPMyAdmin四个容器的Symfony项目,为简化部署流程编写了Makefile。执行make init命令时,其他步骤均正常,但创建数据库环节出现「SQLSTATE[HY000] [2002] Connection refused」错误。不过手动执行数据库创建命令时则无此问题,曾尝试通过循环等待确保MySQL容器端口开放,但并未解决问题。
可行解决方案
1. 替换端口等待为MySQL服务就绪检测
容器启动完成不代表MySQL服务已经可以处理连接请求,需要等待MySQL完全初始化完成。在Makefile中新增一个等待数据库就绪的目标,并在database-init前调用:
修改后的Makefile关键部分:
## —— 🐳 Docker —— docker-start: $(DOCKER_COMPOSE) up -d $(MAKE) wait-for-db wait-for-db: ## Wait for MySQL to be ready @echo "Waiting for MySQL database to be ready..." @until docker exec db_resrel mysqladmin ping -h "localhost" --silent; do \ sleep 2; \ done @echo "MySQL is ready!"
2. 为MySQL容器添加健康检查(可选但推荐)
在docker-compose.yml的db服务中添加健康检查,让Docker自动检测MySQL服务状态,确保后续服务只在数据库就绪后才执行操作:
修改后的docker-compose.yml关键部分:
services: db: image: mysql container_name: db_resrel restart: always volumes: - db-data:/var/lib/mysql environment: MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' networks: - dev healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] timeout: 20s retries: 10
同时,在www服务中添加depends_on的健康检查依赖:
www: build: docker container_name: www_resrel ports: - "8000:80" volumes: - ./docker/vhosts:/etc/apache2/sites-enabled - ./api:/var/www networks: - dev depends_on: db: condition: service_healthy
3. 验证.env文件的数据库配置
确保.env(从.env.example复制而来)中的数据库连接URL使用容器服务名作为主机:
DATABASE_URL="mysql://root:@db:3306/your_database_name?serverVersion=8.0&charset=utf8mb4"
完整修改后的代码示例
修改后的Makefile
# Variables DOCKER_COMPOSE = docker-compose EXEC = docker exec -it www_resrel bash NPM = $(EXEC) npm SYMFONY_CONSOLE = bin/console # Colors GREEN = /bin/echo -e "\x1b[32m\#\# $1\x1b[0m" RED = /bin/echo -e "\x1b[31m\#\# $1\x1b[0m" ## —— 🔥 App —— init: ## Init the project $(MAKE) docker-start cp .env.example .env $(MAKE) composer-install $(MAKE) database-init $(MAKE) jwt-keys @$(call GREEN,"Symfony is available at: http://127.0.0.1:8000/.") @$(call GREEN,"React is available at: http://127.0.0.1:3000/.") @$(call GREEN,"PhpMyAdmin is available at: http://127.0.0.1:8080/.") cache-clear: ## Clear cache $(EXEC) -c "bin/console cache:clear; exit" ## —— 🐳 Docker —— docker-start: $(DOCKER_COMPOSE) up -d $(MAKE) wait-for-db wait-for-db: ## Wait for MySQL to be ready @echo "Waiting for MySQL database to be ready..." @until docker exec db_resrel mysqladmin ping -h "localhost" --silent; do \ sleep 2; \ done @echo "MySQL is ready!" jwt-keys: ## Generate JWT keys $(EXEC) -c "bin/console lexik:jwt:generate-keypair" ## —— 🎻 Composer —— composer-install: ## Install dependencies composer install composer-update: ## Update dependencies $(COMPOSER) update ## —— 📊 Database —— database-init: ## Init database $(MAKE) database-drop $(MAKE) database-create $(MAKE) database-migrate $(MAKE) database-fixtures-load $(MAKE) database-drop-test $(MAKE) database-create-test $(MAKE) database-migrate-test $(MAKE) database-fixtures-load-test @$(call GREEN,"Database and test database have been initialized.") database-drop: ## Drop database $(EXEC) -c "bin/console d:d:d --force --if-exists" database-create: ## Create database $(EXEC) -c "bin/console d:d:c --if-not-exists" database-migration: ## Make migration $(EXEC) -c "bin/console make:migration" migration: ## Alias : database-migration $(EXEC) -c "bin/console database-migration" database-migrate: ## Migrate migrations $(EXEC) -c "bin/console d:m:m --no-interaction" migrate: ## Alias : database-migrate $(EXEC) -c "bin/console database-migrate" database-fixtures-load: ## Load fixtures $(EXEC) -c "bin/console d:f:l --no-interaction" fixtures: ## Alias : database-fixtures-load $(EXEC) -c "bin/console database-fixtures-load" ## —— 📊 Database test —— database-drop-test: ## Drop database $(EXEC) -c "bin/console d:d:d --env=test --force --if-exists" database-create-test: ## Create test database $(EXEC) -c "bin/console d:d:c --env=test --if-not-exists" database-migrate-test: ## Migrate migrations $(EXEC) -c "bin/console d:m:m --env=test --no-interaction" database-fixtures-load-test: ## Load test fixtures $(EXEC) -c "bin/console d:f:l --env=test --no-interaction" ## —— 🛠️ Others —— help: ## List of commands @grep -E '(^[a-zA-Z0-9_-]+:.*?##.*$$)|(^##)' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}{printf "\033[32m%-30s\033[0m %s\n", $$1, $$2}' | sed -e 's/\[32m##/[33m/'
修改后的docker-compose.yml
version: '3' services: db: image: mysql container_name: db_resrel restart: always volumes: - db-data:/var/lib/mysql environment: MYSQL_ALLOW_EMPTY_PASSWORD: 'yes' networks: - dev healthcheck: test: ["CMD", "mysqladmin", "ping", "-h", "localhost"] timeout: 20s retries: 10 phpmyadmin: image: phpmyadmin container_name: phpmyadmin_resrel depends_on: - db ports: - 8080:80 environment: PMA_HOST: db networks: - dev www: build: docker container_name: www_resrel ports: - "8000:80" volumes: - ./docker/vhosts:/etc/apache2/sites-enabled - ./api:/var/www networks: - dev depends_on: db: condition: service_healthy app: build: app container_name: app_resrel command: npm run dev ports: - "3000:3000" volumes: - ./app:/usr/src/app - /usr/src/app/node_modules networks: dev: volumes: db-data:
内容的提问来源于stack exchange,提问作者Halchimiste
相关产品推荐
相关产品推荐

