如何配置Docker端口映射以使用Nginx作为上游代理?
更新II 现在是2015年7月16日,事情又发生了变化。我从Jason Wilder那里发现了这个自动容器:它在docker运行容器所需的时间内解决了这个问题。这就是我现在用来解决这个问题的解决方案 更新如何配置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
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"