Docker MySQL Github Actions 连接被拒绝

5
我已经将我的应用程序运行在docker中,并设置了Github Actions来运行我的测试。为了运行Behat测试,我有一个单独的测试数据库,因此需要使用一个单独的.env文件。
在.env.test文件中:
DATABASE_URL=mysql://root:emc@mysql:3306/emc_test?serverVersion=5.7

在docker-compose.test.yml中。
version: "3.7"
services:

  mysql:
    build:
      context: docker/mysql
      dockerfile: Dockerfile
    volumes:
      - mysql-data:/var/lib/mysql
    environment:
      MYSQL_ROOT_PASSWORD: emc
      MYSQL_USER: emc
      MYSQL_PASSWORD: emc
      MYSQL_DATABASE: emc
      TZ: Europe/Brussels
    ports:
      - "3306:3306"
    networks:
      - backend

  cli:
    image: christianvermeulen/itexperts:latest
    volumes:
      - .:/application:cached
      - app-cache:/application/var/cache
      - composer:/composer
    networks:
      - backend

volumes:
  composer:
  app-cache:
  mysql-data:

networks:
  backend:

一旦我访问数据库,就会得到一个连接被拒绝的错误。在Symfony中,我已经设置了以下测试命令:

<?php
declare(strict_types=1);

namespace Development\Cli;

use Development\Fixtures\LoadFixtures;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\DBALException;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class TestDBCommand extends Command
{
    protected static $defaultName = 'test:db';
    /**
     * @var Connection
     */
    private Connection $connection;

    public function __construct(Connection $connection)
    {
        parent::__construct();
        $this->connection = $connection;
    }

    public function execute(InputInterface $input, OutputInterface $output)
    {
        $io = new SymfonyStyle($input, $output);
        $io->title('Testing Database');

        $io->note('Username: '.$this->connection->getUsername());
        $io->note('Password: '.$this->connection->getPassword());
        $io->note('Host: '.$this->connection->getHost());

        try {
            $st = $this->connection->executeQuery('show databases;');
            $result = $st->fetchAll(\PDO::FETCH_ASSOC);
            foreach ($result as $key => $value) {
                $io->note($value);
            }
        } catch (DBALException $e) {
            $io->warning('Failed: '.$e->getMessage());
        }

        $io->success('All good');

        return 0;
    }
}

最后,我也想查看一些信息,因此在Github Actions中运行了以下命令:

- name: Prepare Testing
  run: |
    cp docker-compose.test.yml docker-compose.yml
    docker-compose build
    docker-compose up -d
    docker-compose ps
    docker-compose run --rm cli ping -c 5 mysql
    docker-compose run --rm mysql env | sort
    docker-compose run --rm -e APP_ENV=test cli bin/console test:db

输出结果为:
   Name                 Command              State                  Ports              
---------------------------------------------------------------------------------------
emc_cli_1     docker-php-entrypoint php -a   Exit 0                                    
emc_mysql_1   docker-entrypoint.sh mysqld    Up       0.0.0.0:3306->3306/tcp, 33060/tcp


PING mysql (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.170 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.066 ms
64 bytes from 172.18.0.3: seq=2 ttl=64 time=0.092 ms
64 bytes from 172.18.0.3: seq=3 ttl=64 time=0.100 ms
64 bytes from 172.18.0.3: seq=4 ttl=64 time=0.070 ms

--- mysql ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max = 0.066/0.099/0.170 ms


GOSU_VERSION=1.12
HOME=/root
HOSTNAME=7656ccf87670
MYSQL_DATABASE=emc_test
MYSQL_MAJOR=5.7
MYSQL_PASSWORD=emc
MYSQL_ROOT_PASSWORD=emc
MYSQL_USER=emc
MYSQL_VERSION=5.7.30-1debian10
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
SHLVL=0
TZ=Europe/Brussels

Testing Database
================

 ! [NOTE] Username: root                                                         

 ! [NOTE] Password: emc                                                         

 ! [NOTE] Host: mysql                                                           

 [WARNING] Failed: An exception occurred in driver: SQLSTATE[HY000] [2002]      
           Connection refused                                                   

 [OK] All good

简而言之,我已验证:

  • 主机名正确
  • 预期的用户名和密码是正确的
  • 端口3306被映射(虽然在内部不应该需要)
  • mysql容器正在运行
  • cli容器可以从网络上到达(pingable)mysql
  • mysql容器对设置具有正确的环境变量

最后,我在准确的代码上进行了2次运行,结果却不同。Github Actions上可能存在什么变量问题?

Failure Success

为什么我的连接被拒绝?

1个回答

12

如果有其他人也在为此烦恼,那么问题的原因是mysql容器已经成功启动,但是mysql本身需要更多时间来启动和运行。

因此,ping测试正常,环境变量正常,容器正在运行,但是mysql服务尚未启动(尚未完全启动)。

在自动化环境(例如CI流水线)中进行此操作时,速度比本地主机等手动环境快得多。

解决方案:重新排列您的命令,以便给mysql更多的启动时间,或者添加短暂的2秒休眠。


1
谢谢你帮我避免头疼! - Bernard Wiesner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接