If you ever tried to run Docker in a corporate network then you know what I’m talking about. To prevent potential intrusions, infrastructure engineers force all internet traffic to go through proxy servers, sometimes making it extremely difficult to run even the simplest thing.
Why should you read this article?
With this tutorial, you’ll learn everything there is to know on how to configure proxies for Docker engine and containers!
- configure proxy servers in Docker for Desktop
- configure proxy servers with Linux & Systemd
- use proxy servers with running containers
Let’s get started! 🚀
Quick refresher: what is a Proxy server?
A proxy server is simply a server that sits in between your machine and the Internet, that can interact with the outside of your network on your behalf.
The main reasons why you would want to use a Proxy are the following:
- To improve network performance by caching internet content
- As an additional layer of security by implementing additional encryption, protect against DoS attacks, blacklist dangerous sites, and much more
- For auditing and logging purposes, many companies need to track who and when access mission-critical systems
How Docker uses proxies
One thing that was very confusing for me at first, is that Docker daemon and Docker containers don’t share the same proxy configuration!
Settings for Docker engine
Your Docker engine needs to connect to the internet to access image registries and pull/push container images.
If your settings are not correct you will typically see errors when trying to use docker login
or pulling images from DockerHub, see below for example:
Setting a Proxy on Docker for Mac/Windows
If you’re running Docker for Desktop this is a really simple operation. You can do this from Docker’s settings Docker > Preferences > Resources > Proxies
. All you need to do is provide values for the following variables:
-
HTTP_PROXY
: the proxy server endpoint to handle HTTP calls -
HTTPS_PROXY
: the endpoint to handle HTTPS calls (notice this doesn’t have to be an https endpoint) -
NO_PROXY
: a list of hosts that Docker can reach without using the proxy (usually you’ll seelocalhost,127.0.0.1
in this field
After this, you should click the Apply & Restart button, and you’ll be able to push/pull images ✅
Using authentication
One question I get asked a lot is how to provide authentication if this form does not have a username and password field. I am not sure why they didn’t include such fields in the configuration, but you can just use URL authentication like this:
http://<username>:<password>@my.proxy.com:3128/
Enter fullscreen mode
Exit fullscreen mode
Setting a Proxy on Linux with Systemd
If you’re working with a Linux installation, you won’t have access to some nice Preferences menu. In Linux, the Docker engine is configured as a system service with Systemd.
Let’s dust off our System Administration skills! 👨🏻💻
In most Linux distributions, Docker is configured as a service with Systemd. You can alter the service configuration by creating an override file. Follow these simple steps:
1) Edit the Docker service configuration with:
> sudo systemctl edit docker.service
Enter fullscreen mode
Exit fullscreen mode
Systemd will open (or create) the service override file with your default terminal editor.
2) Add or modify the service configuration to include proxy variables. Your service file should look like this:
[Service]
Environment=“HTTP_PROXY=http://10.0.1.60:3128”
Environment=“HTTPS_PROXY=http://10.0.1.60:3128”
Environment=“NO_PROXY=localhost,127.0.0.1”
Enter fullscreen mode
Exit fullscreen mode
3) Save and close the file, and restart Docker with
> sudo systemctl restart docker.service
Enter fullscreen mode
Exit fullscreen mode
Running containers with proxy settings
Now that you set up proxies for Docker engine, you need to understand that Docker will never share those settings with running containers! 👎🏻
If you want your containers to access the internet, you’ll need to supply Proxy settings using environment variables like this for example:
Full Step-By-Step Tutorial
Take a look at my video below to see everything I described in the article in a real environment!
In the video, I’ll also explain how you can configure Docker to use proxy configuration for containers by default? This way you won’t have to pass http_proxy
and https_proxy
variables every time.
Productivity? Yes, please! 🚀
Don’t forget to follow me for more content like this!
Why setting the http_proxy and https_proxy environment variables has no effect on Docker for Windows (or, why there is no docker.ini or Windows Registry setting for this)
Docker for Windows allows you to use docker commands from cmd or PowerShell as if the Docker host were running locally on your PC. This is a clever illusion: while docker.exe is a Windows program, the Docker host you’re connecting to is really running in a Hyper-V virtual machine named MobyLinuxVM. So far, I have not found a way to SSH into this VM; had I done so, I could have set the HTTP_PROXY and HTTPS_PROXY environment variables by PowerShell script every time my PC’s IP address changed.
Caveats before beginning
I use this setup on Windows 10 and Docker for Windows 17.06. A colleague still using Docker for Windows 17.03 reports that he has over 20 instances of the DummyDesperatePoitras virtual switch, so if you’re not on 17.06 yet, I recommend updating.
The IP address (169.254.123.45), DNS host (10.1.1.1) and domain (mandie.net) are DEFINITELY not the right options for your configuration, and are just here to make the examples easier to read. Do NOT just cut and paste things from this page – but you shouldn’t do that anyway 😉
DummyDesperatePoitras: this weird Docker for Windows artifact turns out to be key
The Hyper-V DummyDesperatePoitras virtual switch gets made when the Docker virtual switch is. This is a workaround for some issue or other. It turns out to be extremely useful! I’d tried using the Docker virtual switch’s IP address as the proxy address, but that didn’t work.
DummyDesperatePoitras gets a random, non-routable (169.254.0.0/16) IP address.
Get that IP address using PowerShell (no need to be admin):
(GetNetIPAddress -InterfaceAlias "*DummyDesperate*" -AddressFamily IPv4).IPAddress
For this example, I’ll use 169.254.123.45 as the result of this command. Your randomly-generated IP address will almost certainly be different.
If you get more than one result, it might be due to the problem described earlier in this post that some older versions of Docker for Windows had, where the Docker virtual switch was removed every time and remade, without removing the DummyDesperatePoitras, but still being made every time the Docker virtual switch was made. As mentioned earlier, try uninstalling Docker for Windows (removing the MobyLinuxVM will remove any images or containers you’ve created), remove all the DummyDesperatePoitras virtual switches, and then installing the 17.06 or later version.
Just enough CNTLM
CNTLM is an executable primarily available on SourceForge (now under new management and no longer dispensing spyware with its downloads, but still…) that has not been updated in over 5 years. It runs as a service, which requires local admin. It goes against all my principles.
It is also the only practical way to use Unix-style command line tools with NTLM-authenticating corporate web proxies.
Promising alternative: the Python-based Windows proxy px (https://github.com/genotrance/px). It has the major advantage of not requiring your Windows password in any form, and the major disadvantage of needing to understand more than I do about Python to build and run it. If you manage this feat, please tell me about it, and better yet, write your own blog post about how you pulled it off.
Listening on 127.0.0.1:3128 or just 3128 and setting http://127.0.0.1:3128 as your proxy will not work for Docker for Windows, because the guest VM that is really your Docker host interprets that address as *itself*, not your Windows host running CNTLM.
Having it listen to 0.0.0.0:3128 and setting the PC’s IP address as the proxy works, but you have to then change your Docker settings any time your PC gets a new IP address – a routine occurrence for consultants or anyone moving around a large campus. It also means that your PC will act as a web proxy for ANYTHING that isn’t blocked by its firewall. This can be either a bug or a feature, but I officially recommend that you do not use it as a proxy for things outside of your desktop.
The advantage of having CNTLM listen on a non-routable but static IP address is that only traffic that originated on your PC can use the proxy, but you still don’t have to change it when your PC’s IP address changes.
CNTLM configuration is set in cntlm.ini, under C:\Program Files (x86)\cntlm. The easy way to use it is to set your Windows password directly in the file. That is also the terrible way to use it. If you store the NTLMv2 hash, at least it can’t be used anywhere other than your PC (which is still not great). Set your cntlm.ini file to only be readable to the account the cntlm Windows service is running under.
Here is a way to get your NTLMv2 hash: https://stackoverflow.com/a/44238035
Set CNTLM to listen for (DummyDesperatePoitras IP) 3128 – in this example:
Listen 169.254.123.45 3128
Remember to set your NoProxy subnets here: usually, 127.0.0.*, 10.*, 172.16.*-172.31.* and 192.168.*, but you might have others that shouldn’t go via the corporate web proxy.
Set your http_proxy and https_proxy in Windows for other command line tools
While testing, set it at the command line for your current session – note the http:// (not https://) for both.
For cmd:
set http_proxy=http://169.254.123.45:3128 set https_proxy=http://169.254.123.45:3128
PowerShell:
$env:http_proxy = "http://169.254.123.45:3128" $env:https_proxy = "http://169.254.123.45:3128"
This will only have effect for this session, and only as long as you have the window open.
Once you’re sure this works, set them in your profile’s environment variables. This change will not take effect until you log off and log back on to Windows.
Docker for Windows settings: Proxies and daemon.json
Right-click the little whale icon in the system tray and select “Settings…”, then click “Proxies”
Docker Proxy Settings
In the “Web Server (HTTP)” blank, type http://169.254.123.45:3128 (replace with the IP address you got from running the Get-NetIPAddress cmdlet at the beginning) and click the “Use same for both” box. You should set your proxy bypass addresses in cntlm.ini for consistency between all the command line tools you use.
Click “Apply” – this is necessary to save your changes (writing them to MobyLinuxVM), but will also restart Docker (MobyLinuxVM). Go get a coffee – this takes a minute or two.
Next, click “Daemon” so that we can give it a DNS server to use for your internal domains. Click the “Experimental features” checkbox and the “Basic” switch so that it turns to “Advanced”
Docker Daemon – Enable daemon.json editing
Add entries for dns and dns-search, remembering to separate each entry with a comma.
Your resulting JSON file should look like this, but with your internal domain and DNS server’s IP address instead of mandie.net’s:
{ "registry-mirrors": [], "insecure-registries": [], "debug": true, "experimental": true, "dns": [ "10.1.1.10" ], "dns-search": [ "mandie.net" ] }
Click “Apply,” and wait that minute or two again.
Testing, and extra help for docker build
Were we successful? Open cmd or PowerShell, and try pulling the hello-world image. Even if you have the latest version already, this goes out to docker.io and checks.
docker pull hello-world:latest
This configuration should be sufficient for pulling Docker images and running containers on your Docker host. However, any image builds that pull components from outside (apt-get, npm, etc.) will need to get the proxy information explicitly. You don’t want to store this in your Dockerfiles, since it’s specific to your PC. You can feed build-time environment variables like this:
docker build --build-arg http_proxy=http://169.254.123.45:3128 --build-arg https_proxy=http://169.254.123.45:3128 -t myawesomeimage:latest .
Let me know if something about this doesn’t work for you – I’m still a bit surprised that it works at all.
Working with Sitecore and Docker Desktop behind a proxy can be a common requirement in corporate environments. Configuring Docker to work seamlessly with a proxy ensures that you can pull images, run containers, and perform other Docker tasks without interruption. This guide will walk you through setting up Docker Desktop for Windows containers behind a proxy.
1. Understanding Your Proxy Settings
Before starting, make sure you have the necessary proxy details:
- Proxy server address: The URL or IP address of the proxy server.
- Port number: The port number for the proxy.
- Authentication credentials: Username and password (if required).
You may need to contact your network administrator to obtain these details.
2. Configuring Docker Desktop for Windows Containers
Docker Desktop on Windows requires specific configuration steps to ensure it works correctly behind a proxy, especially when using Windows containers.
Step 1: Configure Windows System Proxy Settings
Docker Desktop on Windows typically uses the system’s proxy settings, so it’s important to configure these first:
- Open Windows Settings: Press Win + I to open the Settings window.
- Navigate to Network & Internet > Proxy.
- Under Manual proxy setup, toggle Use a proxy server to On.
- Enter your proxy server’s address and port number.
- If your proxy requires a username and password, ensure those are set correctly under Authentication.
- Click Save to apply the changes.
Step 2: Configure Docker Daemon Proxy Settings for Windows Containers
After setting the system proxy, you need to configure Docker Daemon to work with these settings:
- Open Docker Desktop and go to Settings.
- Under Settings, select Resources > Proxies.
- Fill in the proxy details:
- HTTP Proxy:
http://<proxy_server>:<port>
- HTTPS Proxy:
http://<proxy_server>:<port>
- No Proxy: Enter any addresses that should bypass the proxy (e.g.,
localhost,127.0.0.1
).
- HTTP Proxy:
- Click Apply & Restart to save your changes and restart Docker.
Step 3: Configure Environment Variables for Docker CLI
Docker CLI also needs to recognize the proxy settings. Setting environment variables ensures Docker CLI commands work correctly with your proxy:
- Open PowerShell as an administrator.
- Set the following environment variables:powershellCopy code
[System.Environment]::SetEnvironmentVariable("HTTP_PROXY", "http://<proxy_server>:<port>", [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable("HTTPS_PROXY", "http://<proxy_server>:<port>", [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable("NO_PROXY", "localhost,127.0.0.1", [System.EnvironmentVariableTarget]::Machine)
- Restart your PowerShell session for the changes to take effect.
Step 4: Configure Docker’s Proxy Settings for Windows Containers
You need to set proxy settings specifically for Docker’s Windows containers. This involves modifying Docker’s configuration file:
- Open the Docker configuration file located at
%USERPROFILE%\.docker\config.json
. - Add or modify the
proxies
configuration section to include your proxy settings:jsonCopy code{ "proxies": { "default": { "httpProxy": "http://<proxy_server>:<port>", "httpsProxy": "http://<proxy_server>:<port>", "noProxy": "localhost,127.0.0.1" } } }
- Save the file and restart Docker Desktop to apply the changes.
3. Testing the Proxy Configuration with Windows Containers
To confirm that Docker is correctly set up to use the proxy with Windows containers, you can run a simple test:
- Open PowerShell.
- Run the following Docker command to test pulling a Windows-based container:powershellCopy code
docker run mcr.microsoft.com/windows/nanoserver:latest cmd /c echo Hello, World!
If Docker successfully pulls the Windows container image and runs the command, then your proxy configuration is correctly set up. If not, recheck the proxy settings and configuration files for any errors.
4. Troubleshooting Common Issues with Windows Containers
Even with proper setup, you might encounter issues. Here are a few tips for troubleshooting:
- Proxy Authentication: If you’re facing authentication errors, double-check your proxy credentials and ensure they’re encoded correctly in your environment variables or Docker settings.
- Windows Firewall or Antivirus Interference: Sometimes, firewall or antivirus software might block Docker’s proxy configuration. Check the settings to ensure Docker is allowed to communicate through the proxy.
- Docker Network Configuration: Windows containers use different networking stacks than Linux containers. Ensure that the network configuration for Windows containers is compatible with your proxy.
5. Advanced Configuration for Windows Containers
For more complex setups, such as using different proxies for different Docker contexts or configuring Windows containers in a Kubernetes environment, consult Docker and Kubernetes documentation for more details on proxy configurations.
Conclusion
Configuring Docker Desktop to work with Windows containers behind a proxy requires careful setup of system-wide proxy settings, Docker Daemon settings, and Docker CLI environment variables. Following the steps outlined in this guide will help ensure that Docker Desktop runs smoothly in a restricted network environment with Windows containers.
With these configurations, you should be able to work effectively with Docker Desktop and Windows containers, even behind a proxy.
In today’s article, I am going to explore a common pain point for anyone running Docker in a large corporate environment. Today I’ll show how to use Docker without direct internet access.
By default, Docker assumes that the system running Docker and executing Docker commands has general access to the internet. Often in large corporate networks this is simply not the case. More often than not, a corporate network will route all internet traffic through a proxy.
While this setup is generally transparent to the end user, this type of network environment often neglects command line tools such as Docker. For today’s article, we will use Docker to build and run a simple container within a «locked down» network.
A Simple Example of Working with a Proxy
In this article, we will be building a simple ubuntu
-based container that uses apt-get
to install curl
. While this example is simple, it will require us to leverage a proxy in several ways.
Before jumping into the proxy settings however, let’s take a quick look at the Dockerfile
we will be building from.
FROM ubuntu RUN apt-get update && apt-get install -y curl
The above Dockerfile
only has two instructions: FROM
, which is used to specify which base image to build the container from, and RUN
. RUN
is used to execute commands, in this case apt-get
commands.
Let’s go ahead and attempt to execute a docker build
to see what happens by default in a «locked down» network.
$ sudo docker build -t curl . Sending build context to Docker daemon 12.29 kB Sending build context to Docker daemon Step 0 : FROM ubuntu Pulling repository ubuntu INFO[0002] Get https://index.docker.io/v1/repositories/library/ubuntu/images: dial tcp 52.22.146.88:443: connection refused
From the above execution, we can see that the docker build
results in a download error of the base ubuntu
image. The reason is also pretty obvious: access to docker.io
was blocked.
In order for this to work within our network, Docker will need to route its request through a proxy. This will allow Docker to indirectly communicate with docker.io
.
Configuring Docker to Use a Proxy
On Ubuntu (which is the OS our Docker host is running), we can configure Docker to do this by simply editing the /etc/default/docker
file.
# If you need Docker to use an HTTP proxy, it can also be specified here. #export http_proxy="http://127.0.0.1:3128/"
Within the /etc/default/docker
file, there is a line that is commented by default which specifies the http_proxy
environmental variable.
In order to route Docker traffic through a proxy, we will need to uncomment this line and replace the default value with our proxy address.
# If you need Docker to use an HTTP proxy, it can also be specified here. export http_proxy="http://192.168.33.10:3128/"
In the above, we specify using the proxy located at 192.168.33.10:3128
. This proxy is a simple Squid proxy created using the sameersbn/squid:3.3.8-23
Docker container.
This proxy is not currently set up for username— or password-based authentication. However, if it was we could add those details using the https://username:password@192.168.33.10:3128/
format.
With changes made to /etc/default/docker
, we need to restart the Docker service before our changes will take effect.
We can do this by executing the service
command.
# service docker restart docker stop/waiting docker start/running, process 32703
With our changes in effect, let’s go ahead and see what happens when executing a docker build
command.
$ sudo docker build -t curl . Sending build context to Docker daemon 10.75 kB Sending build context to Docker daemon Step 0 : FROM ubuntu latest: Pulling from ubuntu 2a2723a6e328: Pull complete fa1b78b7309e: Pull complete 0ce8ddcea421: Pull complete c4cb212fd6fe: Pull complete 109d5efde28a: Pull complete 7f06d5cab2df: Pull complete Digest: sha256:f649e49c1ed34607912626a152efbc23238678af1ac37859b6223ef28e711a3f Status: Downloaded newer image for ubuntu:latest ---> 7f06d5cab2df Step 1 : RUN apt-get update && apt-get install -y curl ---> Running in 39b964be90bc Err:1 http://archive.ubuntu.com/ubuntu xenial InRelease Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8001::17). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8001::17 80] W: Failed to fetch http://archive.ubuntu.com/ubuntu/dists/xenial/InRelease Cannot initiate the connection to archive.ubuntu.com:80 (2001:67c:1360:8001::17). - connect (101: Network is unreachable) [IP: 2001:67c:1360:8001::17 80] W: Some index files failed to download. They have been ignored, or old ones used instead. Reading package lists... Building dependency tree... Reading state information... E: Unable to locate package curl INFO[0013] The command [/bin/sh -c apt-get update && apt-get install -y curl] returned a non-zero code: 100
From the above build output, we can see that Docker was able to pull the ubuntu
image successfully. However, our build still failed due to connectivity issues.
Specifically, our build failed during the apt-get
command execution.
The reason the build failed is because even though we configured Docker itself to use a proxy, the operating environment within the container is not configured to use a proxy. This means when apt-get
was executed within the container, it attempted to go directly to the internet without routing through the proxy.
In cases like this, it is important to remember that sometimes containers need to be treated in the same way we would treat any other system. The internal container environment works as if it is independent of the host system. That means configurations that exist on the host do not necessarily exist within the container. Our proxy is a prime example of that in practice.
To that end, if we were to stand up a physical or virtual machine with Ubuntu installed in this network environment, we would need to configure apt-get
on that system to utilize a proxy. Just like we configured Docker to utilize a proxy.
The same is true for the container we are building. Luckily, configuring a proxy for apt-get
is pretty easy.
https://js.hscta.net/cta/current.js
hbspt.cta.load(1169977, ‘b86f5b30-1e20-45f4-bc99-d136b7a8eeba’, {});
Configuring apt-get to Use a Proxy
We simply need to set the http_proxy
and https_proxy
environmental variables during build time. We can do this with the docker build
command itself.
$ sudo docker build -t curl --build-arg http_proxy=http://192.168.33.10:3128 .
Or we can specify the http_proxy
value using the ENV
instruction within the Dockerfile
.
Note: If you’re configuring environment variables in your Dockerfile, it’s also essential to understand how Docker’s CMD and ENTRYPOINT instructions determine how the container executes commands.
FROM ubuntu ENV http_proxy "http://192.168.33.10:3128" ENV https_proxy "http://192.168.33.10:3128" RUN apt-get update && apt-get install -y curl
Both options are useful in different situations, but for this article we will specify the values within our Dockerfile
.
Testing the proxy settings
With the http_proxy
and https_proxy
environmental variables added, let’s rerun our build.
$ sudo docker build -t curl . Sending build context to Docker daemon 10.75 kB Sending build context to Docker daemon Step 0 : FROM ubuntu latest: Pulling from ubuntu 2a2723a6e328: Pull complete fa1b78b7309e: Pull complete 0ce8ddcea421: Pull complete c4cb212fd6fe: Pull complete 109d5efde28a: Pull complete 7f06d5cab2df: Pull complete Digest: sha256:f649e49c1ed34607912626a152efbc23238678af1ac37859b6223ef28e711a3f Status: Downloaded newer image for ubuntu:latest ---> 7f06d5cab2df Step 1 : ENV http_proxy "http://192.168.33.10:3128" ---> Running in 6d66226a7cbf ---> 89fab90c9ca2 Removing intermediate container 6d66226a7cbf Step 2 : ENV https_proxy "http://192.168.33.10:3128" ---> Running in ce80b9502a59 ---> c490a0c49b2b Removing intermediate container ce80b9502a59 Step 3 : RUN apt-get update && apt-get install -y curl ---> Running in 2eb328075f7e Get:1 http://archive.ubuntu.com/ubuntu xenial InRelease [247 kB] Get:2 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB] Get:3 http://archive.ubuntu.com/ubuntu xenial-security InRelease [102 kB] Get:4 http://archive.ubuntu.com/ubuntu xenial/main Sources [1103 kB] Get:5 http://archive.ubuntu.com/ubuntu xenial/restricted Sources [5179 B]
From the above, it appears our build was successful. Let’s go ahead and run
this container.
$ sudo docker run curl curl -v http://blog.codeship.com * Rebuilt URL to: http://blog.codeship.com/ * Trying 192.168.33.10... > GET http://blog.codeship.com/ HTTP/1.1 > Host: blog.codeship.com > User-Agent: curl/7.47.0 > Accept: */* > Proxy-Connection: Keep-Alive > < HTTP/1.1 301 Moved Permanently < Server: nginx < Date: Wed, 22 Mar 2017 00:45:04 GMT < Content-Type: text/html < Content-Length: 178 < Location: https://blog.codeship.com/
With the above curl
command output, we can see that our request to http://blog.codeship.com
was also proxied through the 192.168.33.10
proxy server. The reason for this is based on the way we specified the proxies within the container. The curl
command like apt-get
, uses the http_proxy
and https_proxy
environmental variables.
It is important to remember that these values not only affect the container during build but also during execution. If for some reason we did not want to use this proxy during the execution of the container, we would need to reset the http_proxy
and https_proxy
values by either passing new values during docker run execution or by changing our Dockerfile
to match the below.
FROM ubuntu ENV http_proxy "http://192.168.33.10:3128" ENV https_proxy "http://192.168.33.10:3128" RUN apt-get update && apt-get install -y curl ENV http_proxy "" ENV https_proxy ""
With the above, when the container is launched with docker run
, the http_proxy
and https_proxy
values will be unset, allowing the container to route traffic without going through a proxy.
Summary
In this article, we covered how to configure Docker (on Ubuntu) to use a proxy to download container images. We also explored how to configure apt-get
within the container to use a proxy and why it is necessary.
While this is useful for Ubuntu laptops and hosts running Docker, many people use the Docker for Mac & Windows application. Luckily, the proxy configuration for Docker for Mac & Windows is pretty easy as well. In fact, it is part of the Docker preferences configuration.
In the Docker preferences, there is an option for Proxies. If you simply click this option, you can add both an HTTP
and HTTPS
proxy using the Manual proxy configuration option.
This setting will allow you to pull images from docker.io
, however, it does not replace configuring the proxy within the container. That step is required regardless of where the container is built.
This post describes how you can work around a firewall to pull Docker images
from a server that you do not have direct access to, using a SOCKS5 proxy.
Why would you want to do this?
Let us assume you are in a corporate environment. And let us further assume that
you want to pull Docker images from a registry that you do not have direct
access to from that corporate environment, for instance because the registry is
running on a non-standard port and is thus blocked by a firewall.
So for instance the following does not work for you:
docker pull registry.example.com:5678/image
Now let’s make a few more assumptions:
- You have got SSH access to a machine outside of the corporate environment.
- You are not violating any policy by bypassing the firewall, or have permission
to do so.
Workaround
To work around the issue, you can do the following:
- Connect to a machine over SSH
- Tunnel your
docker pull
command via that SSH connection.
Setting up the SOCKS5 proxy connection
You are going to use the -D
option in your SSH command. This allocates a
socket listing on a port. Connections made to this port are forwarded over the
(secure) channel.
For example, if you can use host 172.31.10.5
as a proxy, the command would look
like this:
Every connection to port 8080
on localhost
is proxied via host 172.31.10.5
.
Configure Docker
To make Docker use the proxy, you will have to configure dockerd
. One way to do
this is to create the file /etc/systemd/system/docker.service.d/proxy.conf
with the following content:
[Service]
Environment="HTTP_PROXY=socks5://127.0.0.1:8080"
Environment="HTTPS_PROXY=socks5://127.0.0.1:8080"
(You most likely do not even need the HTTP_PROXY
line, but it also doesn’t
hurt. )
Once this file is in place, you need to restart the Docker service:
systemctl daemon-reload
systemctl restart docker
When you run the following command again, the traffic is tunneled via your proxy.
docker pull registry.example.com:5678/image
Voilà, the firewall is bypassed and you can now pull your Docker image.