diff --git a/README.md b/README.md index 13058c0..76594fa 100644 --- a/README.md +++ b/README.md @@ -21,12 +21,13 @@ for this to work it requires inserting a root CA certificate into system trusted - Map volume `/docker_mirror_cache` for up to 32gb of cached images from all registries - Map volume `/ca`, the proxy will store the CA certificate here across restarts - Env `REGISTRIES`: space separated list of registries to cache; no need to include Docker Hub, its already there. -- Env `AUTH_REGISTRIES`: space separated list of `hostname:username:password` authentication info. +- Env `AUTH_REGISTRIES`: space separated list of `hostname:username:password` authentication info. - `hostname`s listed here should be listed in the REGISTRIES environment as well, so they can be intercepted. - For Docker Hub authentication, `hostname` should be `auth.docker.io`, username should NOT be an email, use the regular username. - For regular registry auth (HTTP Basic), `hostname` here should be the same... unless your registry uses a different auth server. This should work for quay.io also, but I have no way to test. - - For Google Container Registry (GCR), username should be `_json_key` and the password should be the contents of the service account JSON. Check out [GCR docs](https://cloud.google.com/container-registry/docs/advanced-authentication#json_key_file) - + - Env `AUTH_REGISTRIES_DELIMITER` to change the separator between authentication info. By default, a space: "` `". If you use keys that contain spaces (as with Google Cloud Registry), you should update this variable, e.g. setting it to `AUTH_REGISTRIES_DELIMITER=";;;"`. In that case, `AUTH_REGISTRIES` could contain something like `registry1.com:user1:pass1;;;registry2.com:user2:pass2`. + - Env `AUTH_REGISTRY_DELIMITER` to change the separator between authentication info *parts*. By default, a colon: "`:`". If you use keys that contain single colons, you should update this variable, e.g. setting it to `AUTH_REGISTRIES_DELIMITER=":::"`. In that case, `AUTH_REGISTRIES` could contain something like `registry1.com:::user1:::pass1 registry2.com:::user2:::pass2`. + - For Google Container Registry (GCR), username should be `_json_key` and the password should be the contents of the service account JSON. Check out [GCR docs](https://cloud.google.com/container-registry/docs/advanced-authentication#json_key_file). The service account key is in JSON format, it contains spaces ("` `") and colons ("`:`"). To be able to use GCR you should set `AUTH_REGISTRIES_DELIMITER` to something different than space (e.g. `AUTH_REGISTRIES_DELIMITER=";;;"`) and `AUTH_REGISTRY_DELIMITER` to something different than a single colon (e.g. `AUTH_REGISTRY_DELIMITER=":::"`). ```bash docker run --rm --name docker_registry_proxy -it \ @@ -38,6 +39,20 @@ docker run --rm --name docker_registry_proxy -it \ rpardini/docker-registry-proxy:0.2.4 ``` +Example with GCR using credentials from a service account from a key file `servicekey.json`: + +```bash +docker run --rm --name docker_registry_proxy -it \ + -p 0.0.0.0:3128:3128 \ + -v $(pwd)/docker_mirror_cache:/docker_mirror_cache \ + -v $(pwd)/docker_mirror_certs:/ca \ + -e REGISTRIES="k8s.gcr.io gcr.io quay.io your.own.registry another.public.registry" \ + -e AUTH_REGISTRIES_DELIMITER=";;;" \ + -e AUTH_REGISTRY_DELIMITER=":::" \ + -e AUTH_REGISTRIES="gcr.io:::_json_key:::$(cat servicekey.json);;;auth.docker.io:::dockerhub_username:::dockerhub_password" \ + rpardini/docker-registry-proxy:0.2.4 +``` + Let's say you did this on host `192.168.66.72`, you can then `curl http://192.168.66.72:3128/ca.crt` and get the proxy CA certificate. #### Configuring the Docker clients / Kubernetes nodes diff --git a/entrypoint.sh b/entrypoint.sh index 701f4d4..a661baa 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -34,15 +34,35 @@ export ALLDOMAINS=${ALLDOMAINS:1} # remove the first comma and export # Now handle the auth part. echo -n "" > /etc/nginx/docker.auth.map -for ONEREGISTRYIN in ${AUTH_REGISTRIES}; do - ONEREGISTRY=$(echo -n ${ONEREGISTRYIN} | xargs) # Remove whitespace - AUTH_HOST=$(echo -n ${ONEREGISTRY} | cut -d ":" -f 1 | xargs) - AUTH_USER=$(echo -n ${ONEREGISTRY} | cut -d ":" -f 2 | xargs) - AUTH_PASS=$(echo -n ${ONEREGISTRY} | cut -d ":" -f 3 | xargs) - AUTH_BASE64=$(echo -n ${AUTH_USER}:${AUTH_PASS} | base64 | xargs) - echo "Adding Auth for registry '${AUTH_HOST}' with user '${AUTH_USER}'." - echo "\"${AUTH_HOST}\" \"${AUTH_BASE64}\";" >> /etc/nginx/docker.auth.map -done +# Only configure auth registries if the env var contains values +if [ "$AUTH_REGISTRIES" ]; then + # Ref: https://stackoverflow.com/a/47633817/219530 + AUTH_REGISTRIES_DELIMITER=${AUTH_REGISTRIES_DELIMITER:-" "} + s=$AUTH_REGISTRIES$AUTH_REGISTRIES_DELIMITER + auth_array=(); + while [[ $s ]]; do + auth_array+=( "${s%%"$AUTH_REGISTRIES_DELIMITER"*}" ); + s=${s#*"$AUTH_REGISTRIES_DELIMITER"}; + done + + AUTH_REGISTRY_DELIMITER=${AUTH_REGISTRY_DELIMITER:-":"} + + for ONEREGISTRY in "${auth_array[@]}"; do + s=$ONEREGISTRY$AUTH_REGISTRY_DELIMITER + registry_array=(); + while [[ $s ]]; do + registry_array+=( "${s%%"$AUTH_REGISTRY_DELIMITER"*}" ); + s=${s#*"$AUTH_REGISTRY_DELIMITER"}; + done + AUTH_HOST="${registry_array[0]}" + AUTH_USER="${registry_array[1]}" + AUTH_PASS="${registry_array[2]}" + # make base64 not wrap lines: https://superuser.com/a/1225334 + AUTH_BASE64=$(echo -n "${AUTH_USER}:${AUTH_PASS}" | base64 | tr -d \\n ) + echo "Adding Auth for registry '${AUTH_HOST}' with user '${AUTH_USER}'." + echo "\"${AUTH_HOST}\" \"${AUTH_BASE64}\";" >> /etc/nginx/docker.auth.map + done +fi echo "" > /etc/nginx/docker.verify.ssl.conf if [[ "a${VERIFY_SSL}" == "atrue" ]]; then