我是一个收听8080端口的服务。这个不是容器。
然后,我使用官方图片创建了一个nginx容器:
docker run --name nginx -d -v /root/nginx/conf:/etc/nginx/conf.d -p 443:443 -p 80:80 nginx
毕竟:
# netstat -tupln | grep 443
tcp6 0 0 :::443 :::* LISTEN 3482/docker-proxy
# netstat -tupln | grep 80
tcp6 0 0 :::80 :::* LISTEN 3489/docker-proxy
tcp6 0 0 :::8080 :::* LISTEN 1009/java
Nginx配置是:
upstream eighty {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name eighty.domain.com;
location / {
proxy_pass http://eighty;
}
}
我已通过# curl http://127.0.0.1:8080
<html><head><meta http-equiv='refresh'
content='1;url=/login?from=%2F'/><script>window.location.replace('/login?from=%2F');</script></head><body
style='background-color:white; color:white;'>
...
似乎运行良好,但是,当我尝试使用我的浏览器进行访问时,nginx告诉bt 502错误的网关响应。
我发现它可能是与非集装箱化过程和集装箱打开之间的可见性相关的问题。我可以将容器与其他非容器进程打开的端口建立连接吗?
修改
记录upstream { server 127.0.0.1:8080; }
:
2016/07/13 09:06:53 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:8080/", host: "eighty.domain.com"
62.57.217.25 - - [13/Jul/2016:09:06:53 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-"
记录upstream { server 0.0.0.0:8080; }
:
62.57.217.25 - - [13/Jul/2016:09:00:30 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-" 2016/07/13 09:00:30 [error] 5#5: *1 connect() failed (111: Connection refused) while connecting to upstream, client:
62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", host: "eighty.domain.com" 2016/07/13 09:00:32 [error] 5#5: *3 connect() failed (111: Connection refused) while connecting to upstream, client: 62.57.217.25, server: eighty.domain.com, request: "GET / HTTP/1.1", upstream: "http://0.0.0.0:8080/", host: "eighty.domain.com"
62.57.217.25 - - [13/Jul/2016:09:00:32 +0000] "GET / HTTP/1.1" 502 173 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0" "-"
有什么想法吗?
答案 0 :(得分:37)
对于容器来说,Localhost有点棘手。在docker容器中,localhost指向容器本身。 这意味着,像这样的上游:
upstream foo{
server 127.0.0.1:8080;
}
或
upstream foo{
server 0.0.0.0:8080;
}
您告诉nginx将您的请求传递给本地主机。 但是在docker-container的上下文中,localhost(以及相应的ip地址)指向容器本身:
通过解决127.0.0.1,如果您的容器不在主机网络上,您将永远无法访问主机。
您可以选择在与主机相同的网络上运行nginx:
docker run --name nginx -d -v /root/nginx/conf:/etc/nginx/conf.d --net=host nginx
请注意,在这种情况下,您不需要公开任何端口。
虽然您失去了docker网络的好处,但这仍然有效。如果您有多个应通过docker网络进行通信的容器,则此方法可能存在问题。如果您只想使用docker部署nginx并且不想使用任何高级docker网络功能,那么这种方法很好。
另一个方法是重新配置你的nginx上游指令,通过添加远程IP地址直接连接到你的主机:
upstream foo{
//insert your hosts ip here
server 192.168.99.100:8080;
}
容器现在将通过网络堆栈并正确解析您的主机:
如果您有DNS名称,也可以使用它。确保docker知道您的DNS服务器。
答案 1 :(得分:2)
只是为了完成其他答案,我使用 mac 进行开发,直接在上游使用 host.docker.internal 对我有用,无需传递主机远程 IP 地址。这是代理nginx的配置:
events { worker_connections 1024; }
http {
upstream app1 {
server host.docker.internal:81;
}
upstream app1 {
server host.docker.internal:82;
}
server {
listen 80;
server_name app1.com;
location / {
proxy_pass http://app1;
}
}
server {
listen 80;
server_name app2.com;
location / {
proxy_pass http://app2;
}
}
}
如您所见,我在 nginx 代理后面为不同的应用程序使用了不同的端口。我为 app1 使用了端口 81,为 app2 使用了端口 82,并且 app1 和 app2 都有自己的 nginx 容器:
对于 app1:
docker run --name nginx -d -p 81:80 nginx
对于 app2:
docker run --name nginx -d -p 82:80 nginx
另外,请参阅此链接了解更多详情: docker doc for mac
答案 2 :(得分:1)
# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8001; # for a web port socket (we'll use this first)
}
location / {
uwsgi_pass django;
include /path/to/your/mysite/uwsgi_params; # the uwsgi_params file you installed
}
完整参考:https://uwsgi-docs.readthedocs.io/en/latest/tutorials/Django_and_nginx.html
答案 3 :(得分:0)
对我来说,这行代码proxy_set_header Host $http_host;
server {
listen 80;
server_name localhost;
location / {
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;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_redirect off;
proxy_pass http://myserver;
}
答案 4 :(得分:0)
ip=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n 1)
docker run --name nginx --add-host="host:${ip}" -p 80:80 -d nginx
location / {
...
proxy_pass http://host:8080/;
}
对我有用
答案 5 :(得分:0)
您可以做的是将proxy_pass
配置为从container
角度来看,地址将指向您的真实主机。
要从容器的角度获取host
地址,可以在Windows上使用docker 18.03
(或更新版本)执行以下操作:
从映像名称为nginx
的主机上对容器运行bash(可在Alpine Linux distribution
上运行):
docker run -it nginx /bin/ash
然后在容器中运行
/ # nslookup host.docker.internal
Name: host.docker.internal
Address 1: 192.168.65.2
192.168.65.2
是主机的IP,而不是spinus
接受答案中的网桥IP。
我正在这里host.docker.internal:
主机的IP地址正在更改(如果没有网络访问权限,则没有IP地址)。从18.03开始,我们的建议是连接到特殊的DNS名称host.docker.internal,它将解析为主机使用的内部IP地址。这是出于开发目的,不适用于Docker for Windows以外的生产环境。
然后,您可以将nginx
的配置更改为:
proxy_pass http://192.168.65.2:{your_app_port};
,它应该可以正常工作。
请记住提供与您的本地应用程序运行时相同的port
。
答案 6 :(得分:0)
我遇到了这个问题,由于权限问题,事实证明这是docker容器无法启动的问题。
就我而言
docker-compose ps
显示容器尚未启动并以状态1退出。事实证明,迁移到新计算机时权限丢失。调整对父目录的已知员工用户的权限后,这个问题为我解决了,然后我可以像以前一样在
上启动docker服务。nginx_1_c18a7f6f7d6d | chown: /var/www/html: Operation not permitted