我正在使用 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 的问题。
更新:
您在 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 daemon 来工作,但如果你想拉图像等,你也需要为 docker deamon 设置代理。您可以在 Ubuntu 的 /etc/default/docker
中为守护进程设置代理(它不影响容器设置)。
此外,如果您在主机上运行代理(即 localhost,127.0.0.1),也会发生这种情况。主机上的 localhost 与容器中的 localhost 不同。在这种情况下,您需要使用另一个 IP(如 172.17.42.1)将您的代理绑定到,或者如果您绑定到 0.0.0.0,您可以在 docker build
期间使用 172.17.42.1 而不是 127.0.0.1 从容器连接。
您还可以在此处查找示例:How to rebuild dockerfile quick by using cache?
更新于 2018 年 2 月 10 日
使用 docker 选项 --config
中的新功能,您不再需要在 Dockerfile 中设置代理。您可以拥有相同的 Dockerfile 以在有或没有代理设置的情况下在公司环境内外使用。
命令 docker run
选项:
--config string Location of client config files (default "~/.docker")
或环境变量 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, ftpProxy
和 noProxy
设置代理(官方文档错过了有时有用的变量 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 中的以下设置对我有用。我在 CoreOS
、Vagrant
和 boot2docker
中进行了测试。假设代理端口是 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"
80
:stackoverflow.com/a/46949277/1654763
$DOCKER_CONFIG
应该指向一个目录而不是直接指向 config.json
文件
当您想使用 Dockerfile 进行构建时,可以使用 --build-arg
选项。
从 https://github.com/docker/docker/issues/14634 上的链接,请参阅“使用 --build-arg 和多个 HTTP_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 环境变量。
在 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 是用户名, bar 是密码。
Acquire::socks::proxy
表示为所有以 socks
方案开头的 URL 设置代理。由于您的 sources.list
没有任何 socks://
URL,因此该行将被完全忽略。我将提交修改以更正此问题。
jessie
上有 /etc/apt/apt.conf.d/<config>
,因此 Dockerfile COPY
指令需要在此处更新。
在小写环境变量中使用 --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 .
@Reza Farshi 提供的答案的一个轻微替代方案(在我的情况下效果更好)是通过 Dockerfile 使用 echo
将代理设置写入 /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> .
根据 docker build 文档。
我遇到了同样的问题并找到了另一个小解决方法:我有一个从 docker 构建环境添加的配置器脚本。在脚本中,我根据 ping 检查设置环境变量:
Dockerfile:
ADD script.sh /tmp/script.sh
RUN /tmp/script.sh
脚本.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
这仍然有点粗糙,但对我有用
如果您正确设置了代理,但仍然无法访问 Internet,则可能是 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 容器复制。
pip install
在代理后面使用 docker。这不是 OP 真正想要的,但对我帮助很大! :)
我们正在做 ...
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 引入构建环境变量),这允许代理环境变量仅用于构建而不暴露它们
解决方案的替代方案不是在代理后面本地构建图像,而是让 docker 使用 docker“自动构建”为您构建图像。由于 docker 没有在您的代理后面构建图像,因此问题已解决。自动构建的示例可在...
https://github.com/danday74/docker-nginx-lua(GITHUB 存储库)
https://registry.hub.docker.com/u/danday74/nginx-lua(DOCKER repo 正在使用自动构建观看 github repo,并在推送到 github master 分支时进行 docker build)
如果你想为 wget 设置代理,你应该把这些行放在你的 Dockerfile
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 中。
此外,您不能与公司 n/w 之外的其他人分享您的图像。
不定期副业成功案例分享
FROM
)。ENV http_proxy corporate-proxy.com
。这很恶心,因为这意味着您不能与公司以外的任何人共享您的 Dockerfile。我刚刚通过在容器中运行 polipo 验证了这一点,同时尝试缓存apt-get install
命令以开发 Dockerfile。也许未来版本的 Docker 将拥有一些神奇的 iptables 配置,允许对 HTTP 请求进行透明代理?polipo parentProxy=corporate-proxy.com
) 在主机上设置 polipo,而不是使用 iptables:iptables -t nat -A OUTPUT -p tcp -m owner ! --uid-owner <polipo-user> --dport 80 -j REDIRECT --to-port 8123
设置透明代理。