简体   繁体   English

为 node.js 应用程序构建 docker 镜像在代理之后失败

[英]Building a docker image for a node.js app fails behind proxy

I have an issue with npm during the docker build.我在 docker 构建期间遇到 npm 问题。 I am behind a corporate proxy and have read about 30 articles (and stackoverflow posts) addressing similar issues.我是一家公司代理人,阅读了大约 30 篇解决类似问题的文章(和 stackoverflow 帖子)。 However I was still not able to overcome this.但是我仍然无法克服这一点。

I am able to "npm install" the project and fetch all necessary dependencies outside of the docker build process (but also using the proxy), but not during.我能够“npm install”项目并在 docker build 过程之外获取所有必要的依赖项(但也使用代理),但不是在 docker 构建过程中。

What I have tried so far:到目前为止我尝试了什么:

  1. Using the proxy directly (along with hardcoded auth data) and also over CNTLM.直接使用代理(连同硬编码的身份验证数据)以及通过 CNTLM。 The description below is when using CNTLM.下面的描述是使用 CNTLM 时的情况。
  2. Using the http repository as depicted below with strict_ssl false.使用如下所示的 http 存储库和 strict_ssl false。

npm config set strict-ssl=false \

npm config set registry=http://registry.npmjs.org/ \

  1. Passing the proxy settings as --build-arg, env and via the RUN param将代理设置作为 --build-arg、env 并通过 RUN 参数传递

  2. Starting with a clean git checkout (without node_modules) and after running the npm install从干净的 git checkout(没有 node_modules)开始并在运行 npm install 之后

I am trying to build with:我正在尝试构建:

$ sudo docker build --build-arg HTTP_PROXY=http://127.0.0.1:3128 --build-arg HTTPS_PROXY=http://127.0.0.1:3128 .

The output输出

Sending build context to Docker daemon 226.6 MB
Step 1 : FROM node:argon
 ---> c74c117ed521
Step 2 : ENV http_proxy http://127.0.0.1:3128/
 ---> Using cache
 ---> ad2e2df7429b
Step 3 : ENV https_proxy http://127.0.0.1:3128/
 ---> Using cache
 ---> 75fb2eb0bb22
Step 4 : RUN mkdir -p /usr/src/app
 ---> Using cache
 ---> ee79de37d6d7
Step 5 : WORKDIR /usr/src/app
 ---> Using cache
 ---> 404356f5def0
Step 6 : COPY package.json /usr/src/app/
 ---> Using cache
 ---> a2ec47267628
Step 7 : RUN git config --global http.proxy http://127.0.0.1:3128/
 ---> Running in 3cd5db8b1371
 ---> 7353cd94b67a
Removing intermediate container 3cd5db8b1371
Step 8 : RUN npm install
 ---> Running in 79ed0eb809d8
npm info it worked if it ends with ok
npm info using npm@2.15.5
npm info using node@v4.4.6
npm info preinstall app
npm info attempt registry request try #1 at 10:24:02 AM
npm http request GET https://registry.npmjs.org/bufferutil
npm info attempt registry request try #1 at 10:24:02 AM
npm http request GET https://registry.npmjs.org/connect-mongo
<snip>

npm info retry will retry, error on last attempt: Error: tunneling socket could not be established, cause=connect ECONNREFUSED 127.0.0.1:3128
npm info retry will retry, error on last attempt: Error: tunneling socket could not be established, cause=connect ECONNREFUSED 127.0.0.1:3128
<snip>

npm ERR! Linux 3.13.0-88-generic
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "install"
npm ERR! node v4.4.6
npm ERR! npm  v2.15.5
npm ERR! code ECONNRESET

npm ERR! network tunneling socket could not be established, cause=connect ECONNREFUSED 127.0.0.1:3128
npm ERR! network This is most likely not a problem with npm itself
npm ERR! network and is related to network connectivity.
npm ERR! network In most cases you are behind a proxy or have bad network settings.
npm ERR! network 
npm ERR! network If you are behind a proxy, please make sure that the
npm ERR! network 'proxy' config is set properly.  See: 'npm help config'

npm ERR! Please include the following file with any support request:
npm ERR!     /usr/src/app/npm-debug.log

This is my docker script这是我的泊坞窗脚本

FROM node:argon

ENV http_proxy http://127.0.0.1:3128/
ENV https_proxy http://127.0.0.1:3128/

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/

# setup proxies
RUN git config --global http.proxy http://127.0.0.1:3128/ && \
    npm config set strict-ssl=false \
    npm config set registry=http://registry.npmjs.org/ \
    npm config set proxy=http://127.0.0.1:3128/ && \
    npm config set https-proxy=http://127.0.0.1:3128/

# Install dependencies for node.js
RUN npm install

# Bundle app source
COPY . /usr/src/app

EXPOSE 8080
CMD [ "npm", "start" ]

The approach using --build-arg is the correct one: you only want to use the proxy settings when building the Docker image, and not having them inside the Dockerfile so it is not tied to an specific environment (you don't need the ENV entries on it). 使用--build-arg的方法是正确的方法:您只希望在构建Docker映像时使用代理设置,并且不将其包含在Dockerfile中,因此它与特定环境无关(您不需要上面的ENV条目)。

Your issue is that you are trying to use as cntlm proxy inside the docker build localhost , which is not valid since at build time it will point to the docker container running the build, but it should actually point to the address of your host offering cntlm in the docker network. 您的问题是您试图在docker build localhost用作cntlm代理,这是无效的,因为在构建时,它将指向运行构建的docker容器,但实际上应指向提供cntlm的主机的地址在docker网络中。

In order to make that work, you can configure your cntlm to listen in several interfaces, and then activate gateway mode so you can use it from other machines. 为了使它起作用,您可以将cntlm配置为侦听多个接口,然后激活网关模式,以便可以从其他计算机上使用它。 This way, when your image is being built, you will send the requests from the docker instance to the host. 这样,在构建映像时,您会将请求从Docker实例发送到主机。

My docker bridge network is as follows (my host gets as address in docker0 172.17.0.1 ): 我的Docker桥网络如下(我的主机以docker0 172.17.0.1地址获取):

$ docker network inspect bridge
...
            "Config": [
            {
                "Subnet": "172.17.0.0/16",
                "Gateway": "172.17.0.1"
            }
...

In my cntlm.conf : 在我的cntlm.conf

...
Listen          127.0.0.1:3128
Listen          172.17.0.1:3128
...
Gateway yes
Allow           127.0.0.1/32
Allow           172.17.0.0/16
Deny            0/0
...

With this config, cntlm will listen to both localhost and the docker bridge network, only allowing remote connections from any docker container. 使用此配置,cntlm将侦听localhost和docker bridge网络,仅允许来自任何docker容器的远程连接。

You then use the proxy settings when building your image with npm: 然后在使用npm构建映像时使用代理设置:

$ docker build --build-arg=HTTP_PROXY=http://172.17.0.1:3128 --build-arg=HTTPS_PROXY=http://172.17.0.1:3128 .

I hope that helps, I know that making all of this in corporate networks is really a pita! 我希望能有所帮助,我知道在企业网络中实现所有这些确实是皮塔饼!

EDIT 18-aug-2016 编辑2016年8月18日

Something I discovered today is, if you use docker-compose files with v2 format, starting the compose file will create a new network for your containers. 我今天发现的事情是,如果您使用v2格式的docker-compose文件,则启动compose文件将为您的容器创建一个新的网络。 This means that you need to adapt your cntlm file accordingly to accept connections from those new ranges. 这意味着您需要相应地调整cntlm文件以接受来自这些新范围的连接。

As an example, one of my compose files has just created a network under 172.19.0.0/16 , but my cntlm config only allowed connections from 172.17.0.0/16 . 例如,我的一个撰写文件刚刚在172.19.0.0/16下创建了一个网络,但是我的cntlm配置仅允许来自172.17.0.0/16连接。 Check your syslog to identify the issue if you experience connection problems. 如果遇到连接问题,请检查系统日志以识别问题。

https://docs.docker.com/compose/networking/ https://docs.docker.com/compose/networking/

Had the exact same situation!有完全一样的情况! Just setting proxy and http-proxy in .npmrc like this worked for me.像这样在.npmrc中设置proxyhttp-proxy对我有用。

proxy = http://your-company-proxy
https-proxy = http://your-company-proxy

Might also work if you run如果你跑步也可能有效

RUN npm config set proxy http://your-company-proxy
RUN npm config set https-proxy http://your-company-proxy

in your Dockerfile.在你的 Dockerfile 中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM