如何使用 Jenkins HTTP_PROXY 后面的 Docker 文件构建 Docker 图像?
How to build Docker Images with Dockerfile behind HTTP_PROXY by Jenkins?
构建 Docker 图像在桌面上没有问题。安装 Node.js NPM 依赖项像往常一样工作。但是,当使用持续集成服务器(例如托管在公司代理后面的 Jenkins)时,构建 Docker 图像失败。
Node.js NPM 依赖项
构建 Node.js 包时,命令 npm install 在克隆 GIT 依赖项时无法连接到 GIT 时失败。
e1ce5e8407d1: Already exists
Status: Image is up to date for node:0.10.33
---> e1ce5e8407d1
Step 1 : RUN mkdir -p /usr/src/app
---> Using cache
---> 965cad0c68b0
Step 2 : WORKDIR /usr/src/app
---> Using cache
---> 4c498f0c07e9
Step 3 : COPY package.json /usr/src/app/
---> b0662a8275fb
Removing intermediate container 5aca20551452
Step 4 : RUN npm install
---> Running in 7ccf9e5362af
npm WARN package.json newww@2.0.0 No README data
npm WARN package.json Dependency 'async-cache' exists in both dependencies and devDependencies, using 'async-cache@^0.1.5' from dependencies
npm ERR! git clone https://github.com/npm/npm2es.git Cloning into bare repository '/root/.npm/_git-remotes/https-github-com-npm-npm2es-git-60a75edb'...
npm ERR! git clone https://github.com/npm/npm2es.git fatal: unable to access 'https://github.com/npm/npm2es.git/': Failed to connect to github.com port 443: Connection timed out
Java Maven,Ruby,Go Docker Images with Dependencies
构建 Java、Ruby 或 Go 容器时也会发生同样的情况,其中依赖项位于跨公司代理服务器的存储库服务器中。
知道可以使用 HTTP_PROXY 环境变量配置 Docker,如何正确配置 Docker 以在 CI 环境中正确构建映像?
Docker 守护程序 HTTP 代理
有很多关于为 Docker 守护程序设置 HTTP_PROXY 环境变量的文档。环境变量只有在运行个容器时才有,所以这里帮不了我们
Docker文件中的解决方案
虽然在Docker文件中设置了环境变量HTTP_ENV或http_env可能有帮助,但对我们的事业没有帮助。
ENV http_proxy http://proxy.mycompany.com:80
原因是每个特定服务仅以不同方式支持 HTTP 代理设置。我可以解决的方法如下。
- NPM:NPM 需要使用 CLI 命令设置 HTTP_PROXY 变量。
- GIT:GIT 还需要使用 CLI 命令设置 HTTP_PROXY 变量。
- MAVEN: MVN 命令需要在 ~/.m2/settings.xml 用户目录下将 HTTP_PROXY 设置为 XML 文件。对于 Docker,您可以将其添加到根目录的“/root/.m2/settings.xml”目录(不安全,仅限开发),或者添加到 Docker 文件的用户目录主目录。
例如,运行 一个使用 Docker 文件的应用程序,我可以使用以下 Docker 文件构建图像:
FROM node:0.10.33
# Prepare
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Use the cache for dependencies
COPY package.json /usr/src/app/
# If building behind an http_proxy, set them for git and npm
RUN git config --global http.proxy http://qypprdproxy02.ie.company.net:80 && \
npm config set proxy http://qypprdproxy02.ie.company.net:80 && \
npm config set https-proxy http://qypprdproxy02.ie.company.net:80
# Install dependencies
RUN npm install
# Copy all the source
COPY . /usr/src/app
# Execute the dev steps
COPY ./numbat-config.example.js /usr/src/app/numbat-config.js
COPY ./.env.example /usr/src/app/.evn
RUN touch /usr/src/app/config.admin.js
请注意,我已经使用它们的 CLI 命令配置了 GIT 和 NPM,以便在 运行 NPM 安装命令之前明确采用代理设置。这样,NPM 和 GIT 依赖项将分别被自动检索和克隆。
使用此 Docker 文件构建图像的结果按预期工作:
[root@pppdc9prd6dq newww]# fig build
...
...
Building npmregistryserver...
---> Using cache
---> 965cad0c68b0
Step 2 : WORKDIR /usr/src/app
---> Using cache
---> 4c498f0c07e9
Step 3 : COPY package.json /usr/src/app/
---> ae8ff7861246
Removing intermediate container ba1d7b8c9963
Step 4 : RUN npm config set proxy http://qypprdproxy02.ie.company.net:80 && npm config set https-proxy http://qypprdproxy02.ie.company.net:80 && npm install
---> Running in aa6e05d9c7a4
npm WARN package.json newww@2.0.0 No README data
npm WARN package.json Dependency 'async-cache' exists in both dependencies and devDependencies, using 'async-cache@^0.1.5' from dependencies
npm WARN deprecated extend@1.1.3: Please update to the latest version.
> v8flags@1.0.8 install /usr/src/app/node_modules/gulp/node_modules/v8flags
> node fetch.js
> hiredis@0.1.17 install /usr/src/app/node_modules/hiredis
> node-gyp rebuild
make: Entering directory '/usr/src/app/node_modules/hiredis/build'
CC(target) Release/obj.target/hiredis/deps/hiredis/hiredis.o
CC(target) Release/obj.target/hiredis/deps/hiredis/net.o
CC(target) Release/obj.target/hiredis/deps/hiredis/sds.o
CC(target) Release/obj.target/hiredis/deps/hiredis/async.o
AR(target) Release/obj.target/deps/hiredis.a
COPY Release/hiredis.a
CXX(target) Release/obj.target/hiredis/src/hiredis.o
CXX(target) Release/obj.target/hiredis/src/reader.o
SOLINK_MODULE(target) Release/obj.target/hiredis.node
SOLINK_MODULE(target) Release/obj.target/hiredis.node: Finished
COPY Release/hiredis.node
make: Leaving directory '/usr/src/app/node_modules/hiredis/build'
npm WARN engine hawk@0.10.2: wanted: {"node":"0.8.x"} (current: {"node":"0.10.33","npm":"2.1.11"})
> pngcrush-bin@1.0.0 postinstall /usr/src/app/node_modules/imagemin-pngcrush/node_modules/pngcrush-bin
> node lib/install.js
fetch : https://raw.githubusercontent.com/imagemin/pngcrush-bin/v1.0.0/vendor/linux/pngcrush
✔ pre-build test passed successfully!
> dtrace-provider@0.3.1 install /usr/src/app/node_modules/npm-typeahead/node_modules/restify/node_modules/dtrace-provider
> scripts/install.js
npm WARN engine cryptiles@0.1.3: wanted: {"node":"0.8.x"} (current: {"node":"0.10.33","npm":"2.1.11"})
npm WARN engine sntp@0.1.4: wanted: {"node":"0.8.x"} (current: {"node":"0.10.33","npm":"2.1.11"})
npm WARN engine boom@0.3.8: wanted: {"node":"0.8.x"} (current: {"node":"0.10.33","npm":"2.1.11"})
npm WARN engine hoek@0.7.6: wanted: {"node":"0.8.x"} (current: {"node":"0.10.33","npm":"2.1.11"})
npm WARN cannot run in wd newww@2.0.0 gulp build (wd=/usr/src/app)
newww-metrics@1.0.0 node_modules/newww-metrics
murmurhash@0.0.2 node_modules/murmurhash
npm-humans@2.0.1 node_modules/npm-humans
leven@1.0.1 node_modules/leven
chunk@0.0.2 node_modules/chunk
npm-expansions@1.14.0 node_modules/npm-expansions
similarity@1.0.1 node_modules/similarity
truncate@1.0.4 node_modules/truncate
这按预期正常工作,您可以在 http 代理后面有一个 CI/CD 环境,以根据此 Docker 文件重建图像。
我们正在做...
ENV http_proxy http://9.9.9.9:9999
ENV https_proxy http://9.9.9.9:9999
并且在 docker 文件的末尾...
ENV http_proxy ""
ENV https_proxy ""
现在(直到 docker 引入构建环境变量),允许代理变量用于构建而不公开它们
注意:Docker 1.9 可能 有助于解决这个问题:
- "Issue 14634":Builder - 构建时参数传递(例如,
HTTP_PROXY
)
- "PR 15182":支持在构建上下文中传递构建时变量
用法(建议):
docker build --build-arg http_proxy=http://my.proxy.url --build-arg foo=bar <<MARK
FROM busybox
RUN <command that need http_proxy>
ARG --description="foo's description" foo
USER $foo
MARK
Docker有多种方法可以设置不同时间生效的代理。
如果您的 docker build
必须 通过代理检索基本图像 ,您需要指定 build-arg
s:
docker build --build-arg HTTP_PROXY=$http_proxy \
--build-arg HTTPS_PROXY=$http_proxy --build-arg NO_PROXY="$no_proxy" \
--build-arg http_proxy=$http_proxy --build-arg https_proxy=$http_proxy \
--build-arg no_proxy="$no_proxy" -t myContainer /path/to/Dockerfile/directory
我的 bashrc 中设置了 $http_proxy
和 $no_proxy
。我同时使用了 HTTP_PROXY
和 http_proxy
,因为不同的实用程序会检查不同的变量(curl
检查两者,wget
只检查小写的,等等)。
如果您的 docker build
有一个必须通过代理的 RUN curl/wget/etc
命令,您需要在您的 docker 图片:
ENV https_proxy=http://proxy-us02.company.com:8080
ENV http_proxy=http://proxy-us02.company.com:8080
ENV HTTP_PROXY=http://proxy-us02.company.com:8080
ENV HTTPS_PROXY=http://proxy-us02.company.com:8080
ENV no_proxy="localhost,localdomain,127.0.0.1,etc"
ENV NO_PROXY="localhost,localdomain,127.0.0.1,etc"
如果你不想在运行时在你的图像中使用这个环境变量,你可以在最后删除所有这些:
RUN unset http_proxy https_proxy no_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY
公司网络不允许下载和设置 docker 图像时出现问题,因此 n/w 提供了 http 代理信息。虽然 运行 docker 图像构建我传递了变量并且它没有任何问题地工作。
docker build --build-arg http_proxy="http://userid:pwd@iaisystem.com:8080" - < Dockerfile
您可以使用透明代理,如下所述:
https://jpetazzo.github.io/2014/06/17/transparent-squid-proxy-docker/
docker run --net host jpetazzo/squid-in-a-can
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 3129
从 Docker 17.07 开始,您可以选择使用 Docker 客户端配置文件集中提供代理配置:
https://docs.docker.com/network/proxy/#configure-the-docker-client
构建 Docker 图像在桌面上没有问题。安装 Node.js NPM 依赖项像往常一样工作。但是,当使用持续集成服务器(例如托管在公司代理后面的 Jenkins)时,构建 Docker 图像失败。
Node.js NPM 依赖项
构建 Node.js 包时,命令 npm install 在克隆 GIT 依赖项时无法连接到 GIT 时失败。
e1ce5e8407d1: Already exists
Status: Image is up to date for node:0.10.33
---> e1ce5e8407d1
Step 1 : RUN mkdir -p /usr/src/app
---> Using cache
---> 965cad0c68b0
Step 2 : WORKDIR /usr/src/app
---> Using cache
---> 4c498f0c07e9
Step 3 : COPY package.json /usr/src/app/
---> b0662a8275fb
Removing intermediate container 5aca20551452
Step 4 : RUN npm install
---> Running in 7ccf9e5362af
npm WARN package.json newww@2.0.0 No README data
npm WARN package.json Dependency 'async-cache' exists in both dependencies and devDependencies, using 'async-cache@^0.1.5' from dependencies
npm ERR! git clone https://github.com/npm/npm2es.git Cloning into bare repository '/root/.npm/_git-remotes/https-github-com-npm-npm2es-git-60a75edb'...
npm ERR! git clone https://github.com/npm/npm2es.git fatal: unable to access 'https://github.com/npm/npm2es.git/': Failed to connect to github.com port 443: Connection timed out
Java Maven,Ruby,Go Docker Images with Dependencies
构建 Java、Ruby 或 Go 容器时也会发生同样的情况,其中依赖项位于跨公司代理服务器的存储库服务器中。
知道可以使用 HTTP_PROXY 环境变量配置 Docker,如何正确配置 Docker 以在 CI 环境中正确构建映像?
Docker 守护程序 HTTP 代理
有很多关于为 Docker 守护程序设置 HTTP_PROXY 环境变量的文档。环境变量只有在运行个容器时才有,所以这里帮不了我们
Docker文件中的解决方案
虽然在Docker文件中设置了环境变量HTTP_ENV或http_env可能有帮助,但对我们的事业没有帮助。
ENV http_proxy http://proxy.mycompany.com:80
原因是每个特定服务仅以不同方式支持 HTTP 代理设置。我可以解决的方法如下。
- NPM:NPM 需要使用 CLI 命令设置 HTTP_PROXY 变量。
- GIT:GIT 还需要使用 CLI 命令设置 HTTP_PROXY 变量。
- MAVEN: MVN 命令需要在 ~/.m2/settings.xml 用户目录下将 HTTP_PROXY 设置为 XML 文件。对于 Docker,您可以将其添加到根目录的“/root/.m2/settings.xml”目录(不安全,仅限开发),或者添加到 Docker 文件的用户目录主目录。
例如,运行 一个使用 Docker 文件的应用程序,我可以使用以下 Docker 文件构建图像:
FROM node:0.10.33
# Prepare
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Use the cache for dependencies
COPY package.json /usr/src/app/
# If building behind an http_proxy, set them for git and npm
RUN git config --global http.proxy http://qypprdproxy02.ie.company.net:80 && \
npm config set proxy http://qypprdproxy02.ie.company.net:80 && \
npm config set https-proxy http://qypprdproxy02.ie.company.net:80
# Install dependencies
RUN npm install
# Copy all the source
COPY . /usr/src/app
# Execute the dev steps
COPY ./numbat-config.example.js /usr/src/app/numbat-config.js
COPY ./.env.example /usr/src/app/.evn
RUN touch /usr/src/app/config.admin.js
请注意,我已经使用它们的 CLI 命令配置了 GIT 和 NPM,以便在 运行 NPM 安装命令之前明确采用代理设置。这样,NPM 和 GIT 依赖项将分别被自动检索和克隆。
使用此 Docker 文件构建图像的结果按预期工作:
[root@pppdc9prd6dq newww]# fig build
...
...
Building npmregistryserver...
---> Using cache
---> 965cad0c68b0
Step 2 : WORKDIR /usr/src/app
---> Using cache
---> 4c498f0c07e9
Step 3 : COPY package.json /usr/src/app/
---> ae8ff7861246
Removing intermediate container ba1d7b8c9963
Step 4 : RUN npm config set proxy http://qypprdproxy02.ie.company.net:80 && npm config set https-proxy http://qypprdproxy02.ie.company.net:80 && npm install
---> Running in aa6e05d9c7a4
npm WARN package.json newww@2.0.0 No README data
npm WARN package.json Dependency 'async-cache' exists in both dependencies and devDependencies, using 'async-cache@^0.1.5' from dependencies
npm WARN deprecated extend@1.1.3: Please update to the latest version.
> v8flags@1.0.8 install /usr/src/app/node_modules/gulp/node_modules/v8flags
> node fetch.js
> hiredis@0.1.17 install /usr/src/app/node_modules/hiredis
> node-gyp rebuild
make: Entering directory '/usr/src/app/node_modules/hiredis/build'
CC(target) Release/obj.target/hiredis/deps/hiredis/hiredis.o
CC(target) Release/obj.target/hiredis/deps/hiredis/net.o
CC(target) Release/obj.target/hiredis/deps/hiredis/sds.o
CC(target) Release/obj.target/hiredis/deps/hiredis/async.o
AR(target) Release/obj.target/deps/hiredis.a
COPY Release/hiredis.a
CXX(target) Release/obj.target/hiredis/src/hiredis.o
CXX(target) Release/obj.target/hiredis/src/reader.o
SOLINK_MODULE(target) Release/obj.target/hiredis.node
SOLINK_MODULE(target) Release/obj.target/hiredis.node: Finished
COPY Release/hiredis.node
make: Leaving directory '/usr/src/app/node_modules/hiredis/build'
npm WARN engine hawk@0.10.2: wanted: {"node":"0.8.x"} (current: {"node":"0.10.33","npm":"2.1.11"})
> pngcrush-bin@1.0.0 postinstall /usr/src/app/node_modules/imagemin-pngcrush/node_modules/pngcrush-bin
> node lib/install.js
fetch : https://raw.githubusercontent.com/imagemin/pngcrush-bin/v1.0.0/vendor/linux/pngcrush
✔ pre-build test passed successfully!
> dtrace-provider@0.3.1 install /usr/src/app/node_modules/npm-typeahead/node_modules/restify/node_modules/dtrace-provider
> scripts/install.js
npm WARN engine cryptiles@0.1.3: wanted: {"node":"0.8.x"} (current: {"node":"0.10.33","npm":"2.1.11"})
npm WARN engine sntp@0.1.4: wanted: {"node":"0.8.x"} (current: {"node":"0.10.33","npm":"2.1.11"})
npm WARN engine boom@0.3.8: wanted: {"node":"0.8.x"} (current: {"node":"0.10.33","npm":"2.1.11"})
npm WARN engine hoek@0.7.6: wanted: {"node":"0.8.x"} (current: {"node":"0.10.33","npm":"2.1.11"})
npm WARN cannot run in wd newww@2.0.0 gulp build (wd=/usr/src/app)
newww-metrics@1.0.0 node_modules/newww-metrics
murmurhash@0.0.2 node_modules/murmurhash
npm-humans@2.0.1 node_modules/npm-humans
leven@1.0.1 node_modules/leven
chunk@0.0.2 node_modules/chunk
npm-expansions@1.14.0 node_modules/npm-expansions
similarity@1.0.1 node_modules/similarity
truncate@1.0.4 node_modules/truncate
这按预期正常工作,您可以在 http 代理后面有一个 CI/CD 环境,以根据此 Docker 文件重建图像。
我们正在做...
ENV http_proxy http://9.9.9.9:9999
ENV https_proxy http://9.9.9.9:9999
并且在 docker 文件的末尾...
ENV http_proxy ""
ENV https_proxy ""
现在(直到 docker 引入构建环境变量),允许代理变量用于构建而不公开它们
注意:Docker 1.9 可能 有助于解决这个问题:
- "Issue 14634":Builder - 构建时参数传递(例如,
HTTP_PROXY
) - "PR 15182":支持在构建上下文中传递构建时变量
用法(建议):
docker build --build-arg http_proxy=http://my.proxy.url --build-arg foo=bar <<MARK
FROM busybox
RUN <command that need http_proxy>
ARG --description="foo's description" foo
USER $foo
MARK
Docker有多种方法可以设置不同时间生效的代理。
如果您的 docker build
必须 通过代理检索基本图像 ,您需要指定 build-arg
s:
docker build --build-arg HTTP_PROXY=$http_proxy \
--build-arg HTTPS_PROXY=$http_proxy --build-arg NO_PROXY="$no_proxy" \
--build-arg http_proxy=$http_proxy --build-arg https_proxy=$http_proxy \
--build-arg no_proxy="$no_proxy" -t myContainer /path/to/Dockerfile/directory
我的 bashrc 中设置了 $http_proxy
和 $no_proxy
。我同时使用了 HTTP_PROXY
和 http_proxy
,因为不同的实用程序会检查不同的变量(curl
检查两者,wget
只检查小写的,等等)。
如果您的 docker build
有一个必须通过代理的 RUN curl/wget/etc
命令,您需要在您的 docker 图片:
ENV https_proxy=http://proxy-us02.company.com:8080
ENV http_proxy=http://proxy-us02.company.com:8080
ENV HTTP_PROXY=http://proxy-us02.company.com:8080
ENV HTTPS_PROXY=http://proxy-us02.company.com:8080
ENV no_proxy="localhost,localdomain,127.0.0.1,etc"
ENV NO_PROXY="localhost,localdomain,127.0.0.1,etc"
如果你不想在运行时在你的图像中使用这个环境变量,你可以在最后删除所有这些:
RUN unset http_proxy https_proxy no_proxy HTTP_PROXY HTTPS_PROXY NO_PROXY
公司网络不允许下载和设置 docker 图像时出现问题,因此 n/w 提供了 http 代理信息。虽然 运行 docker 图像构建我传递了变量并且它没有任何问题地工作。
docker build --build-arg http_proxy="http://userid:pwd@iaisystem.com:8080" - < Dockerfile
您可以使用透明代理,如下所述:
https://jpetazzo.github.io/2014/06/17/transparent-squid-proxy-docker/
docker run --net host jpetazzo/squid-in-a-can
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 3129
从 Docker 17.07 开始,您可以选择使用 Docker 客户端配置文件集中提供代理配置:
https://docs.docker.com/network/proxy/#configure-the-docker-client