From 6dbce2f5cdea549efc1ff332d04740f6de9e242b Mon Sep 17 00:00:00 2001 From: Ricardo Pardini Date: Mon, 9 Nov 2020 16:25:04 +0100 Subject: [PATCH] Docker for Mac's Proxy GUI is a monster; avoid it by setting ENV directly in LinuxKit config --- Docker-for-Mac.md | 75 +++++++++++++++++++++++++++++------------------ 1 file changed, 47 insertions(+), 28 deletions(-) diff --git a/Docker-for-Mac.md b/Docker-for-Mac.md index 9d24bc6..6562cab 100644 --- a/Docker-for-Mac.md +++ b/Docker-for-Mac.md @@ -1,44 +1,63 @@ -# Attention: issues for developer scenarios! +# Attention: don't use Docker's own GUI to set the proxy! -- beware: this will probably break your Docker for Mac install in more ways than one -- docker for mac does bizarre stuff with proxies, affecting runtime and building of containers -- you might run into https://github.com/docker/for-mac/issues/2467 - - building images is affected for sure; simple "FROM ubuntu; RUN apt update" fails +- See https://github.com/docker/for-mac/issues/2467 +- In `Docker > Preferences`, in `Resources > Proxies`, make sure you're NOT using manual proxies +- Use the hack below to set the environment var directly in LinuxKit +- The issue is that setting it in the GUI affects containers too (!!!), and we don't want that in this scenario +- If you actually need an upstream proxy (for company proxy etc) this will NOT work. # Using a Docker Desktop for Mac as a client for the proxy First, know this is a MiTM, and could break with new Docker Desktop for Mac releases or during resets/reinstalls/upgrades. These instructions tested on Mac OS Catalina, and: -- Docker Desktop for Mac `2.5.0.0` (Stable) (which provides Docker `19.03`) - Docker Desktop for Mac `2.4.2.0` (Edge) (which provides Docker `20.10.0-beta1`) +- Docker Desktop for Mac `2.5.0.0` (Stable) (which provides Docker `19.03`) This assumes you have `docker-registry-proxy` running _somewhere else_, eg, on a different machine on your local network. See the main [README.md](README.md) for instructions. (If you're trying to run both proxy and client on the same machine, see below). -For these examples I will assume it is successfully running on `http://192.168.1.2:3128/` +We'll inject the CA certificates and the HTTPS_PROXY env into the Docker install inside the HyperKit VM running LinuxKit that is used by Docker Desktop for Mac. -- Make sure you can access the proxy. On your Mac/Terminal (not Docker), run: - ```shell script - # with wget... - wget --quiet -O - "http://192.168.1.2:3128/" - # ... or, with curl: - curl "http://192.168.1.2:3128/" - ``` -- Make sure your Docker Desktop for Mac install is pristine like new, go into Troubleshoot > "Reset to Factory defaults". -- Inject the CA certificates into the Docker install inside the HyperKit VM running LinuxKit that is used by Docker Desktop for Mac. - To do that, we use a privileged container. `justincormack/nsenter1` does the job nicely: - ```shell script - docker run -it --privileged --pid=host justincormack/nsenter1 /bin/bash -c "wget -O - http://192.168.1.2:3128/ca.crt | tee -a /containers/services/docker/lower/etc/ssl/certs/ca-certificates.crt" - ``` -- Go into `Docker > Preferences`, and set `Resources > Proxies` to - - "Manual proxy configuration" to ON - - HTTP proxy: `http://192.168.1.2:3128/` - - HTTPS proxy: `http://192.168.1.2:3128/` - - (Optional) I also recommend "Enable CLI experimental features" under "Experimental Features" (since I use `buildx` a lot) - - Click button "Apply & Restart", wait for it to restart. +To do that, we use a privileged container. `justincormack/nsenter1` does the job nicely. + +First things first: + +### 1) Factory Reset Docker Desktop for Mac... +... or make sure it's pristine (just installed). + +- Go into Troubleshoot > "Reset to Factory defaults" +- it will take a while to reset/restart everything and require your password. + +### 2) Inject config into Docker's VM + +For these examples I will assume it is successfully running on `http://192.168.1.2:3128/` -- +change the `export DRP_PROXY` as appropriate. Do not include slashes. + +Run these commands in your Mac terminal. + +```bash +set -e +export DRP_PROXY="192.168.66.100:3129" # Format IP:port, change this +wget -O - "http://${DRP_PROXY}/" # Make sure you can reach the proxy +# Inject the CA certificate +docker run -it --privileged --pid=host justincormack/nsenter1 \ + /bin/bash -c "wget -O - http://$DRP_PROXY/ca.crt \ + | tee -a /containers/services/docker/lower/etc/ssl/certs/ca-certificates.crt" + +# Preserve original config. +docker run -it --privileged --pid=host justincormack/nsenter1 /bin/bash -c "cp /containers/services/docker/config.json /containers/services/docker/config.json.orig" + +# Inject the HTTPS_PROXY enviroment variable. I dare you find a better way. +docker run -it --privileged --pid=host justincormack/nsenter1 /bin/bash -c "sed -ibeforedockerproxy -e 's/\"PATH=/\"HTTPS_PROXY=http:\/\/$DRP_PROXY\/\",\"PATH=/' /containers/services/docker/config.json" +``` + +### 3) Restart, test. + +- Restart Docker. (Quit & Open again, or just go into Preferences and give it more RAM, then Restart.) - Try a `docker pull` now. It should be using the proxy (watch the logs on the proxy server). +- Test that no crazy proxy has been set: `docker run -it curlimages/curl:latest http://ifconfig.me` and `docker run -it curlimages/curl:latest https://ifconfig.me` both work. - Important: **push**es done with this configured will either not work, or use the auth you configured on the proxy, if any. Beware, and report back. @@ -48,8 +67,8 @@ For these examples I will assume it is successfully running on `http://192.168.1 You need to pre-pull the proxy itself and `justincormack/nsenter1`. -Then set up the proxy server, and then follow the instructions above (without the Factory Reset). +Follow the instructions above, but pre-pull after the Factory Reset. -Do NOT use 127.0.0.1, instead use your machine's local LAN IP address. (Hint: there's a good chance 192.168.64.1 is useable, due the the way Docker Desktop for Mac sets networking up). +Do NOT use 127.0.0.1, instead use your machine's local LAN IP address. Make sure to bring the proxy up after applying/restarting the Docker Engine.