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

时间:2014-03-04 17:50:45

标签: docker apt http-proxy

我正在使用docker(版本0.8.1,构建a1598d1)运行虚拟机(Ubuntu 13.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的一个问题。

11 个答案:

答案 0 :(得分:79)

<强>更新

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 deamon设置代理。您可以在Ubuntu的/etc/default/docker中为守护进程设置代理(它不会影响容器设置)。


此外,如果在主机上运行代理(即localhost,127.0.0.1),也会发生这种情况。主机上的Localhost与容器中的localhost不同。在这种情况下,您需要使用另一个IP(如172.17.42.1)绑定您的代理,或者如果绑定到0.0.0.0,您可以在{{1}期间使用172.17.42.1而不是127.0.0.1来连接容器}。

您还可以在此处查找示例:How to rebuild dockerfile quick by using cache?

答案 1 :(得分:46)

于02/10/2018更新

使用docker选项--config中的新功能,您无需再在Dockerfile中设置Proxy。您可以在公司环境中使用相同的Dockerfile。

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

或环境变量DOCKER_CONFIG

`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设置代理。

{
 "proxies":
 {
   "default":
   {
     "httpProxy": "http://127.0.0.1:3001",
     "httpsProxy": "http://127.0.0.1:3001",
     "ftpProxy": "http://127.0.0.1:3001",
     "noProxy": "*.test.example.com,.example2.com"
   }
 }
}

根据需要调整代理IP和端口并保存到~/.docker/config.json

使用它正确设置后,您可以正常运行docker build和docker。

$ docker build -t demo . 

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

旧答案

Dockerfile中的以下设置适合我。我在CoreOSVagrantboot2docker进行了测试。假设代理端口为3128

在Centos中:

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

在Ubuntu中:

ENV http_proxy 'http://ip:3128'
ENV https_proxy 'http://ip:3128'

注意格式,有些有http,有些没有,有些有单个配额。如果IP地址是192.168.0.193,则设置为:

在Centos中:

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

在Ubuntu中:

ENV http_proxy 'http://192.168.0.193:3128'
ENV https_proxy 'http://192.168.0.193:3128'

如果您需要在coreos中设置代理,例如拉动图像

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

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

答案 2 :(得分:36)

如果要使用Dockerfile构建,可以使用--build-arg选项。

https://github.com/docker/docker/issues/14634上的链接,请参阅“使用多个HTTP_PROXY构建--build-arg”部分:

[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环境变量。

答案 3 :(得分:11)

Dockerfile 中的任何apt-get命令之前,你应该放这行

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

不要忘记在 Dockerfile 的相同文件夹中创建 apt.conf apt.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/";

foo 是用户名,是密码。

答案 4 :(得分:7)

在小写环境变量中使用--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 .

答案 5 :(得分:3)

我有同样的问题,并找到了另一个小解决方法: 我有一个从docker构建环境添加的配置脚本。 在脚本中,我根据ping检查设置环境变量:

Dockerfile:

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

这仍然有些粗糙但对我有用

答案 6 :(得分:3)

正如其他答案所示,--build-arg可能是解决方案。 就我而言,除了--network=host选项之外,我还必须添加--build-arg

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

答案 7 :(得分:1)

我们正在做......

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变量仅用于构建而不暴露它们

解决方案的替代方案不是在代理后面本地构建您的图像,而是让docker使用docker&#34;自动构建&#34;为您构建图像。由于docker没有在代理后面构建图像,因此问题得以解决。自动构建的示例可在...

中找到

https://github.com/danday74/docker-nginx-lua(GITHUB repo)

https://registry.hub.docker.com/u/danday74/nginx-lua(DOCKER repo正在使用自动构建观看github存储库并在推送到github主分支上进行docker构建)

答案 8 :(得分:1)

如果你想为wget设置代理,你应该将这些行放在你的 Dockerfile

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

答案 9 :(得分:1)

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

此外,您无法与公司外的其他人共享您的图像。

答案 10 :(得分:1)

@Reza Farshi(在我的情况下效果更好)提供的答案的一个略微替代方法是使用/etc/apt/apt.conf通过Dockerfile将代理设置写入echo,例如:

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

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

e.g。

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

根据docker build文档。