Docker构建指定https_proxy后wget仍无法连接远程主机问题
问题
在VM外部执行export https_proxy=http://proxy-fg:8080/后,wget可正常下载PostgreSQL 13.13源码包;但执行docker build --build-arg https_proxy="http://proxy-fg:8080/"构建镜像时,构建阶段的wget命令无法连接远程主机,出现超时错误。
VM外部wget执行日志
[root@LQL-BDDBAS01 pg13]# export https_proxy=http://proxy-fg:8080/ [root@LQL-BDDBAS01 pg13]# wget -O postgresql.tar.bz2 "https://ftp.postgresql.org/pub/source/v13.13/postgresql-13.13.tar.bz2" --2024-03-25 17:42:23-- https://ftp.postgresql.org/pub/source/v13.13/postgresql-13.13.tar.bz2 解析proxy-fg (proxy-fg)... 10.1.100.254 连接到proxy-fg (proxy-fg)|10.1.100.254|:8080... 已连接。 已发送Proxy请求,正在等待响应... 200 OK 大小:21563452 (21M) [application/octet-stream] 保存到:«postgresql.tar.bz2» postgresql.tar.bz2 100%[=================================================================================================================>] 20.56M 5.79MB/s 用时3.6s 2024-03-25 17:42:28 (5.79 MB/s) — «postgresql.tar.bz2» 已保存 [21563452/21563452]
Docker构建执行日志
[root@LQL-BDDBAS01 pg13]# docker build --build-arg https_proxy="http://proxy-fg:8080/" --tag postgres13:alpine3.18 . [+] Building 132.4s (8/12) docker:default => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 8.07kB 0.0s => [internal] load metadata for docker.io/library/alpine:3.18 1.1s => [1/8] FROM docker.io/library/alpine:3.18@sha256:11e21d7b981a59554b3f822c49f6e9f57b6068bb74f49c4cd5cc4c663c7e5160 0.0s => [internal] load build context 0.0s => => transferring context: 102B 0.0s => CACHED [2/8] RUN set -eux; addgroup -g 70 -S postgres; adduser -u 70 -S -D -G postgres -H -h /var/lib/postgresql -s /bin/sh postgres; mkdir -p /var/lib/postgresql; chown -R postgres:postgres 0.0s => CACHED [3/8] RUN mkdir /docker-entrypoint-initdb.d 0.0s => ERROR [4/8] RUN set -eux; wget -O postgresql.tar.bz2 "https://ftp.postgresql.org/pub/source/v13.13/postgresql-13.13.tar.bz2"; echo "8af69c2599047a2ad246567d68ec4131aef116954d8c3e469e9789080b 131.2s ------ > [4/8] RUN set -eux; wget -O postgresql.tar.bz2 "https://ftp.postgresql.org/pub/source/v13.13/postgresql-13.13.tar.bz2"; echo "8af69c2599047a2ad246567d68ec4131aef116954d8c3e469e9789080b37a474 *postgresql.tar.bz2" | sha256sum -c -; mkdir -p /usr/src/postgresql; tar --extract --file postgresql.tar.bz2 --directory /usr/src/postgresql --strip-components 1 ; rm postgresql.tar.bz2; apk add --no-cache --virtual .build-deps llvm15-dev clang15 bison coreutils dpkg-dev dpkg flex g++ gcc krb5-dev libc-dev libedit-dev libxml2-dev libxslt-dev linux-headers make openldap-dev openssl-dev perl-dev perl-ipc-run perl-utils python3-dev tcl-dev util-linux-dev zlib-dev icu-dev ; cd /usr/src/postgresql; awk '$1 == "#define" && $2 == "DEFAULT_PGSOCKET_DIR" && $3 == "\"/tmp\"" { $3 = "\"/var/run/postgresql\""; print; next } { print }' src/include/pg_config_manual.h > src/include/pg_config_manual.h.new; grep '/var/run/postgresql' src/include/pg_config_manual.h.new; mv src/include/pg_config_manual.h.new src/include/pg_config_manual.h; gnuArch="$(dpkg-architecture --query DEB_BUILD_GNU_TYPE)"; wget -O config/config.guess 'https://git.savannah.gnu.org/cgit/config.git/plain/config.guess?id=7d3d27baf8107b630586c962c057e22149653deb'; wget -O config/config.sub 'https://git.savannah.gnu.org/cgit/config.git/plain/config.sub?id=7d3d27baf8107b630586c962c057e22149653deb'; export LLVM_CONFIG="/usr/lib/llvm15/bin/llvm-config"; export CLANG=clang-15; ./configure --enable-option-checking=fatal --build="$gnuArch" --enable-integer-datetimes --enable-thread-safety --enable-tap-tests --disable-rpath --with-uuid=e2fs --with-gnu-ld --with-pgport=5432 --with-system-tzdata=/usr/share/zoneinfo --prefix=/usr/local --with-includes=/usr/local/include --with-libraries=/usr/local/lib --with-gssapi --with-ldap --with-tcl --with-perl --with-python --with-openssl --with-libxml --with-libxslt --with-icu --with-llvm ; make -j "$(nproc)" world; make install-world; make -C contrib install; runDeps="$( scanelf --needed --nobanner --format '%n#p' --recursive /usr/local | tr ',' ' ' | sort -u | awk 'system("[ -e /usr/local/lib/" $1 " ]") == 0 { next } { print "so:" $1 }' | grep -v -e perl -e python -e tcl )"; apk add --no-cache --virtual .postgresql-rundeps $runDeps bash su-exec tzdata zstd icu-data-full $([ "$(apk --print-arch)" != 'ppc64le' ] && echo 'nss_wrapper') ; apk del --no-network .build-deps; cd /; rm -rf /usr/src/postgresql /usr/local/share/doc /usr/local/share/man ; echo '{"spdxVersion":"SPDX-2.3","SPDXID":"SPDXRef-DOCUMENT","name":"postgres-sbom","packages":[{"name":"postgres","versionInfo":"13.13","SPDXID":"SPDXRef-Package--postgres","externalRefs":[{"referenceCategory":"PACKAGE-MANAGER","referenceType":"purl","referenceLocator":"pkg:generic/postgres@13.13?os_name=alpine&os_version=3.18"}],"licenseDeclared":"PostgreSQL"}]}' > /usr/local/postgres.spdx.json ; postgres --version: 0.312 + wget -O postgresql.tar.bz2 https://ftp.postgresql.org/pub/source/v13.13/postgresql-13.13.tar.bz2 0.371 Connecting to ftp.postgresql.org (147.75.85.69:443) 131.1 wget: can't connect to remote host (147.75.85.69): Operation timed out ------ Dockerfile:34
原因分析
- 构建参数未在RUN阶段生效:
--build-arg仅传递参数到构建上下文,但如果Dockerfile中没有显式声明ARG https_proxy并将其设置为环境变量,RUN命令中的wget无法读取到代理配置,导致直接尝试连接目标主机而非走代理。 - 容器内部DNS解析失败:VM外部能解析
proxy-fg到10.1.100.254,但容器默认的DNS配置可能无法解析该主机名,导致wget无法找到代理服务器,只能直接连接目标地址超时。 - Docker网络隔离限制:默认的bridge网络与VM主机网络隔离,容器可能无法访问VM内部的代理服务器,或者代理服务器拒绝来自容器网络的请求。
解决办法
方法一:在Dockerfile中显式使用构建参数
修改Dockerfile,先声明构建参数,再在RUN命令中设置代理环境变量:
ARG https_proxy RUN set -eux; \ export https_proxy=$https_proxy; \ wget -O postgresql.tar.bz2 "https://ftp.postgresql.org/pub/source/v13.13/postgresql-13.13.tar.bz2"; \ # 后续原有命令...
或者直接给wget指定代理参数:
ARG https_proxy RUN set -eux; \ wget -O postgresql.tar.bz2 "https://ftp.postgresql.org/pub/source/v13.13/postgresql-13.13.tar.bz2" --proxy=$https_proxy; \ # 后续原有命令...
方法二:使用代理IP代替主机名
既然VM外部能解析proxy-fg到10.1.100.254,直接用IP避免DNS解析问题:
docker build --build-arg https_proxy="http://10.1.100.254:8080/" --tag postgres13:alpine3.18 .
同时确保Dockerfile中声明ARG https_proxy并在RUN中使用。
方法三:使用主机网络构建
让构建过程使用主机的网络栈,消除网络隔离问题:
docker build --network host --build-arg https_proxy="http://proxy-fg:8080/" --tag postgres13:alpine3.18 .
注:该方法在Windows/macOS的Docker Desktop上可能存在兼容性问题,需根据实际环境调整。
方法四:全局配置Docker守护进程代理
编辑Docker守护进程配置文件/etc/docker/daemon.json:
{ "proxies": { "default": { "httpsProxy": "http://proxy-fg:8080/" } } }
重启Docker服务使配置生效:
systemctl restart docker
之后所有构建和容器运行都会自动使用该代理,无需每次传递--build-arg。
内容的提问来源于stack exchange,提问作者Linna
相关产品推荐
相关产品推荐

