Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -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"]
35 changes: 28 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -79,21 +79,34 @@ 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.
- 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.
- 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
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
Expand All @@ -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)
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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!
Expand Down
30 changes: 28 additions & 2 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 "---"

Expand Down Expand Up @@ -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 <<EOD >>/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
Expand All @@ -217,7 +244,6 @@ else
echo "Upstream SSL certificate verification is DISABLED."
fi


echo "Testing nginx config..."
${NGINX_BIN} -t

Expand Down
8 changes: 5 additions & 3 deletions nginx.conf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down