Working in a corporate environment, it may come that web access is filtered through a proxy… and even an NTLM one which requiere MS-style authentication.
If you also are lucky enough to run Docker inside a Linux Virtual machine (not natively on Windows), your docker builds or package update operations may fail at first.
You may ease the building and running of docker containers by using an intermediate proxy (cntlm) that will authenticate your and forward your requests against the coprorate proxy, while acting as simpler (unanthenticated) proxy for your doacker daemon or containers.
Build images behind a proxy
- Coporate NTLM proxy - Windows 7 (running cntlm proxy properly configured, listenning to 127.0.0.1:9128, and NOT in gateway mode) - Virtual Box - Centos 7 - Docker
Make docker daemon use the proxy of the Windows host
Not hard but a bit complex:
The first thing to take care of with all these virtualization layers is that 127.0.0.1 means something different for each layer !
The tricky part is to understand that Virtual box creates a specific NIC inside CentOS (address is 10.0.2.x with a default gateway of 10.0.2.2). The 10.0.2.2 IP address is redirected by Virtual Box to the 127.0.0.1 of Windows, on which cntlm proxy is listenning.
Last thing, the daemon needs to be aware of proxy at build time (download an image from web), while apt-get or yum may need to be aware of proxy at build time but also possibly at runtime.
In short, from docker daemon perspective, the proxy is 10.0.2.2:9128
Docker daemon setup
[Service] Environment="HTTP_PROXY=http://10.0.2.2:9128/" Environment="HTTPS_PROXY=https://10.0.2.2:9128/"
Then reload configuration and restart daemon
sudo systemctl daemon-reload sudo systemctl restart docker
Build the image
Then you should run the build using buildtime-only proxy configuration:
docker build --build-arg http_proxy=http://10.0.2.2:9128 --build-arg https_proxy=https://10.0.2.2:9128 -t my_app .
--build-args needed for yum update only ?
Run containers behind a proxy
Here the context is a bit different: we want a running container to access the web. Generraly speaking, it may not be the best idea in production environments, but it may still greatly help you to test or develop inside container.
Quick and dirty: rely on another container to provide the proxy
The simplest way is to use an already existing container, made specifically to provide transparent cntlm proxy service to others through Docker -link capability. It allows your application to address the proxy by name.
You should rather build this container from source (rather than blindly downloading it) as you will entrust it sufficiently with your logins and passwords.
Several cntml proxies are available, I choose to use jaschac/cntlm.
Download / build image with:
docker pull jaschac/cntlm
Start jashac/cntlm container:
docker run --name cntlm -e CNTLM_USERNAME=your_username -e CNTLM_DOMAIN=your_domain -e CNTLM_PROXY_URL=your_parent_ proxy -e CNTLM_PROXY_PORT=your_parent_proxy_port -e CNTLM_PASSNTLMv2=yourhash -d jaschac/cntlm
Then start your applciation container with:
docker run --link cntlm:cntlm -it my_app /bin/bash
Note the –link option that allow your application to resolve the cntlm host destite in another container.
Optional: set the proxy env in the dockerfile:
ENV http_proxy http://cntlm:3128 ENV https_proxy https://cntlm:3128
Make your container aware of the external proxy
Use the same address (corresponding to Windows 127.0.0.1 through Virtual box) to let your container access the Windows cntlm proxy at runtime.
TBD: remains to be tested
ENV http_proxy http://10.0.2.2:9128 ENV https_proxy https://10.0.2.2:9128