如何配置Docker端口映射以使用Nginx作为上游代理?

如何配置Docker端口映射以使用Nginx作为上游代理?,nginx,docker,Nginx,Docker,更新II 现在是2015年7月16日,事情又发生了变化。我从Jason Wilder那里发现了这个自动容器:它在docker运行容器所需的时间内解决了这个问题。这就是我现在用来解决这个问题的解决方案 更新 FROM ubuntu:14.04 MAINTAINER Your Name <you@myapp.com> RUN apt-get update && apt-get install -y nano htop git nginx ADD nginx.conf

更新II

现在是2015年7月16日,事情又发生了变化。我从Jason Wilder那里发现了这个自动容器:它在docker运行容器所需的时间内解决了这个问题。这就是我现在用来解决这个问题的解决方案

更新

FROM ubuntu:14.04
MAINTAINER Your Name <you@myapp.com>

RUN apt-get update && apt-get install -y nano htop git nginx

ADD nginx.conf /etc/nginx/nginx.conf
ADD api.myapp.conf /etc/nginx/sites-enabled/api.myapp.conf
ADD app.myapp.conf /etc/nginx/sites-enabled/app.myapp.conf
ADD Nginx-Startup.sh /etc/nginx/Nginx-Startup.sh

EXPOSE 80 443

CMD ["/bin/bash","/etc/nginx/Nginx-Startup.sh"]
现在是2015年7月,关于网络化Docker容器,情况发生了巨大变化。现在有许多不同的产品可以解决这个问题(以各种方式)

您应该通过这篇文章对docker-link服务发现方法有一个基本的了解,该方法非常基本,工作非常好,实际上比大多数其他解决方案需要更少的花哨舞蹈。它的局限性在于很难在任何给定集群中的不同主机上连接容器,并且容器一旦连接就不能重新启动,但它确实提供了一种在同一主机上连接容器的快速且相对简单的方法。这是一个很好的方法,可以让你了解你可能用来解决这个问题的软件实际上是在做什么

此外,你可能还想看看Docker的新生网络,Hashicorp的Consour,Weaveworks weave,Jeff Lindsay的progrium/Consour&gliderlabs/registrator和Google的Kubernetes

还有利用etcd、fleet和法兰绒的CoreOS产品

如果你真的想开派对,你可以旋转一个星系团来运行中间层,或者Deis,或者Flynn

如果你是网络新手(和我一样),那么你应该拿出你的阅读眼镜,在Wi-Hi-Fi上弹出“用星星画天空——恩雅的最棒”,然后喝杯啤酒——你还需要一段时间才能真正理解你到底想做什么。提示:您正试图在集群控制平面中实现服务发现层。这是度过周六晚上的好方法

这很有趣,但我希望在投入工作之前,我能花点时间更好地了解人际网络。我最终从仁慈的数字海洋教程《众神:网络术语和理解导论》中找到了几篇帖子。。。网络。我建议在开始之前先读几遍

玩得开心

原创帖子

我似乎无法掌握
Docker
容器的端口映射。特别是如何将请求从Nginx传递到同一服务器上的另一个容器,侦听另一个端口

我有一个针对Nginx容器的Dockerfile,如下所示:

FROM ubuntu:14.04
MAINTAINER Me <me@myapp.com>

RUN apt-get update && apt-get install -y htop git nginx

ADD sites-enabled/api.myapp.com /etc/nginx/sites-enabled/api.myapp.com
ADD sites-enabled/app.myapp.com /etc/nginx/sites-enabled/app.myapp.com
ADD nginx.conf /etc/nginx/nginx.conf

RUN echo "daemon off;" >> /etc/nginx/nginx.conf

EXPOSE 80 443

CMD ["service", "nginx", "start"]
还有一个是app.myapp.com

然后我跑:

sudo docker run -p 80:80 -p 443:443 -d --name Nginx myusername/nginx

这一切都很好,但请求没有传递到其他容器/端口。当我ssh到Nginx容器并检查日志时,我没有看到任何错误。 有什么帮助吗?

使用,您可以将上游容器链接到nginx容器。另外一个功能是docker管理主机文件,这意味着您可以使用名称而不是潜在的随机ip来引用链接的容器。

是正确的,但我想我会详细介绍一下,因为实际上我花了大约20个小时才最终实现一个工作解决方案

如果您希望在自己的容器中运行Nginx,并将其用作反向代理,以便在同一服务器实例上平衡多个应用程序的负载,则需要执行以下步骤:

链接您的容器

当您
docker运行
您的容器时,通常通过将shell脚本输入到
用户数据
,您可以声明指向任何其他运行容器的链接。这意味着您需要按顺序启动容器,并且只有后一个容器可以链接到前一个容器。像这样:

#!/bin/bash
sudo docker run -p 3000:3000 --name API mydockerhub/api
sudo docker run -p 3001:3001 --link API:API --name App mydockerhub/app
sudo docker run -p 80:80 -p 443:443 --link API:API --link App:App --name Nginx mydockerhub/nginx
因此,在本例中,
API
容器没有链接到任何其他容器,而是
App
容器链接到
API
Nginx
链接到
API
App

这将导致
env
vars和
/etc/hosts
文件发生更改,这些文件位于
API
App
容器中。结果如下:

/etc/hosts

Nginx
容器中运行
cat/etc/hosts
将产生以下结果:

172.17.0.5  0fd9a40ab5ec
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3  App
172.17.0.2  API


环境变量

Nginx
容器中运行
env
将产生以下结果:

API_PORT=tcp://172.17.0.2:3000
API_PORT_3000_TCP_PROTO=tcp
API_PORT_3000_TCP_PORT=3000
API_PORT_3000_TCP_ADDR=172.17.0.2

APP_PORT=tcp://172.17.0.3:3001
APP_PORT_3001_TCP_PROTO=tcp
APP_PORT_3001_TCP_PORT=3001
APP_PORT_3001_TCP_ADDR=172.17.0.3
我已经截断了许多实际的变量,但上面是将流量代理到容器所需的关键值

要获取shell以在正在运行的容器中运行上述命令,请使用以下命令:

172.17.0.5  0fd9a40ab5ec
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3  App
172.17.0.2  API
sudo docker exec-i-t Nginx bash

您可以看到,您现在既有
/etc/hosts
文件条目,也有
env
变量,它们包含链接的任何容器的本地IP地址。据我所知,当您运行声明了链接选项的容器时,就会发生这种情况。但是您现在可以使用此信息在
nginx
容器中配置
nginx



配置Nginx

这就是它变得有点棘手的地方,有几个选择。您可以选择将站点配置为指向
/etc/hosts
文件中创建的
docker
项,或者可以使用
ENV
vars并运行字符串替换(我使用了
sed
)在您的
nginx.conf
/etc/nginx/sites中的任何其他conf文件上,启用了
文件夹以插入IP值



选项A:使用环境变量配置Nginx

这是我的选择,因为我无法获得 daemon off; user www-data; pid /var/run/nginx.pid; worker_processes 1; events { worker_connections 1024; } http { # Basic Settings sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 33; types_hash_max_size 2048; server_tokens off; server_names_hash_bucket_size 64; include /etc/nginx/mime.types; default_type application/octet-stream; # Logging Settings access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; # Gzip Settings gzip on; gzip_vary on; gzip_proxied any; gzip_comp_level 3; gzip_buffers 16 8k; gzip_http_version 1.1; gzip_types text/plain text/xml text/css application/x-javascript application/json; gzip_disable "MSIE [1-6]\.(?!.*SV1)"; # Virtual Host Configs include /etc/nginx/sites-enabled/*; # Error Page Config #error_page 403 404 500 502 /srv/Splash; }
upstream api_upstream{
    server APP_IP:3000;
}

server {
    listen 80;
    server_name api.myapp.com;
    return 301 https://api.myapp.com/$request_uri;
}

server {
    listen 443;
    server_name api.myapp.com;

    location / {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        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_cache_bypass $http_upgrade;
        proxy_pass http://api_upstream;
    }

}
#!/bin/bash
sed -i 's/APP_IP/'"$API_PORT_3000_TCP_ADDR"'/g' /etc/nginx/sites-enabled/api.myapp.com
sed -i 's/APP_IP/'"$APP_PORT_3001_TCP_ADDR"'/g' /etc/nginx/sites-enabled/app.myapp.com

service nginx start
upstream api_upstream{
    server 172.0.0.2:3000;
}
upstream api_upstream{
    server API:3000;
}
FROM ubuntu
RUN apt-get update && apt-get install -y nginx
RUN ln -sf /dev/stdout /var/log/nginx/access.log
RUN ln -sf /dev/stderr /var/log/nginx/error.log
RUN rm -rf /etc/nginx/sites-enabled/default
EXPOSE 80 443
COPY conf/mysite.com /etc/nginx/sites-enabled/mysite.com
CMD ["nginx", "-g", "daemon off;"]
server {
    listen 80 default;
    server_name mysite.com;

    location / {
        proxy_pass http://website;
    }
}

upstream website {
    server website:3000;
}
$ docker run -dP --name website website
$ docker run -dP --name nginx --link website:website nginx
docker network create web
FROM nginx
COPY default.conf /etc/nginx/conf.d/default.conf
server {
    listen       80;
    server_name  localhost;

    location / {
        root   /var/www/html;
        index  index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }
}
version: "2"

networks:
  mynetwork:
    external:
      name: web

services:
  nginx:
    container_name: sample-site
    build: .
    expose:
      - "80"
    volumes:
      - "./content/:/var/www/html/"
    networks:
      default: {}
      mynetwork:
        aliases:
          - sample-site
docker-compose up -d
docker exec -it sample-site bash
ping sample-site
FROM nginx

RUN rm /etc/nginx/conf.d/*
version: "2"

networks:
  mynetwork:
    external:
      name: web


services:
  nginx:
    container_name: nginx-proxy
    build: .
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./conf.d/:/etc/nginx/conf.d/:ro
      - ./sites/:/var/www/
    networks:
      default: {}
      mynetwork:
        aliases:
          - nginx-proxy
docker-compose up -d
docker exec -it nginx-proxy bash
ping sample-site
ping nginx-proxy
  server {
    listen 80;
    listen [::]:80;

    server_name my.domain.com;

    location / {
      proxy_pass http://sample-site;
    }

  }
docker exec nginx-proxy service nginx reload
server {
    listen 80;

    location / {
        proxy_pass http://client:8080; # this one here
        proxy_redirect off;
    }

}
version: "2"
services:
  entrypoint:
    image: some-image-with-nginx
    ports:
      - "80:80"
    links:
      - client  # will use this one here

  client:
    image: some-image-with-api
    ports:
      - "8080:8080"