0%

运行个人 Docker Registry(进阶)

域名解析

主机记录 记录类型 记录值
registry A x.x.x.x
registry-ui A x.x.x.x

安装 Docker Compose

Install Docker Compose

1
yum install -y docker-compose-plugin

配置 Nginx 反向代理

SSL Configuration Generator

Getting Started with NGINX (Part 1): Installation and Basic Setup

Getting Started with NGINX (Part 2): Advanced Configuration

Getting Started with NGINX (Part 3): Enable TLS/SSL for HTTPS

Getting Started with NGINX (Part 4): TLS Deployment Best Practices

目录结构

1
2
3
4
5
6
7
8
9
10
11
12
.
├── certs
│   ├── dhparam2048.pem
│   ├── domain.crt
│   └── domain.key
└── nginx
   ├── conf.d
   │   ├── <domain>.conf
   │   ├── registry.<domain>.conf
   │   └── registry-ui.<domain>.conf
   ├── docker-compose.yml
   └── nginx.conf

nginx.conf

CSP Blocked Loading of Resources

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
user nginx;
# Use Multiple Worker Processes
worker_processes auto;

error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;

events {
worker_connections 1024;
}

http {
include /etc/nginx/mime.types;
default_type application/octet-stream;

log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log main;

sendfile on;

keepalive_timeout 65;

include /etc/nginx/conf.d/*.conf;

ssl_certificate /etc/nginx/certs/domain.crt;
ssl_certificate_key /etc/nginx/certs/domain.key;

# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers on;

ssl_session_timeout 1d;
# about 40000 sessions
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;

# curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam
ssl_dhparam /etc/nginx/certs/dhparam2048.pem;

# HSTS (ngx_http_headers_module is required) (31536000 seconds)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;

# verify chain of trust of OCSP response using Root CA and Intermediate certs
# ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates;

# replace with the IP address of your resolver
resolver 127.0.0.1;

# Disable Content Sniffing
add_header X-Content-Type-Options nosniff;
# Limit or Disable Content Embedding
add_header X-Frame-Options SAMEORIGIN;
# Cross-Site Scripting (XSS) Filter
add_header X-XSS-Protection "1; mode=block";
# Referrer Policy
add_header Referrer-Policy strict-origin-when-cross-origin;
# Content Security Policy
add_header Content-Security-Policy "upgrade-insecure-requests;";

# Disable Server Tokens
server_tokens off;
}

conf.d/<domain>.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
# Serve Content Over IPv4 and IPv6
listen 80 default_server;
listen [::]:80 default_server;
server_name _;

location / {
return 301 https://$host$request_uri;
}
}

server {
# Serve Content Over IPv4 and IPv6
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;

location / {
return 403;
}
}

conf.d/registry.<domain>.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
# Serve Content Over IPv4 and IPv6
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name registry.<domain>;

location / {
proxy_pass https://registry-srv:5000;
proxy_ssl_certificate /etc/nginx/certs/domain.crt;
proxy_ssl_certificate_key /etc/nginx/certs/domain.key;

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

conf.d/registry-ui.<domain>.conf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
server {
# Serve Content Over IPv4 and IPv6
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name registry-ui.<domain>;

location / {
proxy_pass https://registry-web:443;
proxy_ssl_certificate /etc/nginx/certs/domain.crt;
proxy_ssl_certificate_key /etc/nginx/certs/domain.key;

proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}

编辑 docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
version: "3.9"

services:
nginx:
image: nginx:1.20.2
ports:
- 80:80
- 443:443
volumes:
- /root/certs/:/etc/nginx/certs/
- /mnt/nginx-log/:/var/log/nginx/
- ./nginx.conf:/etc/nginx/nginx.conf
- ./conf.d/:/etc/nginx/conf.d/
restart: always
networks:
- registry-network

networks:
registry-network:
external: true

运行 Nginx 反向代理

1
2
3
docker compose up -d
# https://registry.<domain>/v2/busybox/tags/list
# https://registry-ui.<domain>/

更进一步

更新防火墙规则

来源 协议 端口
0.0.0.0/0 TCP 443
0.0.0.0/0 TCP 80

使用 user-defined bridge networks

Use bridge networks

1
docker network create -d bridge registry-network

使用 --expose 替换 -port

expose

Expose ports without publishing them to the host machine - they’ll only be accessible to linked services.

Publish or expose port (-p, --expose)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
docker run -d \
--expose 5000 \
--restart=always \
--name registry-srv \
-v "$(pwd)"/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
-v /root/certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
-v /mnt/registry:/var/lib/registry \
--network=registry-network \
registry:2
1
2
3
4
5
6
7
8
9
10
11
docker run -d \
--name registry-web \
-e ENV_USE_SSL=yes \
-e ENV_DOCKER_REGISTRY_HOST=registry-srv \
-e ENV_DOCKER_REGISTRY_PORT=5000 \
-e ENV_DOCKER_REGISTRY_USE_SSL=1 \
-v /root/certs/domain.crt:/etc/apache2/server.crt:ro \
-v /root/certs/domain.key:/etc/apache2/server.key:ro \
--expose 443 \
--network=registry-network \
konradkleine/docker-registry-frontend:v2

SSL Server Test

https://www.ssllabs.com/ssltest/

A+