简体   繁体   English

Nginx Docker容器代理传递到另一个端口

[英]Nginx docker container proxy pass to another port

I want to run Nginx in a docker container, it listens to port 80 and I want it to proxy_pass to port 8080 when the url starts with word api , and I have some web app listening port 8080. This has been working for me without docker, but with docker, I couldn't get it to work. 我想在docker容器中运行Nginx,它侦听端口80,并且当URL以word api开头时,我希望它通过proxy_pass到端口8080,并且我有一些Web应用程序侦听端口8080。这在没有docker的情况下一直为我工作,但是使用docker,我无法使其正常工作。

My nginx.conf is like: 我的nginx.conf是这样的:

    location /{
        # serve static page
    }
    location /api {
        proxy_pass http://0.0.0.0:8080;
    }

I run my nginx container with docker run -d -p 80:80 -p 8080: 8080 nginx 我用docker run -d -p 80:80 -p 8080: 8080 nginx运行我的nginx容器

My problem is now I can no longer run my web app because it can't listen to port 8080 since that container is already listening to it. 我的问题是,我现在不能再运行我的Web应用程序,因为它无法监听端口8080,因为该容器已经在监听它。

docker run -d --net host nginx

Try it! 试试吧! Nginx container will share the host network with IP and all ports Nginx容器将与IP和所有端口共享主机网络

You can (or rather should) only have one process per docker container which means you will have nginx running in one container and your application on another. 每个Docker容器只能(或者应该)只有一个进程,这意味着您将使nginx在一个容器中运行,而您的应用程序在另一个容器中。 The old way is to create links between containers like this: 老方法是在容器之间创建链接,如下所示:

$ docker run --name my-app -d myself/myapp
$ docker run --name proxy --link my-app:my-app -d nginx

This will add a line in /etc/hosts in the nginx container so it will be able to call the other container by it's name. 这将在nginx容器中的/etc/hosts中添加一行,这样便可以使用其名称调用另一个容器。

And then in nginx.conf file: 然后在nginx.conf文件中:

location /api {
    proxy_pass http://my-app:8080;
}

However according to official Docker docs this method is deprecated and you should only use it's "absolutely needed". 但是,根据Docker官方文档,此方法已弃用,您仅应使用“绝对需要”的方法。 Instead you should use the docker networking . 相反,您应该使用docker网络 Theoretically if both containers are in the same network and the local DNS server is working (embedded in docker) they should be able to see each other without the --link parameter. 从理论上讲,如果两个容器都在同一个网络中并且本地DNS服务器正在工作(嵌入docker),则它们应该能够在没有--link参数的情况下看到彼此。 Unfortunately it didn't work for me for some reason. 不幸的是,由于某种原因,它对我不起作用。 Nginx didn't have the correct DNS configured in /etc/resolv.conf, but read the article and play around it, I'm sure it will work. Nginx在/etc/resolv.conf中没有配置正确的DNS,但是请阅读本文并进行尝试,我敢肯定它会起作用。

First, you need to create a network to place both containers: 首先,您需要创建一个网络来放置两个容器:

docker network create nginx_network

Then, you should specify Docker's DNS server in nginx configuration: 然后,您应该在nginx配置中指定Docker的DNS服务器:

location /api {
    #Docker DNS
    resolver 127.0.0.11;

    #my_api - name of container with your API, see below
    proxy_pass http://my_api:8080;
}

Finally, run your containers: 最后,运行容器:

docker run --network="nginx_network" -d --name my_api your_api_container
docker run --network="nginx_network" -d -p 80:80 nginx

Note: 注意:

  1. --name parameter's value for API's container must match domain name in Nginx config API容器的--name参数值必须与Nginx配置中的域名匹配
  2. it's enough to specify only 80 port for your nginx container 仅为您的nginx容器指定80端口就足够了
  3. first run your API's container and then Nginx's container (see below) 首先运行API的容器,然后运行Nginx的容器(见下文)
  4. both containers must be in the same network 两个容器必须在同一网络中

This should work. 这应该工作。

In case if you run nginx container first, then nginx will try to resolve domain name my_api on startup and fail, because container with this name doesn't exist yet. 如果您首先运行nginx容器,则nginx将尝试在启动时解析域名my_api并失败,因为具有该名称的容器尚不存在。 In this case there is a following workaround (not sure if it is good solution). 在这种情况下,有以下解决方法(不确定是否是好的解决方案)。 Modify nginx config: 修改nginx配置:

location /api {
    #Docker DNS
    resolver 127.0.0.11;

    #hack to prevent nginx to resolve domain on start up
    set $docker_host "my_api";

    #my_api - name of container with your API, see below
    proxy_pass http://$docker_host:8080;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM