Docker CLI behind a Squid proxy
While helping analyse a problem with docker-machine behind an HTTP proxy, I figured that I have never setup a squid proxy with Docker myself, and wanted to see what I can learn..
Use case
A container environment in a DMZ behind a (corporate) HTTP proxy, or a home lab without direct internet access come to mind.
Squid proxy as a container
Ubuntu provides a ready-to-use squid image which does not need any extra configuration other than mapping port 3128.
docker run -d --name squid-container -e TZ=UTC -p 3128:3128 ubuntu/squid:5.2-22.04_beta
Tell the Docker CLI to use a proxy
For Docker client operations such as pull
, push
, etc. you'll actually need to configure the Docker daemon instead. All other HTTP Proxy settings in config.json or as --env
parameter are passed as environment variables into the container itself.
On a Ubuntu 20 LTS VM, Docker runs as systemd service, and needs the HTTP_PROXY
and HTTPS_PROXY
environment variables being specified in Service
section. Best practice is to not edit the package provided configuration but to create a snippet that overrides/adds settings.
sudo mkdir -p /etc/systemd/system/docker.service.d
sudo vim /etc/systemd/system/docker.service.d/http-proxy.conf
[Service]
Environment="HTTPS_PROXY=http://localhost:3128"
Environment="HTTP_PROXY=http://localhost:3128"
Reload the systemd configuration and restart Docker. Note that all running containers will need to be restarted too (docker-compose: restart: always).
sudo systemctl daemon-reload
sudo systemctl restart docker
Re-create the squid proxy container.
docker rm squid-container
docker run -d --name squid-container -e TZ=UTC -p 3128:3128 ubuntu/squid:5.2-22.04_beta
Test docker pull and inspect proxy logs
Open a new terminal to follow the squid proxy container logs using the following command. Adjust the container name if you modified it above.
docker logs -f squid-container
Next, pull images which are not in use yet, and delete them afterwards, to save disk space and recreate the same test conditions.
$ docker pull alpine:latest
latest: Pulling from library/alpine
2408cc74d12b: Pull complete
Digest: sha256:686d8c9dfa6f3ccfc8230bc3178d23f84eeaf7e457f36f271ab1acc53015037c
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest
$ docker rmi alpine:latest
Inspect the squid container logs to see all outgoing requests.
1655892244.445 402 172.17.0.1 TCP_TUNNEL/200 6087 CONNECT registry-1.docker.io:443 - HIER_DIRECT/3.215.210.111 -
1655892244.858 407 172.17.0.1 TCP_TUNNEL/200 10284 CONNECT auth.docker.io:443 - HIER_DIRECT/54.144.118.70 -
1655892245.324 462 172.17.0.1 TCP_TUNNEL/200 6219 CONNECT registry-1.docker.io:443 - HIER_DIRECT/3.215.210.111 -
1655892245.793 459 172.17.0.1 TCP_TUNNEL/200 7857 CONNECT registry-1.docker.io:443 - HIER_DIRECT/3.215.210.111 -
1655892246.258 440 172.17.0.1 TCP_TUNNEL/200 6741 CONNECT registry-1.docker.io:443 - HIER_DIRECT/3.215.210.111 -
1655892246.678 406 172.17.0.1 TCP_TUNNEL/200 6143 CONNECT registry-1.docker.io:443 - HIER_DIRECT/3.215.210.111 -
1655892246.704 431 172.17.0.1 TCP_TUNNEL/200 6139 CONNECT registry-1.docker.io:443 - HIER_DIRECT/3.215.210.111 -
1655892246.762 55 172.17.0.1 TCP_TUNNEL/200 5227 CONNECT production.cloudflare.docker.com:443 - HIER_DIRECT/104.18.125.25 -
1655892246.787 105 172.17.0.1 TCP_TUNNEL/200 2809694 CONNECT production.cloudflare.docker.com:443 - HIER_DIRECT/104.18.125.25 -
Pulling the container worked through the proxy. If it does not, or the client receives errors such as
Error response from daemon: Get “https://registry-1.docker.io/v2/”: http: server gave HTTP response to HTTPS client
the logs are a great way to inspect the traffic flow, and analyse potential configuration mistakes for http/https responses when the proxy returns HTTP but the client initiated a HTTPS connection.
Remove squid proxy again
I've tested in my production environment running this website, and do not need a proxy by default. Below are the steps to remove the container image and systemd settings.
$ sudo rm /etc/systemd/system/docker.service.d/http-proxy.conf
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
$ docker rm squid-container
$ docker rmi ubuntu/squid:5.2-22.04_beta