The bulk of this post is from Mike Mylonakis and his blog post Using docker behind an http proxy with authentication. I'm writing my own post with my modifications to aid in my learning
The problem
At my place of work, all internet traffic must go via a proxy server, and all requests must include authentication.
Following the official documentation whenever I did a docker pull
I get this error:-
Error response from daemon: Get https://registry-1.docker.io/v2/: proxyconnect tcp: dial tcp: lookup http: Temporary failure in name resolution
My environment
$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.4 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.4 LTS"
VERSION_ID="18.04"
$ sudo docker version
Client: Docker Engine - Community
Version: 19.03.6
API version: 1.40
Go version: go1.12.16
Git commit: 369ce74a3c
Built: Thu Feb 13 01:27:49 2020
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
Version: 19.03.6
API version: 1.40 (minimum version 1.12)
Go version: go1.12.16
Git commit: 369ce74a3c
Built: Thu Feb 13 01:26:21 2020
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.2.10
GitCommit: b34a5c8af56e510852c35414db4c1f4fa6172339
runc:
Version: 1.0.0-rc8+dev
GitCommit: 3e425f80a8c931f88e6d94a8c831b9d5aa481657
docker-init:
Version: 0.18.0
GitCommit: fec3683
TLDR; Solution
The authentication system is backed by Microsoft Active Directory, so usernames are in the form domain\username
. The \
(backslash) symbol is not interpreted by systemd on Ubuntu and escaping it/urlencoding it fails to work too. I need to put the environment variables in a file and get systemd to read that file; this way special characters can be used
Detail
Pre-reqs
- Install Docker as per the usual documentation
Steps to fix
-
Create a system default folder
$ sudo mkdir -p /etc/system/default
-
Create an environment file
$ sudo nano /etc/system/default/docker.env
-
Put the following in (replace the <> placeholders as required (note the
%5C
which is a urlencoded\
character)http_proxy="http://<domain>%5C<username>:<password>@<proxy address>:<port>/"
-
Create a systemd drop-in directory for the docker service:
$ sudo mkdir -p /etc/systemd/system/docker.service.d
-
Create a file called /etc/systemd/system/docker.service.d/environment.conf that specifies the EnvironmentFile location:
[Service] EnvironmentFile=/etc/system/default/docker.env
-
Reload the systemd and docker to pick up the new config
$ sudo systemctl daemon-reload && sudo systemctl restart docker
-
Check the environment variables for the running dockerd process
$ sudo cat /proc/$(pgrep dockerd)/environ | tr '\0' '\n'
Extra notes
As systemd
controls the startup of the docker daemon, I initially followed the docker official documentation to set the http_proxy
environment variable for the docker daemon process. When this clearly wasn't working (a tcpdump
showed me traffic from my machine was going direct to docker.io
during docker pull
and related commands), I hit the web search and came upon Mike Mylonakis and his blog post Using docker behind an http proxy with authentication, without which I would not have figured this out.