现在完全陷入困境。
这就是我所拥有的。我在 nginx 的 8080 端口上构建并运行了一个简单的 HTML 页面(当我弄清楚了这一点后,我最终想运行一个 Java tomcat 应用程序)。
这是在 Windows 10 上使用 Docker 17.09 和 nginx 1.13 的情况
这是配置:
$ cat Dockerfile
FROM nginx
COPY nginx.conf /etc/nginx
COPY static-html /usr/share/nginx/html
EXPOSE 80
和配置:
$ cat nginx.conf
user nginx;
worker_processes 1;
error_log /dev/stdout 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 /dev/stdout main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
像这样运行:
$ docker run -p 8080:80 --name dummy --rm dummy-nginx
很好地回应curl
:
$ curl -i http://localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.13.7
Date: Thu, 30 Nov 2017 16:46:17 GMT
Content-Type: text/html
Content-Length: 101
Last-Modified: Wed, 29 Nov 2017 16:24:39 GMT
Connection: keep-alive
ETag: "5a1edf47-65"
Accept-Ranges: bytes
<head>
<title>oh yeah</title>
</head>
<body>
<h1>Absolutely</h1>
<p>did this work?</p>
</body>
这样一切就都正常了。对于失败的部分,反向代理也是同样的内容:
反向代理 Dockerfile
FROM nginx
COPY nginx.conf /etc/nginx/nginx.conf
COPY apt-proxy.conf /etc/apt/apt.conf.d
COPY nginx_signing.key /etc/apt
RUN apt-get update
RUN apt-get -y install apt-utils
RUN apt-get -y install gnupg gnupg2 gnupg1
RUN apt-key add /etc/apt/nginx_signing.key
RUN apt-get -y install curl
RUN apt-get -y install net-tools
EXPOSE 10040
CMD ["nginx"]
(我把这些额外的工具放在那里试图帮助诊断这个问题)
反向代理 nginx.conf
daemon off;
user nginx;
worker_processes 1;
pid /var/run/nginx.pid;
error_log /dev/stdout debug;
events { worker_connections 1024; }
http {
access_log /dev/stdout;
upstream myapp {
server localhost:8080;
}
server {
listen 10040;
location / {
proxy_pass $scheme://myapp;
proxy_redirect default;
proxy_set_header HOST $host;
proxy_set_header Referer $http_referer;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}
我强烈怀疑整个问题只是某个地方的一个小错误(撞墙)。
命令行启动反向代理
这包括一些来自 nginx 的错误日志,以及我也传输到 /dev/stdout 的 access_log 项。
$ docker run -p 10040:10040 --name rproxy --rm we1p202420008.cloud.registry(example).com:11095/rproxy
2017/11/30 16:55:20 [notice] 1#1: using the "epoll" event method
2017/11/30 16:55:20 [notice] 1#1: nginx/1.13.7
2017/11/30 16:55:20 [notice] 1#1: built by gcc 6.3.0 20170516 (Debian 6.3.0-18)
2017/11/30 16:55:20 [notice] 1#1: OS: Linux 4.9.49-moby
2017/11/30 16:55:20 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2017/11/30 16:55:20 [notice] 1#1: start worker processes
2017/11/30 16:55:20 [notice] 1#1: start worker process 5
2017/11/30 16:55:25 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.17.0.1, server: , request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", host: "localhost:10040"
172.17.0.1 - - [30/Nov/2017:16:55:25 +0000] "GET / HTTP/1.1" 502 173 "-" "curl/7.56.1"
2017/11/30 16:55:25 [info] 5#5: *1 client 172.17.0.1 closed keepalive connection
当我尝试通过 r-proxy 访问虚拟网站时,会记录该错误,如下所示:
$ curl -i http://localhost:10040
HTTP/1.1 502 Bad Gateway
Server: nginx/1.13.7
Date: Thu, 30 Nov 2017 18:05:06 GMT
Content-Type: text/html
Content-Length: 173
Connection: keep-alive
<html>
<head><title>502 Bad Gateway</title></head>
<body bgcolor="white">
<center><h1>502 Bad Gateway</h1></center>
<hr><center>nginx/1.13.7</center>
</body>
</html>
现在,如果我刚刚发布的配置中没有明显的问题,而且这真的不仅仅是我的愚蠢,那么就有一些令人困惑的东西,我无法进一步解决。例如,当我curl
在反向代理实例中运行时:
docker exec rproxy curl -i http://localhost:8080
它给了我公司防火墙阻止内容的结果:
网站http://本地主机/您尝试访问的当前分类为未分类的 URL< 并且被认为可能不安全或不适合浏览。
答案1
使用bridge
作为神奇的关键词,我终于开始获得我需要的搜索引擎结果。
问题中的评论指出了这个问题:nginx 只是将请求转发到localhost:8080
它自己的容器内部,而不是host:ports
其他 docker 容器所在的位置。
我检查了一下,很多人都把他们的代理服务器的 FQDN 写入他们的nginx.conf
,但我不想这样做,因为我认为当构建填充每个环境的配置文件时可能会变得过于复杂。
因此从从docker容器内访问主机和Docker 文档我了解了docker network
今天的情况并实施了以下步骤,为我的开发环境提供一个唯一且不变的主机 IP。
在我的nginx.conf
反向代理中,我有为proxy_pass http://myapp:8080
代理myapp
应用程序提供的 docker 容器名称。
然后我创建用户定义的桥接网络:
docker network create -d bridge myapp-net
我还不明白为什么默认的 docker bridge 网络不起作用。
然后我启动容器,并将它们附加到myapp-net
:
docker run -p 8080:8080 --network=myapp-net --name myapp --rm myregistry:11095/myapp
docker run -p 10040:443 --network=myapp-net --name rproxy --rm myregistry:11095/myapp-rproxy
并且它有效。
我正在我的 Windows 工作站上工作,我发现将真正的外部主机 FQDN 写入其中nginx.conf
需要为每个工作站定义一个新的环境,但是myapp
在 conf 文件中,它消除了对主机名或 IP 的依赖。