如何在代理的dockerfile中运行“apt-get”?

时间:2022-12-17 21:51:17

I am running a virtual machine (Ubuntu 13.10) with docker (version 0.8.1, build a1598d1). I am trying to build an image with a dockerfile. First, I want to update the packages (using the code below - the proxy is obfuscated) but apt-get times out with the error: Could not resolve 'archive.ubuntu.com'.

我使用docker运行一个虚拟机(Ubuntu 13.10)(版本0.8.1,构建a1598d1)。我正在尝试用dockerfile构建一个映像。首先,我想更新包(使用下面的代码——代理是模糊的),但是用错误来处理时间:不能解决'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

I have also run the following in the host system:

我还在主机系统中运行以下操作:

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

The host is able to run apt-get without issue.

主机可以在没有问题的情况下运行apt-get。

How can I change the dockerfile to allow it to reach the ubuntu servers from within the container?

如何更改dockerfile使其能够从容器内到达ubuntu服务器?

Update

更新

I ran the code in CentOS (changing the FROM ubuntu:13.10 to FROM centos) and it worked fine. It seems to be a problem with Ubuntu.

我在CentOS(从ubuntu:13.10到CentOS)中运行代码,并且运行良好。这似乎是Ubuntu的一个问题。

12 个解决方案

#1


62  

UPDATE:

更新:

You have wrong capitalization of environment variables in ENV. Correct one is http_proxy. Your example should be:

在ENV中,环境变量的资本化是错误的。一个是http_proxy正确。你的例子应该是:

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

or

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

All variables specified in ENV are prepended to every RUN command. Every RUN command is executed in own container/environment, so it does not inherit variables from previous RUN commands!

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

Note: There is no need to call docker daemon with proxy for this to work, although if you want to pull images etc. you need to set the proxy for docker deamon too. You can set proxy for daemon in /etc/default/docker in Ubuntu (it does not affect containers setting).

注意:没有必要调用docker守护进程来完成这个工作,但是如果您想要获取图像,那么您需要设置docker deamon的代理。您可以在Ubuntu的/etc/default/docker中为守护进程设置代理(它不影响容器设置)。


Also, this can happen in case you run your proxy on host (i.e. localhost, 127.0.0.1). Localhost on host differ from localhost in container. In such case, you need to use another IP (like 172.17.42.1) to bind your proxy to or if you bind to 0.0.0.0, you can use 172.17.42.1 instead of 127.0.0.1 for connection from container during docker build.

同样,如果您在主机上运行代理(即localhost, 127.0.0.1),也会发生这种情况。主机上的本地主机不同于容器中的本地主机。在这种情况下,您需要使用另一个IP(比如172.17.42.1)来绑定您的代理,或者如果您绑定到0.0.0.0,那么您可以使用172.17.42.1而不是127.0.0.1来连接docker构建期间的容器。

You can also look for an example here: How to rebuild dockerfile quick by using cache?

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

#2


34  

Below setting in Dockerfile works for me. I tested in CoreOS, Vagrant and boot2docker. Suppose the proxy port is 3128

在Dockerfile中设置为我工作。我在CoreOS, Vagrant和boot2docker测试过。假设代理端口是3128。

In Centos:

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

In Ubuntu:

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

Be careful of the format, some have http in it, some haven't, some with single quota. if the IP address is 192.168.0.193, then the setting will be:

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

In Centos:

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

In Ubuntu:

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

If you need set proxy in coreos, for example to pull the image

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

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

#3


28  

You can use the --build-arg option when you want to build using a Dockerfile.

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

From a link on https://github.com/docker/docker/issues/14634 , see the section "Build with --build-arg with multiple HTTP_PROXY":

从https://github.com/docker/docker/addrees/14634的链接中,可以看到“构建with - buildarg与多个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 .

NOTE: On your own system, make sure you have set the HTTP_PROXY and NO_PROXY environment variables.

注意:在您自己的系统上,确保设置了HTTP_PROXY和NO_PROXY环境变量。

#4


11  

before any apt-get command in your Dockerfile you should put this line

在您的Dockerfile中任何一个apt-get命令之前,您应该将这条线。

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

Dont'f forget to create apt.conf in the same folder that you have the Dockerfile, the content of the apt.conf file should be like this:

不要忘记在有Dockerfile的同一个文件夹中创建一个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/";

if you use username and password to connect to your proxy then the apt.conf should be like as below:

如果您使用用户名和密码来连接到您的代理,那么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/";

for example :

例如:

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

Where the foo is the username and bar is the password.

foo是用户名,而bar是密码。

#5


4  

Use --build-arg in lower case environment variable:

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

#6


3  

i had the same problem and found another little workaround: i have a provisioner script that is added form the docker build environment. In the script i set the environment variable dependent on a ping check:

我遇到了同样的问题,发现了另一个小问题:我有一个添加了docker构建环境的供应者脚本。在脚本中,我设置了依赖于ping检查的环境变量:

Dockerfile:

Dockerfile:

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

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

this is still somewhat crude but worked for me

这仍然有点粗糙,但对我很有效。

#7


3  

If you have the proxies set up correctly, and still cannot reach the internet, it could be the DNS resolution. Check /etc/resolve.conf on the host Ubuntu VM. If it contains nameserver 127.0.1.1, that is wrong.

如果您的代理设置正确,并且仍然不能到达internet,那么它可能是DNS解析。检查/etc/resolve.conf在主机Ubuntu VM上。如果它包含nameserver 127.0.1.1,那是错误的。

Run these commands on the host Ubuntu VM to fix it:

在宿主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

Now /etc/resolv.conf should have a valid value for nameserver, which will be copied by the docker containers.

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

#8


2  

As suggested by other answers, --build-arg may be the solution. In my case, I had to add --network=host in addition to the --build-arg options.

正如其他答案所暗示的那样,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 .

#9


1  

We are doing ...

我们正在做……

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

and at end of dockerfile ...

在dockerfile的末尾…

ENV http_proxy ""
ENV https_proxy ""

This, for now (until docker introduces build env vars), allows the proxy env vars to be used for the build ONLY without exposing them

现在(直到docker引入构建env vars),允许代理env vars只用于构建而不暴露它们。

The alternative to solution is NOT to build your images locally behind a proxy but to let docker build your images for you using docker "automated builds". Since docker is not building the images behind your proxy the problem is solved. An example of an automated build is available at ...

解决方案的另一种选择是,不要在代理后面构建您的映像,而是让docker使用docker“自动构建”为您构建映像。因为docker并没有在你的代理后面构建图像,所以问题就解决了。一个自动化构建的例子在……

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

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

https://registry.hub.docker.com/u/danday74/nginx-lua (DOCKER repo which is watching the github repo using an automated build and doing a docker build on a push to the github master branch)

https://registry.hub.docker.com/u/danday74/nginx-lua (DOCKER repo正在使用自动构建来监视github repo,并在push到github主分支上构建DOCKER)

#10


1  

and If you want to set proxy for wget you should put these line in your Dockerfile

如果要设置wget的代理,应该将这些行放到Dockerfile中。

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

#11


1  

As Tim Potter pointed out, setting proxy in dockerfile is horrible. When building the image, you add proxy for your corporate network but you may be deploying in cloud or a DMZ where there is no need for proxy or the proxy server is different.

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

Also, you cannot share your image with others outside your corporate n/w.

此外,你不能在你的公司n/w之外与他人分享你的形象。

#12


1  

A slight alternative to the answer provided by @Reza Farshi (which works better in my case) is to write the proxy settings out to /etc/apt/apt.conf using echo via the Dockerfile e.g.:

@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

The advantage of this approach is that the proxy addresses can be passed in dynamically at image build time, rather than having to copy the settings file over from the host.

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

e.g.

如。

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

build-arg HTTP_PROXY=http:// : —build-arg HTTPS_PROXY=http:// <主机> : <端口> 。

as per docker build docs.

根据docker构建文档。

#1


62  

UPDATE:

更新:

You have wrong capitalization of environment variables in ENV. Correct one is http_proxy. Your example should be:

在ENV中,环境变量的资本化是错误的。一个是http_proxy正确。你的例子应该是:

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

or

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

All variables specified in ENV are prepended to every RUN command. Every RUN command is executed in own container/environment, so it does not inherit variables from previous RUN commands!

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

Note: There is no need to call docker daemon with proxy for this to work, although if you want to pull images etc. you need to set the proxy for docker deamon too. You can set proxy for daemon in /etc/default/docker in Ubuntu (it does not affect containers setting).

注意:没有必要调用docker守护进程来完成这个工作,但是如果您想要获取图像,那么您需要设置docker deamon的代理。您可以在Ubuntu的/etc/default/docker中为守护进程设置代理(它不影响容器设置)。


Also, this can happen in case you run your proxy on host (i.e. localhost, 127.0.0.1). Localhost on host differ from localhost in container. In such case, you need to use another IP (like 172.17.42.1) to bind your proxy to or if you bind to 0.0.0.0, you can use 172.17.42.1 instead of 127.0.0.1 for connection from container during docker build.

同样,如果您在主机上运行代理(即localhost, 127.0.0.1),也会发生这种情况。主机上的本地主机不同于容器中的本地主机。在这种情况下,您需要使用另一个IP(比如172.17.42.1)来绑定您的代理,或者如果您绑定到0.0.0.0,那么您可以使用172.17.42.1而不是127.0.0.1来连接docker构建期间的容器。

You can also look for an example here: How to rebuild dockerfile quick by using cache?

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

#2


34  

Below setting in Dockerfile works for me. I tested in CoreOS, Vagrant and boot2docker. Suppose the proxy port is 3128

在Dockerfile中设置为我工作。我在CoreOS, Vagrant和boot2docker测试过。假设代理端口是3128。

In Centos:

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

In Ubuntu:

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

Be careful of the format, some have http in it, some haven't, some with single quota. if the IP address is 192.168.0.193, then the setting will be:

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

In Centos:

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

In Ubuntu:

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

If you need set proxy in coreos, for example to pull the image

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

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

#3


28  

You can use the --build-arg option when you want to build using a Dockerfile.

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

From a link on https://github.com/docker/docker/issues/14634 , see the section "Build with --build-arg with multiple HTTP_PROXY":

从https://github.com/docker/docker/addrees/14634的链接中,可以看到“构建with - buildarg与多个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 .

NOTE: On your own system, make sure you have set the HTTP_PROXY and NO_PROXY environment variables.

注意:在您自己的系统上,确保设置了HTTP_PROXY和NO_PROXY环境变量。

#4


11  

before any apt-get command in your Dockerfile you should put this line

在您的Dockerfile中任何一个apt-get命令之前,您应该将这条线。

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

Dont'f forget to create apt.conf in the same folder that you have the Dockerfile, the content of the apt.conf file should be like this:

不要忘记在有Dockerfile的同一个文件夹中创建一个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/";

if you use username and password to connect to your proxy then the apt.conf should be like as below:

如果您使用用户名和密码来连接到您的代理,那么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/";

for example :

例如:

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

Where the foo is the username and bar is the password.

foo是用户名,而bar是密码。

#5


4  

Use --build-arg in lower case environment variable:

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

#6


3  

i had the same problem and found another little workaround: i have a provisioner script that is added form the docker build environment. In the script i set the environment variable dependent on a ping check:

我遇到了同样的问题,发现了另一个小问题:我有一个添加了docker构建环境的供应者脚本。在脚本中,我设置了依赖于ping检查的环境变量:

Dockerfile:

Dockerfile:

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

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

this is still somewhat crude but worked for me

这仍然有点粗糙,但对我很有效。

#7


3  

If you have the proxies set up correctly, and still cannot reach the internet, it could be the DNS resolution. Check /etc/resolve.conf on the host Ubuntu VM. If it contains nameserver 127.0.1.1, that is wrong.

如果您的代理设置正确,并且仍然不能到达internet,那么它可能是DNS解析。检查/etc/resolve.conf在主机Ubuntu VM上。如果它包含nameserver 127.0.1.1,那是错误的。

Run these commands on the host Ubuntu VM to fix it:

在宿主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

Now /etc/resolv.conf should have a valid value for nameserver, which will be copied by the docker containers.

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

#8


2  

As suggested by other answers, --build-arg may be the solution. In my case, I had to add --network=host in addition to the --build-arg options.

正如其他答案所暗示的那样,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 .

#9


1  

We are doing ...

我们正在做……

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

and at end of dockerfile ...

在dockerfile的末尾…

ENV http_proxy ""
ENV https_proxy ""

This, for now (until docker introduces build env vars), allows the proxy env vars to be used for the build ONLY without exposing them

现在(直到docker引入构建env vars),允许代理env vars只用于构建而不暴露它们。

The alternative to solution is NOT to build your images locally behind a proxy but to let docker build your images for you using docker "automated builds". Since docker is not building the images behind your proxy the problem is solved. An example of an automated build is available at ...

解决方案的另一种选择是,不要在代理后面构建您的映像,而是让docker使用docker“自动构建”为您构建映像。因为docker并没有在你的代理后面构建图像,所以问题就解决了。一个自动化构建的例子在……

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

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

https://registry.hub.docker.com/u/danday74/nginx-lua (DOCKER repo which is watching the github repo using an automated build and doing a docker build on a push to the github master branch)

https://registry.hub.docker.com/u/danday74/nginx-lua (DOCKER repo正在使用自动构建来监视github repo,并在push到github主分支上构建DOCKER)

#10


1  

and If you want to set proxy for wget you should put these line in your Dockerfile

如果要设置wget的代理,应该将这些行放到Dockerfile中。

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

#11


1  

As Tim Potter pointed out, setting proxy in dockerfile is horrible. When building the image, you add proxy for your corporate network but you may be deploying in cloud or a DMZ where there is no need for proxy or the proxy server is different.

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

Also, you cannot share your image with others outside your corporate n/w.

此外,你不能在你的公司n/w之外与他人分享你的形象。

#12


1  

A slight alternative to the answer provided by @Reza Farshi (which works better in my case) is to write the proxy settings out to /etc/apt/apt.conf using echo via the Dockerfile e.g.:

@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

The advantage of this approach is that the proxy addresses can be passed in dynamically at image build time, rather than having to copy the settings file over from the host.

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

e.g.

如。

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

build-arg HTTP_PROXY=http:// : —build-arg HTTPS_PROXY=http:// <主机> : <端口> 。

as per docker build docs.

根据docker构建文档。