diff --git a/Dockerfile b/Dockerfile index a5238ec..53065ff 100644 --- a/Dockerfile +++ b/Dockerfile @@ -97,5 +97,20 @@ ENV MANIFEST_CACHE_DEFAULT_TIME="1h" # Should we allow actions different than pull, default to false. ENV ALLOW_PUSH="false" +# Timeouts +# ngx_http_core_module +ENV SEND_TIMEOUT="60s" +ENV CLIENT_BODY_TIMEOUT="60s" +ENV CLIENT_HEADER_TIMEOUT="60s" +ENV KEEPALIVE_TIMEOUT="300s" +# ngx_http_proxy_module +ENV PROXY_READ_TIMEOUT="60s" +ENV PROXY_CONNECT_TIMEOUT="60s" +ENV PROXY_SEND_TIMEOUT="60s" +# ngx_http_proxy_connect_module - external module +ENV PROXY_CONNECT_READ_TIMEOUT="60s" +ENV PROXY_CONNECT_CONNECT_TIMEOUT="60s" +ENV PROXY_CONNECT_SEND_TIMEOUT="60s" + # Did you want a shell? Sorry, the entrypoint never returns, because it runs nginx itself. Use 'docker exec' if you need to mess around internally. ENTRYPOINT ["/entrypoint.sh"] diff --git a/README.md b/README.md index 6f2ef47..a419e99 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,7 @@ for this to work it requires inserting a root CA certificate into system trusted ## master/:latest is unstable/beta - `:latest` and `:latest-debug` Docker tag is unstable, built from master, and amd64-only -- Production/stable is `0.6.1`, see [0.6.1 tag on Github](https://github.com/rpardini/docker-registry-proxy/tree/0.6.1) - this image is multi-arch amd64/arm64 +- Production/stable is `0.6.2`, see [0.6.2 tag on Github](https://github.com/rpardini/docker-registry-proxy/tree/0.6.2) - this image is multi-arch amd64/arm64 - The previous version is `0.5.0`, without any manifest caching, see [0.5.0 tag on Github](https://github.com/rpardini/docker-registry-proxy/tree/0.5.0) - this image is multi-arch amd64/arm64 ## Also hosted on GitHub Container Registry (ghcr.io) @@ -79,6 +79,7 @@ for this to work it requires inserting a root CA certificate into system trusted - Expose port 3128 to the network - Map volume `/docker_mirror_cache` for up to `CACHE_MAX_SIZE` (32gb by default) of cached images across all cached registries - Map volume `/ca`, the proxy will store the CA certificate here across restarts. **Important** this is security sensitive. +- Env `ALLOW_PUSH` : This bypasses the proxy when pushing, default to false - if kept to false, pushing will not work. For more info see this [commit](https://github.com/rpardini/docker-registry-proxy/commit/536f0fc8a078d03755f1ae8edc19a86fc4b37fcf). - Env `CACHE_MAX_SIZE` (default `32g`): set the max size to be used for caching local Docker image layers. Use [Nginx sizes](http://nginx.org/en/docs/syntax.html). - Env `ENABLE_MANIFEST_CACHE`, see the section on pull rate limiting. - Env `REGISTRIES`: space separated list of registries to cache; no need to include DockerHub, its already done internally. @@ -86,6 +87,18 @@ for this to work it requires inserting a root CA certificate into system trusted - `hostname`s listed here should be listed in the REGISTRIES environment as well, so they can be intercepted. - 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`. +- Timeouts ENVS - all of them can pe specified to control different timeouts, and if not set, the defaults will be the ones from `Dockerfile`. The directives will be added into `http` block.: + - SEND_TIMEOUT : see [send_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#send_timeout) + - CLIENT_BODY_TIMEOUT : see [client_body_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_body_timeout) + - CLIENT_HEADER_TIMEOUT : see [client_header_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#client_header_timeout) + - KEEPALIVE_TIMEOUT : see [keepalive_timeout](http://nginx.org/en/docs/http/ngx_http_core_module.html#keepalive_timeout + - PROXY_READ_TIMEOUT : see [proxy_read_timeout](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_read_timeout) + - PROXY_CONNECT_TIMEOUT : see [proxy_connect_timeout](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_connect_timeout) + - PROXY_SEND_TIMEOUT : see [proxy_send_timeout](http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_send_timeout) + - PROXY_CONNECT_READ_TIMEOUT : see [proxy_connect_read_timeout](https://github.com/chobits/ngx_http_proxy_connect_module#proxy_connect_read_timeout) + - PROXY_CONNECT_CONNECT_TIMEOUT : see [proxy_connect_connect_timeout](https://github.com/chobits/ngx_http_proxy_connect_module#proxy_connect_connect_timeout) + - PROXY_CONNECT_SEND_TIMEOUT : see [proxy_connect_send_timeout](https://github.com/chobits/ngx_http_proxy_connect_module#proxy_connect_send_timeout)) + ### Simple (no auth, all cache) ```bash @@ -93,7 +106,7 @@ docker run --rm --name docker_registry_proxy -it \ -p 0.0.0.0:3128:3128 -e ENABLE_MANIFEST_CACHE=true \ -v $(pwd)/docker_mirror_cache:/docker_mirror_cache \ -v $(pwd)/docker_mirror_certs:/ca \ - rpardini/docker-registry-proxy:0.6.1 + rpardini/docker-registry-proxy:0.6.2 ``` ### DockerHub auth @@ -109,7 +122,7 @@ docker run --rm --name docker_registry_proxy -it \ -v $(pwd)/docker_mirror_certs:/ca \ -e REGISTRIES="k8s.gcr.io gcr.io quay.io your.own.registry another.public.registry" \ -e AUTH_REGISTRIES="auth.docker.io:dockerhub_username:dockerhub_password your.own.registry:username:password" \ - rpardini/docker-registry-proxy:0.6.1 + rpardini/docker-registry-proxy:0.6.2 ``` ### Simple registries auth (HTTP Basic auth) @@ -137,7 +150,7 @@ docker run --rm --name docker_registry_proxy -it \ -v $(pwd)/docker_mirror_certs:/ca \ -e REGISTRIES="reg.example.com git.example.com" \ -e AUTH_REGISTRIES="git.example.com:USER:PASSWORD" \ - rpardini/docker-registry-proxy:0.6.1 + rpardini/docker-registry-proxy:0.6.2 ``` ### Google Container Registry (GCR) auth @@ -160,7 +173,7 @@ docker run --rm --name docker_registry_proxy -it \ -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.6.1 + rpardini/docker-registry-proxy:0.6.2 ``` ## Configuring the Docker clients using Docker Desktop for Mac @@ -188,10 +201,18 @@ Environment="HTTP_PROXY=http://192.168.66.72:3128/" Environment="HTTPS_PROXY=http://192.168.66.72:3128/" EOD +### UBUNTU # Get the CA certificate from the proxy and make it a trusted root. curl http://192.168.66.72:3128/ca.crt > /usr/share/ca-certificates/docker_registry_proxy.crt echo "docker_registry_proxy.crt" >> /etc/ca-certificates.conf update-ca-certificates --fresh +### + +### CENTOS +# Get the CA certificate from the proxy and make it a trusted root. +curl http://192.168.66.72:3128/ca.crt > /etc/pki/ca-trust/source/anchors/docker_registry_proxy.crt +update-ca-trust +### # Reload systemd systemctl daemon-reload @@ -223,7 +244,7 @@ docker run --rm --name docker_registry_proxy -it -p 0.0.0.0:3128:3128 -e ENABLE_MANIFEST_CACHE=true \ -v $(pwd)/docker_mirror_cache:/docker_mirror_cache \ -v $(pwd)/docker_mirror_certs:/ca \ - rpardini/docker-registry-proxy:0.6.1-debug + rpardini/docker-registry-proxy:0.6.2-debug ``` - `DEBUG=true` enables the mitmweb proxy between Docker clients and the caching layer, accessible on port 8081 @@ -234,7 +255,7 @@ docker run --rm --name docker_registry_proxy -it - If you authenticate to a private registry and pull through the proxy, those images will be served to any client that can reach the proxy, even without authentication. *beware* - Repeat, **this will make your private images very public if you're not careful**. -- **Currently you cannot push images while using the proxy** which is a shame. PRs welcome. +- ~~**Currently you cannot push images while using the proxy** which is a shame. PRs welcome.~~ **SEE `ALLOW_PUSH` ENV FROM USAGE SECTION.** - Setting this on Linux is relatively easy. - On Mac and Windows the CA-certificate part will be very different but should work in principle. - Please send PRs with instructions for Windows and Mac if you succeed! diff --git a/entrypoint.sh b/entrypoint.sh index 039c87e..ccabc97 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -117,7 +117,7 @@ EOD } EOD -echo "Manifest caching config: ---" +echo -e "\nManifest caching config: ---\n" cat /etc/nginx/nginx.manifest.caching.config.conf echo "---" @@ -201,6 +201,33 @@ if [[ "a${DEBUG_NGINX}" == "atrue" ]]; then NGINX_BIN="/usr/sbin/nginx-debug" fi + +# Timeout configurations +echo "" > /etc/nginx/nginx.timeouts.config.conf +cat <>/etc/nginx/nginx.timeouts.config.conf + # Timeouts + + # ngx_http_core_module + keepalive_timeout ${KEEPALIVE_TIMEOUT}; + send_timeout ${SEND_TIMEOUT}; + client_body_timeout ${CLIENT_BODY_TIMEOUT}; + client_header_timeout ${CLIENT_HEADER_TIMEOUT}; + + # ngx_http_proxy_module + proxy_read_timeout ${PROXY_READ_TIMEOUT}; + proxy_connect_timeout ${PROXY_CONNECT_TIMEOUT}; + proxy_send_timeout ${PROXY_SEND_TIMEOUT}; + + # ngx_http_proxy_connect_module - external module + proxy_connect_read_timeout ${PROXY_CONNECT_READ_TIMEOUT}; + proxy_connect_connect_timeout ${PROXY_CONNECT_CONNECT_TIMEOUT}; + proxy_connect_send_timeout ${PROXY_CONNECT_SEND_TIMEOUT}; +EOD + +echo -e "\nTimeout configs: ---" +cat /etc/nginx/nginx.timeouts.config.conf +echo -e "---\n" + # Upstream SSL verification. echo "" > /etc/nginx/docker.verify.ssl.conf if [[ "a${VERIFY_SSL}" == "atrue" ]]; then @@ -217,7 +244,6 @@ else echo "Upstream SSL certificate verification is DISABLED." fi - echo "Testing nginx config..." ${NGINX_BIN} -t diff --git a/nginx.conf b/nginx.conf index 24bb5c9..42cf0dc 100644 --- a/nginx.conf +++ b/nginx.conf @@ -14,6 +14,9 @@ http { map_hash_bucket_size 128; include /etc/nginx/mime.types; default_type application/octet-stream; + + # Include nginx timeout configs + include /etc/nginx/nginx.timeouts.config.conf; # Use a debug-oriented logging format. log_format debugging escape=json @@ -73,7 +76,6 @@ http { '"upstream":"$upstream_addr"' '}'; - keepalive_timeout 300; gzip off; # Entrypoint generates the proxy_cache_path here, so it is configurable externally. @@ -131,7 +133,7 @@ http { # The proxy director layer, listens on 3128 server { listen 3128; - server_name _; + server_name proxy_director_; # dont log the CONNECT proxy. #access_log /var/log/nginx/access.log debug_proxy; @@ -199,7 +201,7 @@ echo "Docker configured with HTTPS_PROXY=$scheme://$http_host/" # actually could be 443 or 444, depending on debug. this is now generated by the entrypoint. listen 80 default_server; include /etc/nginx/caching.layer.listen; - server_name _; + server_name proxy_caching_; # Do some tweaked logging. access_log /var/log/nginx/access.log tweaked;