如何在代理后面的 dockerfile 中运行‘ apt-get’?

我正在使用 docker (版本0.8.1,构建 a1598d1)运行一个虚拟机(Ubuntu13.10)。我试图用 dockerfile 构建一个映像。首先,我想更新包(使用下面的代码-代理是混淆的) ,但 apt-get超时与错误: Could not resolve 'archive.ubuntu.com'

FROM ubuntu:13.10
ENV HTTP_PROXY <HTTP_PROXY>
ENV HTTPS_PROXY <HTTPS_PROXY>
RUN export http_proxy=$HTTP_PROXY
RUN export https_proxy=$HTTPS_PROXY
RUN apt-get update && apt-get upgrade

我还在主机系统中运行了以下命令:

sudo HTTP_PROXY=http://<PROXY_DETAILS>/ docker -d &

主机能够毫无问题地运行 apt-get

如何更改 dockerfile 以允许它从容器内到达 ubuntu 服务器?

更新

我在 CentOS 中运行代码(将 FROM ubuntu:13.10改为 FROM centos) ,它工作得很好。这似乎是 Ubuntu 的一个问题。

135650 次浏览

更新 :

你在 ENV 中的环境变量大写错误。正确的一个是 http_proxy。你的例子应该是:

FROM ubuntu:13.10
ENV http_proxy <HTTP_PROXY>
ENV https_proxy <HTTPS_PROXY>
RUN apt-get update && apt-get upgrade

或者

FROM centos
ENV http_proxy <HTTP_PROXY>
ENV https_proxy <HTTPS_PROXY>
RUN yum update

ENV 中指定的所有变量都预置在每个 RUN 命令之前。每个 RUN 命令都在自己的容器/环境中执行,因此它不会从以前的 RUN 命令继承变量!

注意: 不需要使用代理调用 docker 守护进程来工作,尽管如果你想拉图片等,你也需要为 docker 守护进程设置代理。您可以在 Ubuntu 的 /etc/default/docker中为守护进程设置代理(它不影响容器设置)。


而且,如果您使用 在主机上运行代理服务器(即 localhost,127.0.0.1) ,也可能发生这种情况。主机上的本地主机与容器中的本地主机不同。在这种情况下,需要使用另一个 IP (比如172.17.42.1)将代理绑定到0.0.0.0,或者如果绑定到0.0.0.0,则可以在 docker build期间使用172.17.42.1而不是127.0.0.1进行容器连接。

您还可以在这里找到一个示例: 如何使用缓存快速重建 dockerfile?

我也遇到了同样的问题,并且找到了另一个解决办法: 我有一个供应商脚本,这是从 Docker 构建环境中添加的。 在脚本中,我根据 ping 检查来设置环境变量:

文件:

ADD script.sh /tmp/script.sh
RUN /tmp/script.sh

Script.sh:

if ping -c 1 ix.de ; then
echo "direct internet doing nothing"
else
echo "proxy environment detected setting proxy"
export http_proxy=<proxy address>
fi

这还是有点粗糙,但对我有效

2018年2月10日更新

有了新的功能在多克选项 --config,你不需要在 Dockerfile 设置代理,你可以有 相同的 Dockerfile 在企业环境中使用或不使用代理设置

命令 docker run选项:

--config string      Location of client config files (default "~/.docker")

或环境变量

`DOCKER_CONFIG` The location of your client configuration files.


$ export DOCKER_CONFIG=~/.docker

Https://docs.docker.com/engine/reference/commandline/cli/

Https://docs.docker.com/network/proxy/

我建议使用 httpProxy, httpsProxy, ftpProxynoProxy设置代理(官方文档遗漏了有时很有用的变量 ftpProxy)

{
"proxies":
{
"default":
{
"httpProxy": "http://192.168.1.12:3128",
"httpsProxy": "http://192.168.1.12:3128",
     "ftpProxy": "http://192.168.1.12:3128",
"noProxy": "*.test.example.com,.example2.com,127.0.0.0/8"
}
}
}

为您的代理环境调整代理 IP 和端口并保存到 ~/.docker/config.json

正确设置之后,可以像正常一样运行 docker build 和 docker run。

$ cat Dockerfile


FROM alpine


$ docker build -t demo .
    

$ docker run -ti --rm demo env|grep -ri proxy
(standard input):HTTP_PROXY=http://192.168.1.12:3128
(standard input):http_proxy=http://192.168.1.12:3128
(standard input):HTTPS_PROXY=http://192.168.1.12:3128
(standard input):https_proxy=http://192.168.1.12:3128
(standard input):NO_PROXY=*.test.example.com,.example2.com,127.0.0.0/8
(standard input):no_proxy=*.test.example.com,.example2.com,127.0.0.0/8
(standard input):FTP_PROXY=http://192.168.1.12:3128
(standard input):ftp_proxy=http://192.168.1.12:3128

旧答案(退役)

下面在 Dockerfile 的设置适合我,我测试了 CoreOSVagrantboot2docker,假设代理端口是 3128

在森托斯:

ENV http_proxy=ip:3128
ENV https_proxy=ip:3128

在 Ubuntu 中: ENV http _ proxy‘ http://ip: 3128’ ENV https _ xy‘ http://ip: 3128’

小心格式,有些有 http,有些没有,有些只有一个配额。如果 IP 地址是192.168.0.193,则设置为:

在森托斯:

ENV http_proxy=192.168.0.193:3128
ENV https_proxy=192.168.0.193:3128

在 Ubuntu 中: 环境影响评估网站 http _ proxy’http://192.168.0.193:3128’ 环境影响评估(ENV) https _ proxy’http://192.168.0.193:3128’

# # # 如果你需要设置代理在核心,例如拉图像

cat /etc/systemd/system/docker.service.d/http-proxy.conf


[Service]
Environment="HTTP_PROXY=http://192.168.0.193:3128"

我们在做..。

ENV http_proxy http://9.9.9.9:9999
ENV https_proxy http://9.9.9.9:9999

在 dockerfile 的最后。

ENV http_proxy ""
ENV https_proxy ""

目前(直到 docker 引入了 build env vars) ,这允许代理 env vars 仅用于构建,而不必公开它们

解决方案的替代方案不是在代理后本地构建映像,而是让 docker 使用 docker“自动构建”为您构建映像。由于 Docker 没有在代理后面构建映像,这个问题就得到了解决。自动构建的示例可以在..。

Https://GITHUB.com/danday74/docker-nginx-lua

Https://registry.hub.DOCKER.com/u/danday74/nginx-lua (DOCKER repo 正在使用自动构建来监视 github repo,并在推送到 github 主分支的过程中进行 DOCKER 构建)

文件夹中的任何 apt-get 命令之前,应该放置这一行

COPY apt.conf /etc/apt/apt.conf

不要忘记在你拥有 文件夹的同一个文件夹中创建 Apt.confApt.conf文件的内容应该是这样的:

Acquire::socks::proxy "socks://YOUR-PROXY-IP:PORT/";
Acquire::http::proxy "http://YOUR-PROXY-IP:PORT/";
Acquire::https::proxy "http://YOUR-PROXY-IP:PORT/";

如果您使用用户名和密码连接到代理,那么 apt.conf 应该如下所示:

Acquire::socks::proxy "socks://USERNAME:PASSWORD@YOUR-PROXY-IP:PORT/";
Acquire::http::proxy "http://USERNAME:PASSWORD@YOUR-PROXY-IP:PORT/";
Acquire::https::proxy "http://USERNAME:PASSWORD@YOUR-PROXY-IP:PORT/";

例如:

Acquire::https::proxy "http://foo:bar@127.0.0.1:8080/";

其中 是用户名,酒吧是密码。

如果你想为 wget 设置代理,你应该把这些行放在你的 文件夹

ENV http_proxy YOUR-PROXY-IP:PORT/
ENV https_proxy YOUR-PROXY-IP:PORT/
ENV all_proxy YOUR-PROXY-IP:PORT/

正如 Tim Potter 指出的,在 dockerfile 中设置代理是可怕的。在构建映像时,您需要为您的公司网络添加代理,但是您可能部署在不需要代理或代理服务器不同的云或 DMZ 中。

此外,您不能与公司以外的其他人分享您的形象。

当您希望使用 Dockerfile 生成时,可以使用 --build-arg选项。

https://github.com/docker/docker/issues/14634上的链接中,可以看到“ Build with —— Build-arg with multiHTTP _ PROXY”部分:

[root@pppdc9prda2y java]# docker build
--build-arg https_proxy=$HTTP_PROXY --build-arg http_proxy=$HTTP_PROXY
--build-arg HTTP_PROXY=$HTTP_PROXY --build-arg HTTPS_PROXY=$HTTP_PROXY
--build-arg NO_PROXY=$NO_PROXY  --build-arg no_proxy=$NO_PROXY -t java .

注意: 在您自己的系统上,确保已经设置了 HTTP _ PROXY 和 NO _ PROXY 环境变量。

使用-build-arg 小写环境变量:

docker build --build-arg http_proxy=http://proxy:port/ --build-arg https_proxy=http://proxy:port/ --build-arg ftp_proxy=http://proxy:port --build-arg no_proxy=localhost,127.0.0.1,company.com -q=false .

正如其他答案所暗示的那样,--build-arg可能是解决方案。 在我的例子中,我必须在 --build-arg选项之外添加 --network=host

docker build -t <TARGET> --build-arg http_proxy=http://<IP:PORT> --build-arg https_proxy=http://<IP:PORT> --network=host .

如果您有正确设置的代理,但仍然无法达到互联网,这可能是 DNS 解决方案。检查主机 Ubuntu VM 上的 /etc/resolve.conf。如果它包含 nameserver 127.0.1.1,那是错误的。

在主机 Ubuntu VM 上运行以下命令来修复它:

sudo vi /etc/NetworkManager/NetworkManager.conf
# Comment out the line `dns=dnsmasq` with a `#`


# restart the network manager service
sudo systemctl restart network-manager


cat /etc/resolv.conf

现在 /etc/resolv.conf应该有一个名称服务器的有效值,这个值将由 docker 容器复制。

与@Reza Farshi 提供的答案相比,一个小小的替代方案(在我的例子中效果更好)是使用 echo通过 Dockerfile 将代理设置写到 /etc/apt/apt.conf,例如:

FROM ubuntu:16.04


RUN echo "Acquire::http::proxy \"$HTTP_PROXY\";\nAcquire::https::proxy \"$HTTPS_PROXY\";" > /etc/apt/apt.conf


# Test that we can now retrieve packages via 'apt-get'
RUN apt-get update

这种方法的优点是代理地址可以在构建映像时动态传入,而不必从主机复制设置文件。

例如:。

docker build --build-arg HTTP_PROXY=http://<host>:<port> --build-arg HTTPS_PROXY=http://<host>:<port> .

根据 码头造型文件。