Я использую внутренний веб-сервер PHP внутри контейнера Docker на основе Alpine 3.8.
Это обслуживает простую страницу, которая:
<!DOCTYPE html>
<html>
<head>
<title>Test page</title>
</head>
<body>
<div>
This is a 'hello world' for my CD container.
</div>
<p>
Version: <?php echo getenv('CD_DEMO_VERSION') ?>
</p>
<p>
GUID: <?php echo file_get_contents(__DIR__ . '/guid.txt') ?>
</p>
</body>
</html>
У меня есть это в процессе сборки CircleCI, и PHPUnit читает HTML, используя simplexml_load_string()
, чтобы проверить, работает ли он. В большинстве случаев это нормально, но иногда он добавляет в начало или конец HTML смещение управляющих символов, что приводит к сбою синтаксического анализа HTML. Я бы сказал, что это происходит в 10% случаев, поэтому его сложно воспроизвести. Кажется, это не происходит локально.
В этом процессе сборки я жду запуска веб-сервера, поэтому я не думаю, что здесь происходит гонка.
Если в начале происходит смещение, это выглядит следующим образом (моя выходная каретка подкачки возвращается к символу ⏎
, процессор XML этого не видит):
^@^@<html>⏎ <head>⏎ <title>Test page</title>⏎ </head>⏎ <body>⏎ <div>⏎ This is a 'hello world' for my CD container.⏎ </div>⏎ <p>⏎ Version: </p>⏎ <p>⏎ GUID: 47294362a6154e9a5397a9f9b72cefe1d349ec2e31de12e6084746a084e4e4ef </p>⏎ </body>⏎</html>
Если в конце появляется крест, это выглядит так:
<!DOCTYPE html>⏎<html>⏎ <head>⏎ <title>Test page</title>⏎ </head>⏎ <body>⏎ <div>⏎ This is a 'hello world' for my CD container.⏎ </div>⏎ <p>⏎ Version: </p>⏎ <p>⏎ GUID: a721f44d05e93debb593eef135fc664fb6b0d3aa6a04d50af7f17339d0d75399 </p>⏎ </body>⏎</html>⏎^@^@
Я не знаю, являются ли они действительными окружностями и символами, или это то, как случайные вещи отображаются на моем экране.
Похоже, веб-сервер обслуживает заголовок набора символов UTF-8.
Я думаю, что мой тест PHPUnit уместен, поэтому я добавлю его сюда. Из-за способа, которым работает CircleCI, я не могу опубликовать порт Docker снаружи контейнера, поэтому я использую docker exec
для выполнения HTTP-операции изнутри:
public function testApp()
{
// Get the page and convert it to an XML object
$html = $this->getWebPage();
// CI is giving me some parsing issues, so let's see it
echo str_replace("\n", "⏎", $html);
$doc = simplexml_load_string($html);
$message = trim((string) $doc->body->div);
$this->assertEquals(
"This is a 'hello world' for my CD container.",
$message
);
}
protected function getWebPage()
{
$output = $return = null;
$command = sprintf(
'docker exec -ti %s php -r "echo file_get_contents(\'http://localhost\');"',
escapeshellarg($this->getRepoName())
);
exec($command, $output, $return);
// Check return value first
if ($return)
{
throw new RuntimeException(
sprintf(
'Returned a failure exit code %d on Docker operation',
$return
)
);
}
$imploded = implode(PHP_EOL, $output);
return $imploded;
}
Обновление
Я обновил до Apache 2.4.x внутри Alpine 3.8, и, к моему большому удивлению, у меня точно такая же проблема. Таким образом, оказывается, что это не веб-сервер PHP.
Я также попробовал Alpine 3.7, тот же результат снова. Я попробовал Ubuntu 18.10, снова то же самое.
Я пробовал php -r
с file_get_contents()
и wget
в качестве HTTP-устройств внутри контейнера.
Теперь я склонен думать, что захват стандартного вывода из docker exec
виноват. Я предполагаю, что если я настрою свои тесты в другом образе и запустим контейнеры с помощью Docker Compose, это, вероятно, будет работать. Или я мог бы использовать docker exec
, записать в файл контейнера, а затем отправить файл с помощью docker cp
.
Хотя было бы интересно узнать, что происходит не так.