【发布时间】:2019-04-08 08:31:58
【问题描述】:
在我的服务器上,我有两个 docker 容器。一个是 docker Registry,另一个是访问第一个容器端点的 Angular 应用程序。
Docker 注册表已映射端口 5000,并通过 Apache 的虚拟主机代理到域 docker.mydomain.com。 Angular 应用程序的端口为 5002,并被代理到 dockerhub.mydomain.com
我为我的 docker 注册表设置了一个虚拟主机文件,如下所示:
<VirtualHost *:80>
ServerName docker.mydomain.com
Redirect permanent / https://docker.mydomain.com/
</VirtualHost>
<VirtualHost *:443>
ServerName mydomain.com
ServerAlias docker.mydomain.com
ServerAdmin admin@mydomain.com
# Headers required for docker registry to work
Header set Host "docker.mydomain.com"
Header always set "Docker-Distribution-Api-Version" "registry/2.0"
Header onsuccess set "Docker-Distribution-Api-Version" "registry/2.0"
RequestHeader set X-forwarded-Proto "https"
# Settings CORS headers
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Headers "X-Requested-With, Content-Type, Origin, Authorization, Accept"
Header always set Vary "Origin, Access-Control-Request-Headers, Access-Control-Request-Method"
# SSL settings
SSLEngine On
SSLCertificateFile "/etc/letsencrypt/live/docker.mydomain.com/cert.pem"
SSLCertificateKeyFile "/etc/letsencrypt/live/docker.mydomain.com/privkey.pem"
SSLCertificateChainFile "/etc/letsencrypt/live/docker.mydomain.com/chain.pem"
# Reply to all OPTIONS requests with 200
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule ^(.*)$ $1 [R=200,L]
ProxyPreserveHost On
ProxyRequests Off
# Proxy request to localhost:5000 and check authentication
<Location "/">
ProxyPass http://localhost:5000/
ProxyPassReverse http://localhost:5000/
Order deny,allow
Allow from all
AuthName "Registry Authentication"
AuthType basic
AuthUserFile "/opt/docker-registry-htpasswd/.registry-htpasswd"
# Allow reading to all users, but pushing images only for certain user
<Limit GET HEAD>
Require valid-user
</Limit>
<Limit POST PUT DELETE PATCH>
Require user myuser
</Limit>
</Location>
ErrorLog ${APACHE_LOG_DIR}/docker-registry-error.log
LogLevel warn
</VirtualHost>
我在另一个 docker 中的 Angular 应用程序使用 nginx 映像提供以下配置:
worker_processes 1;
events {
worker_connections 1024;
}
http {
server {
listen 4200;
server_name localhost;
root /usr/share/nginx/html;
index index.html index.htm;
include /etc/nginx/mime.types;
gzip on;
gzip_min_length 1000;
gzip_proxied expired no-cache no-store private auth;
gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
location / {
try_files $uri $uri/ /index.html;
}
}
}
现在,当我在 dockerhub.mydomain.com 打开我的 Angular 应用程序并尝试从 docker.mydomain.com 调用 API 时,我收到与 CORS 标头相关的错误:
Access to XMLHttpRequest at 'https://docker.mydomain.com/v2' from
origin 'https://dockerhub.mydomain.com' has been blocked by CORS policy:
The 'Access-Control-Allow-Origin' header has a value 'http://localhost:4200' that is
not equal to the supplied origin.
据我所知,如果 Allow-Origin 标头设置为 *,这意味着它设置为请求的 Origin,它设置为 https://dockerhub.mydomain.com,但 Allow-Origin 设置为 localhost:4200 - 可以这里有问题吗?
此外,Angular 应用程序总是向 docker.mydomain.com 发出请求,而不是向 localhost 地址发出请求。
【问题讨论】:
-
基本上标题不匹配。您必须查看您的请求,并找出谁设置了错误的 URL
http://localhost:4200。另一方面,我建议将您的nginx反向代理到 docker 注册表(如点/api/docker-registry),这样您就根本不用担心 CORS。就像browser -> nginx -> docker registry或browser -> nginx -> apache -> docker registry。然后从 Angular 应用程序,将没有域的 API 请求发送到/api/docker-registry/*。对客户来说也更简单。 -
我的 nginx 只提供 Angular 应用程序,它不会发出任何其他请求等。工作流程是这样的:用户请求 dockerhub -> apache 使用 nginx 重定向到 docker 容器 -> ngingx 提供 Angular 应用程序 -> Angular 应用程序请求 docker.mydomain.com -> apache 使用 docker 注册表重定向到 docker 容器 -> docker 注册表回复。你推荐什么工具来监督请求?
-
根据您的流程,使您的 Angular 应用程序在特定路径上请求您的 nginx,然后将其配置为您的 docker.mydomain.com 的反向代理。即不要让带有 Angular 应用程序的浏览器故意转到另一个域(即 docker.mydomain.com),而只能通过 nginx(服务于 Angular 应用程序)作为反向代理。
-
例如,在
location /旁边添加带有角度应用程序的 nginx:location /api/docker { proxy_pass http://docker.mydomain.com/; }并且让应用程序转到/api/docker而不使用域前缀。网上有很多用nginx设置反向代理的例子。
标签: angular apache docker cors virtualhost