Linux 上 Azure 应用服务上 Wordpress 上的“cURL 错误 28:解决超时”

Posted

技术标签:

【中文标题】Linux 上 Azure 应用服务上 Wordpress 上的“cURL 错误 28:解决超时”【英文标题】:"cURL error 28: Resolving timed out" on Wordpress on Azure App Service on Linux 【发布时间】:2018-02-19 16:37:49 【问题描述】:

我使用自定义 Docker 容器在 Linux 上的 Azure 应用服务上安装 Wordpress 的响应时间非常慢。页面加载大约需要 20-40 秒。

我安装了一个故障排除插件,当向以下 URL 发出请求时,它表明问题是“cURL 错误 28:在 N 毫秒后解决超时”

https://api.wordpress.org/core/version-check/1.7/ http://api.wordpress.org/core/version-check/1.7/ https://api.wordpress.org/plugins/update-check/1.1/ http://api.wordpress.org/plugins/update-check/1.1/ https://api.wordpress.org/themes/update-check/1.1/ http://api.wordpress.org/themes/update-check/1.1/

cURL 在 scm-site 命令行上运行良好。例如,这可以正常工作。

curl -X POST http://api.wordpress.org/core/version-check/1.7/

编辑 如果我 ssh 进入容器并运行这个 php 代码,它工作正常。

<?php

$url = 'http://api.wordpress.org/core/version-check/1.7/';

$fields = array(
    'version' => urlencode('4.8.1'),
    'php' => urlencode('7.1.8'),
    'locale' => urlencode('fi'),
    'mysql' => urlencode('5.6.26.0'),
    'local_package' => urlencode('fi'),
    'blogs' => urlencode('1'),
    'users' => urlencode('4'),
    'multisite_enabled' => urlencode('0'),
    'initial_db_version' => urlencode('26691')
);

foreach($fields as $key=>$value)  $fields_string .= $key.'='.$value.'&'; 
rtrim($fields_string, '&');

$ch = curl_init();

curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, TRUE);
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);

curl_exec($ch);

curl_close($ch);

它返回以下内容。

root@71c3bba3a35e:/home/site/wwwroot# php curl.php
"offers":["response":"upgrade","download":"http:\/\/downloads.wordpress.org\/release\/wordpress-4.8.1.zip","locale":"en_US","packages":"full":"http:\/\/downloads.wordpress.org\/release\/wordpres
s-4.8.1.zip","no_content":"http:\/\/downloads.wordpress.org\/release\/wordpress-4.8.1-no-content.zip","new_bundled":"http:\/\/downloads.wordpress.org\/release\/wordpress-4.8.1-new-bundled.zip","par
tial":false,"rollback":false,"current":"4.8.1","version":"4.8.1","php_version":"5.2.4","mysql_version":"5.0","new_bundled":"4.7","partial_version":false],"translations":[]

我的 Docker 镜像使用 php:7.1.8-apache。

这是我的 Dockerfile。

FROM php:7.1.8-apache
EXPOSE 80 443 2222

RUN apt-get update -y && apt-get install -y --no-install-recommends \
    ssl-cert \
    ca-certificates \
    apt-utils \
    vim \
    curl \
    mysql-client \
    openssh-server \
    libmcrypt-dev \
    libcurl4-gnutls-dev \
    libicu-dev \
&& docker-php-ext-install -j$(nproc) iconv \
mcrypt \
mysqli \
json \
mbstring \
curl \
intl \
&& echo "root:Docker!" | chpasswd \
&& ln -s /home/LogFiles /var/log/apache2

ENV APACHE_CONFDIR=/etc/apache2 \
APACHE_ENVVARS=/etc/apache2/envvars \
APACHE_LOCK_DIR=/var/lock/apache2 \
APACHE_LOG_DIR=/var/log/apache2 \
APACHE_RUN_DIR=/var/run/apache2 \
APACHE_PID_FILE=/var/run/apache2/apache2.pid \
APACHE_RUN_USER=www-data \
APACHE_RUN_GROUP=www-data

WORKDIR /usr/local
COPY config/wprun.sh config/wp-config.php /usr/local/
COPY config/sshd_config /etc/ssh/
COPY config/php.ini /usr/local/etc/php/


RUN chmod 755 wprun.sh && \
rm -R /var/www/html && \
a2enmod rewrite && \
a2enmod expires && \
a2enmod include && \
sed -i "s@/var/www@/home/site/wwwroot@" /etc/apache2/sites-enabled/000-default.conf && \
sed -i "s@/var/www@/home/site/wwwroot@" /etc/apache2/apache2.conf

CMD ["/bin/bash","wprun.sh"]

编辑 2 这个GitHub issue 看起来很相似。有一个建议使用OpenDNS resolvers。这可能是DNS问题吗?如果是这样,那么这如何与 Docker 和 Azure 一起工作?

编辑 3 这似乎是一个 DNS 问题。这是 Azure 中的 resolv.conf 文件。

search reddog.microsoft.com
nameserver 127.0.0.11
options timeout:1 attempts:5 ndots:0

当我将名称服务器更改为 8.8.8.8 时,页面会在一到两秒内加载。所有 cURL 错误也都消失了。

如果我理解正确,Docker mounts the host machine's resolv.conf file 和 DNS 设置应该使用 Docker 运行命令选项进行设置。不建议直接更改这些文件。

Docker 如何管理内部 DNS 配置的详细信息 容器可以从一个 Docker 版本更改为下一个版本。那么你 不应假设 /etc/hosts 等文件的方式, /etc/resolv.conf 在容器内管理并保留文件 单独使用以下 Docker 选项。

但是,似乎无法在 Azure 中设置 docker run 参数。

【问题讨论】:

你能进入 docker 容器并检查它是否有效吗?你是用 apache 和 wordpress 还是用 nginx 和 wordpress? 我更新了我的帖子。它似乎在容器内工作。我正在使用 apache。 【参考方案1】:

用于 curl 的 scm-site 命令行在 Azure WebApps for Linux 的主机上运行,​​而不是在 docker 容器内。

GitHub moby/moby 上有一个问题curl fails inside container on https connection,和你的很相似。据此,我认为您需要通过 PHP 方法 curl_setopt($curl, CURLOPT_SSL_CIPHER_LIST, 'TLSv1'); 为您在 Azure WebApp for Linux 的 docker 容器内的 curl 调用设置 --tlsv1 选项。

希望对你有帮助。

【讨论】:

根据这个 scm-site 应该在容器 SSH support for Azure Web Apps for Containers 内工作。我不太确定 GitHub 问题是否相似,因为我的 http 请求也有问题。 我尝试在我自己的机器上的容器内使用 php 运行 curl,它工作正常。我运行了与我的帖子中相同的脚本。

以上是关于Linux 上 Azure 应用服务上 Wordpress 上的“cURL 错误 28:解决超时”的主要内容,如果未能解决你的问题,请参考以下文章

为在 Azure App Service Linux 上运行的容器创建卷

开始生产芹菜工人。在 Azure/linux 应用服务上使用 Django/Python

正在修改或添加应用程序设置到在 linux 容器上运行的 azure 应用程序服务将回收站点

LINUX ON AZURE 安全建议(上)

哪个是基于NodeJS的Azure Web App(Linux)上运行的默认Web服务器?

在Linux上部署Java应用程序,通过Active Directory连接到Azure SQL Server