Skip to content

Commit 325dd23

Browse files
author
ricardop
committed
initial commit
1 parent 2287770 commit 325dd23

File tree

4 files changed

+172
-0
lines changed

4 files changed

+172
-0
lines changed

.dockerignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.idea
2+
.git
3+
.gitignore
4+
LICENSE
5+
README.md

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.idea

Dockerfile

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Use stable nginx on alpine for a light container
2+
FROM nginx:stable-alpine
3+
4+
# Add openssl and clean apk cache
5+
RUN apk add --update openssl && rm -rf /var/cache/apk/*
6+
7+
# Generate a self-signed SSL certificate. It will be ignored by Docker clients due to insecure-registries.
8+
RUN mkdir -p /etc/ssl && \
9+
cd /etc/ssl && \
10+
openssl genrsa -des3 -passout pass:x -out key.pem 2048 && \
11+
cp key.pem key.pem.orig && \
12+
openssl rsa -passin pass:x -in key.pem.orig -out key.pem && \
13+
openssl req -new -key key.pem -out cert.csr -subj "/C=BR/ST=BR/L=Nowhere/O=Fake Docker Mirror/OU=Docker/CN=docker.proxy" && \
14+
openssl x509 -req -days 3650 -in cert.csr -signkey key.pem -out cert.pem
15+
16+
# Create the cache directory
17+
RUN mkdir -p /docker_mirror_cache
18+
19+
# Expose it as a volume, so cache can be kept external to the Docker image
20+
VOLUME /docker_mirror_cache
21+
22+
# Add our configuration
23+
ADD nginx.conf /etc/nginx/nginx.conf
24+
25+
# Test that the configuration is OK
26+
RUN nginx -t

nginx.conf

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
user nginx;
2+
worker_processes auto;
3+
4+
error_log /var/log/nginx/error.log debug;
5+
pid /var/run/nginx.pid;
6+
7+
events {
8+
worker_connections 1024;
9+
}
10+
11+
http {
12+
include /etc/nginx/mime.types;
13+
default_type application/octet-stream;
14+
15+
# Use a debug-oriented logging format.
16+
log_format tweaked '$remote_addr - $remote_user [$time_local] "$request" '
17+
'$status $body_bytes_sent '
18+
'"HOST: $host" "UPSTREAM: $upstream_addr" '
19+
'"UPSTREAM-STATUS: $upstream_status" '
20+
'"SSL-PROTO: $ssl_protocol" '
21+
'"PROXY-HOST: $proxy_host" "UPSTREAM-REDIRECT: $upstream_http_location" "CACHE-STATUS: $upstream_cache_status"';
22+
23+
access_log /var/log/nginx/access.log tweaked;
24+
keepalive_timeout 300;
25+
gzip off;
26+
27+
# The cache directory. This can get huge. Better to use a Docker volume pointing here!
28+
# Set to 32gb which should be enough
29+
proxy_cache_path /docker_mirror_cache levels=1:2 max_size=32g inactive=60d keys_zone=cache:10m use_temp_path=off;
30+
31+
32+
# Just in case you want to rewrite some hosts. Default maps directly.
33+
map $host $targetHost {
34+
hostnames;
35+
default $host;
36+
}
37+
38+
# These maps parse the original Host and URI from a /forcecache redirect.
39+
map $request_uri $realHost {
40+
~/forcecacheinsecure/([^:/]+)/originalwas(/.+) $1;
41+
~/forcecachesecure/([^:/]+)/originalwas(/.+) $1;
42+
default "DID_NOT_MATCH_HOST";
43+
}
44+
45+
map $request_uri $realPath {
46+
~/forcecacheinsecure/([^:/]+)/originalwas(/.+) $2;
47+
~/forcecachesecure/([^:/]+)/originalwas(/.+) $2;
48+
default "DID_NOT_MATCH_PATH";
49+
}
50+
51+
server {
52+
# Listen on both 80 and 443, for all hostnames.
53+
listen 80 default_server;
54+
listen 443 ssl default_server;
55+
server_name _;
56+
57+
# Use a fake SSL certificate. This does not matter, since the Docker clients will be configured with insecure registry
58+
ssl_certificate /etc/ssl/cert.pem;
59+
ssl_certificate_key /etc/ssl/key.pem;
60+
61+
# We need to resolve the real names of our proxied servers.
62+
resolver 8.8.8.8 4.2.2.2 ipv6=off; # Avoid ipv6 addresses for now
63+
64+
# Docker needs this. Don't ask.
65+
chunked_transfer_encoding on;
66+
67+
# Block POST/PUT/DELETE. Don't use this proxy for pushing.
68+
if ($request_method = POST) {
69+
return 405;
70+
}
71+
if ($request_method = PUT) {
72+
return 405;
73+
}
74+
if ($request_method = DELETE) {
75+
return 405;
76+
}
77+
78+
proxy_read_timeout 900;
79+
80+
# Use cache locking, with a huge timeout, so that multiple Docker clients asking for the same blob at the same time
81+
# will wait for the first to finish instead of doing multiple upstream requests.
82+
proxy_cache_lock on;
83+
proxy_cache_lock_timeout 120s;
84+
proxy_cache_valid 200 301 302 60d; # Cache all 200, 301, and 302 for 60 days.
85+
proxy_force_ranges on;
86+
proxy_ignore_client_abort on;
87+
proxy_cache_revalidate on;
88+
89+
# don't cache mutable entity /v2/<name>/manifests/<reference> (unless the reference is a digest)
90+
location ~ ^/v2/[^\/]+/manifests/(?![A-Fa-f0-9_+.-]+:) {
91+
proxy_pass https://$targetHost;
92+
add_header X-Eh-Aqui $targetHost;
93+
}
94+
95+
# don't cache mutable entity /v2/<name>/tags/list
96+
location ~ ^/v2/[^\/]+/tags/list {
97+
proxy_pass https://$targetHost;
98+
}
99+
100+
# don't cache mutable entity /v2/_catalog
101+
location ~ ^/v2/_catalog$ {
102+
proxy_pass https://$targetHost;
103+
}
104+
105+
# cache everything else
106+
location / {
107+
proxy_pass https://$targetHost;
108+
proxy_cache cache;
109+
110+
# Handling of redirects.
111+
# Many registries (eg, quay.io, or k8s.gcr.io) emit a Location redirect
112+
# pointing to something like cloudfront, or google storage.
113+
# We hack into the response, extracting the host and URI parts, injecting them into a URL that points back to us
114+
# That gives us a chance to intercept and cache those, which are the actual multi-megabyte blobs we originally wanted to cache.
115+
# We to it twice, one for http and another for https.
116+
proxy_redirect ~^https://([^:/]+)(/.+)$ https://docker.proxy/forcecachesecure/$1/originalwas$2;
117+
proxy_redirect ~^http://([^:/]+)(/.+)$ http://docker.proxy/forcecacheinsecure/$1/originalwas$2;
118+
}
119+
120+
# handling for the redirect case explained above, with https.
121+
# The $realHost and $realPath variables come from a map defined at the top of this file.
122+
location /forcecachesecure {
123+
proxy_pass https://$realHost$realPath;
124+
proxy_cache cache;
125+
add_header X-Docker-Caching-Proxy-Real-Proto https;
126+
add_header X-Docker-Caching-Proxy-Real-Host $realHost;
127+
add_header X-Docker-Caching-Proxy-Real-Path $realPath;
128+
}
129+
130+
# handling for the redirect case explained above, with http.
131+
# The $realHost and $realPath variables come from a map defined at the top of this file.
132+
location /forcecacheinsecure {
133+
proxy_pass http://$realHost$realPath;
134+
proxy_cache cache;
135+
add_header X-Docker-Caching-Proxy-Real-Proto http;
136+
add_header X-Docker-Caching-Proxy-Real-Host $realHost;
137+
add_header X-Docker-Caching-Proxy-Real-Path $realPath;
138+
}
139+
}
140+
}

0 commit comments

Comments
 (0)