我正在尝试在 ec2实例上部署通用注册表实例(NPM私有注册表 Docker私有注册表)弹性负载平衡器 nginx 作为反向代理。这样做,我希望能够通过HTTPS和Authentication将NPM软件包和Docker图像分别推送到registry.mydomain.org
和docker.mydomain.org
。
要这样做,我遵循以下步骤:
- 我从AWS控制台创建了一个EC2实例
- 我用HTTPS连接到实例的HTTP端口创建了一个新的负载平衡器。
- 我使用此配置创建了一个
docker-compose.yml
文件(我将Verdaccio用作NPM私人注册表和注册表:2作为Docker注册表:
版本:'3' 服务: nginx: 图片:nginx:高山 container_name:nginx 重新启动:总是 端口: - " 80:80" 卷: - ./nginx:/etc/nginx/conf.d/ - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro 链接: -Verdaccio:Verdaccio -Docker:Docker Verdaccio: 图片:Verdaccio/Verdaccio:最新 Container_name:Verdaccio 重新启动:总是 端口: - " 4873:4873" 卷: - ./registry:/verdaccio/conf - ./database/verdaccio:/verdaccio/storage Docker: 图片:注册表:2 container_name:docker 重新启动:总是 端口: - " 5000:5000" 卷: - ./database/docker:/var/lib/registry
- nginx配置( nginx.conf )是:
事件{ Worker_connections 1024; } http { 上游Docker-Registry { 服务器Docker:5000; } 上游npm-registry { 服务器Verdaccio:4873; } ##设置一个变量,以帮助我们决定是否需要添加 ##'Docker-Distribution-api version'标题。 ##注册表始终设置此标头。 ##对于nginx执行AUTH,标题将不设置 ##由于Nginx在代理之前正在授权。 地图$ upstream_http_docker_distribution_api_version $ docker_distribution_api_version { ''注册表/2.0'; } #Healtcheck 服务器 { 听80; 位置/HealthCheck { access_log off; 返回200; } } 服务器 { #服务器选项 听80; Charset UTF-8; client_max_body_size 0; server_name registry.mydomain.org; #代理设置 地点/{ access_log/var/log/nginx/verdaccio.log; proxy_pass http://npm-registry; proxy_set_header主机$主机; proxy_set_header x-forwarded-for $ proxy_add_x_forwarded_for; proxy_set_header x-nginx-proxy true; proxy_ssl_session_reuse off; proxy_redirect off; } } 服务器 { #服务器选项 听80; Charset UTF-8; client_max_body_size 0; #避免http 411的要求:请参阅第1486页(https://github.com/moby/moby/moby/issues/1486) bunked_transfer_encoding on; server_name docker.mydomain.org; # 验证 auth_basic"注册表领域"; auth_basic_user_file/etc/nginx/conf.d/nginx.htpasswd; #代理设置 地点/{ 如果($ http_user_agent〜" 返回404; } ##如果$ docker_distribution_api_version为空,则不会添加标头。 ##请参阅上面的地图指令,其中定义了此变量。 add_header'docker-distribution-api version'$ docker_distribution_api_version始终; access_log/var/log/nginx/docker.log; proxy_pass http://docker-registry; proxy_read_timeout 900; } } }
- 我使用编码身份验证Infos创建了一个
nginx.htpasswd
文件。
现在,注册表非常有效。因此,如果我访问https://registry.mydomain.org
,我可以看到它,并且可以通过npm login --registry=https://registry.mydomain.org --scope=@myscope
关于 docker注册表,虽然我绝对可以使用docker login -u user -p password
登录它,但是当我尝试将图像推向图像时,Docker客户端会进入Infinite Loop并继续尝试上传。图像(没有成功)。在服务器端,Docker注册表的日志没有显示有关正在发生的事情的有用信息,因为所有请求在202 HTTP状态中结束。
关于如何解决它的暗示?
我弄清楚了。我缺少nginx代理配置中的proxy_set_header Host $host;
。
这样做:
server {
# Server options
listen 80;
charset utf-8;
client_max_body_size 0;
# required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486)
chunked_transfer_encoding on;
server_name docker.cubbit.net;
# Authentication
auth_basic "Registry realm";
auth_basic_user_file /etc/nginx/conf.d/nginx.htpasswd;
# Proxy settings
location / {
# Do not allow connections from docker 1.5 and earlier
# docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
if ($http_user_agent ~ "^(docker/1.(3|4|5(?!.[0-9]-dev))|Go ).*$" ) {
return 404;
}
## If $docker_distribution_api_version is empty, the header will not be added.
## See the map directive above where this variable is defined.
add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;
access_log /var/log/nginx/docker.log;
proxy_pass http://docker-registry;
proxy_set_header Host $host;
proxy_read_timeout 900;
}
}
它开始完美工作。希望这可以帮助某人。我花了两天时间。