Docker CLI behind a Squid proxy

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..

Docker-machine docker error
Hi Michi, I am not sure what you are asking for ie context/URL, I simply spun up docker+machine executor on vsphere and when I used that runner for a CI job it failed because it had no internet access and I was unable to configure it to point it to the proxy server. My workaround for that is to si…

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


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 rmi alpine:latest

Inspect the squid container logs to see all outgoing requests.

1655892244.445    402 TCP_TUNNEL/200 6087 CONNECT - HIER_DIRECT/ -
1655892244.858    407 TCP_TUNNEL/200 10284 CONNECT - HIER_DIRECT/ -
1655892245.324    462 TCP_TUNNEL/200 6219 CONNECT - HIER_DIRECT/ -
1655892245.793    459 TCP_TUNNEL/200 7857 CONNECT - HIER_DIRECT/ -
1655892246.258    440 TCP_TUNNEL/200 6741 CONNECT - HIER_DIRECT/ -
1655892246.678    406 TCP_TUNNEL/200 6143 CONNECT - HIER_DIRECT/ -
1655892246.704    431 TCP_TUNNEL/200 6139 CONNECT - HIER_DIRECT/ -
1655892246.762     55 TCP_TUNNEL/200 5227 CONNECT - HIER_DIRECT/ -
1655892246.787    105 TCP_TUNNEL/200 2809694 CONNECT - HIER_DIRECT/ -

Pulling the container worked through the proxy. If it does not, or the client receives errors such as

Error response from daemon: Get “”: 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