为node.js应用构建docker镜像会在代理

时间:2016-06-29 13:54:30

标签: node.js docker proxy npm corporate

我在docker构建期间遇到npm问题。我是一个公司代理的背后,已经阅读了大约30篇文章(和stackoverflow帖子)解决类似的问题。但是我仍然无法克服这一点。

我能够“npm install”项目并获取docker构建过程之外的所有必要依赖项(但也使用代理),但不能在。

期间。

到目前为止我尝试了什么:

  1. 直接使用代理(连同硬编码的身份验证数据)以及 在CNTLM。以下描述是使用CNTLM时。
  2. 使用http存储库,如下所示,使用strict_ssl false。
  3. npm config set strict-ssl=false \

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

    1. 将代理设置传递为--build-arg,env并通过RUN参数

    2. 从干净的git checkout(没有node_modules)开始,之后 运行npm install

    3. 我正在尝试构建:

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

      输出

      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
      

      这是我的码头脚本

      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" ]
      

1 个答案:

答案 0 :(得分:3)

使用--build-arg的方法是正确的:您只想在构建Docker映像时使用代理设置,而不是将它们放在Dockerfile中,因此它不依赖于特定环境(您不要需要ENV条目)。

您的问题是您尝试在docker build localhost中使用cntlm代理,这是无效的,因为在构建时它将指向运行构建的docker容器,但它实际上应该指向主机在docker网络中提供cntlm的地址。

为了实现这一目的,您可以将cntlm配置为在多个界面中进行侦听,然后激活网关模式,以便可以在其他计算机上使用它。这样,在构建映像时,您将把来自docker实例的请求发送到主机。

我的docker bridge网络如下(我的主机在docker0 172.17.0.1中获取地址):

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

在我的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
...

使用此配置,cntlm将侦听localhost和docker桥接网络,仅允许来自任何docker容器的远程连接。

然后在使用npm:

构建映像时使用代理设置
$ docker build --build-arg=HTTP_PROXY=http://172.17.0.1:3128 --build-arg=HTTPS_PROXY=http://172.17.0.1:3128 .

我希望有所帮助,我知道在公司网络中制作这一切真的是一个皮塔饼!

编辑18-aug-2016

我今天发现的一件事是,如果您使用具有v2格式的docker-compose文件,启动compose文件将为您的容器创建一个新网络。这意味着您需要相应地调整cntlm文件以接受来自这些新范围的连接。

例如,我的一个撰写文件刚刚在172.19.0.0/16下创建了一个网络,但我的cntlm配置只允许来自172.17.0.0/16的连接。如果遇到连接问题,请检查您的系统日志以确定问题。

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