It’s now July 16th, 2015 and things have changed again. I’ve
discovered this automagical container from 07000:
07001 and it solves
this problem in about as long as it takes to docker run the
container. This is now the solution I’m using to solve this problem.


It’s now July of 2015 and things have change drastically with regards
to networking Docker containers. There are now many different
offerings that solve this problem (in a variety of ways).

You should use this post to gain a basic understanding of the 07002 approach to service discovery, which is about as basic as it gets, works very well, and actually requires less fancy-dancing than most of the other solutions. It is limited in that it’s quite difficult to network containers on separate hosts in any given cluster, and containers cannot be restarted once networked, but does offer a quick and relatively easy way to network containers on the same host. It’s a good way to get an idea of what the software you’ll likely be using to solve this problem is actually doing under the hood.

Additionally, you’ll probably want to also check out Docker’s nascent 07003, Hashicorp’s 07004, Weaveworks 07005, Jeff Lindsay’s 07006, and Google’s 07007.

There’s also the 07008 offerings that utilize 07009, 070010, and 070011.

And if you really want to have a party you can spin up a cluster to run 070012, or 070013, or 070014.

If you’re new to networking (like me) then you should get out your reading glasses, pop 070015 on the Wi-Hi-Fi, and crack a beer — it’s going to be a while before you really understand exactly what it is you’re trying to do. Hint: You’re trying to implement a Service Discovery Layer in your Cluster Control Plane. It’s a very nice way to spend a Saturday night.

It’s a lot of fun, but I wish I’d taken the time to educate myself better about networking in general before diving right in. I eventually found a couple posts from the benevolent Digital Ocean Tutorial gods: 070016 and 070017. I suggest reading those a few times first before diving in.

Have fun!




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"]


upstream api_upstream{



server {

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


server {

    listen 443;
    server_name api.mypp.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;





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



@T0xicCode’s answer是正确的,但我想我会扩大细节,因为它实际上需要我大约20个小时,终于得到一个工作的解决方案实施。




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


这样做的结果是更改为env vars和驻留在API和App容器中的/ etc / hosts文件。结果如下:

/ etc / hosts

在你的Nginx容器中运行cat / etc / hosts会产生以下结果:  0fd9a40ab5ec   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters  App  API







sudo docker exec -i -t Nginx bash

您可以看到现在具有/ etc / hosts文件条目和env vars,其中包含已链接的任何容器的本地IP地址。就我所知,这是所有发生当你运行容器链接选项声明。但是你现在可以使用这些信息在你的Nginx容器中配置nginx。


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

选项A:使用ENV Vars配置Nginx

This is the option that I went with because I couldn’t get the
/etc/hosts file option to work. I’ll be trying Option B soon enough
and update this post with any findings.

此选项和使用/ etc / hosts文件选项之间的关键区别是如何编写Dockerfile以使用shell脚本作为CMD参数,而后者将处理字符串替换以将IP值从ENV复制到您的conf文件s)。



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"]


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;


NOTE: It’s important to include daemon off; in your nginx.conf file to ensure that your container doesn’t exit immediately after launching.


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;



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



Find and replace text within a file using commands

On OSX, sed handles options differently, the -i flag specifically.
On Ubuntu, the -i flag will handle the replacement ‘in place’; it
will open the file, change the text, and then ‘save over’ the same
On OSX, the -i flag requires the file extension you’d like the resulting file to have. If you’re working with a file that has no extension you must input ” as the value for the -i flag.

To use ENV vars within the regex that sed uses to find the string you want to replace you need to wrap the var within double-quotes. So the correct, albeit wonky-looking, syntax is as above.

所以docker启动了我们的容器并触发了Nginx-Startup.sh脚本运行,它使用sed将值APP_IP更改为我们在sed命令中提供的相应的ENV变量。我们现在在/ etc / nginx / sites-enabled目录中有conf文件,它们在启动容器时具有来自ENV变量的IP地址。在您的api.myapp.conf文件中,您将看到上游块已更改为:

upstream api_upstream{



You cannot restart/rerun any containers once you’ve run the initial instance launch. Docker provides each container with a new IP upon launch and does not seem to re-use any that its used before. So api.myapp.com will get the first time, but then get the next time. But Nginx will have already set the first IP into its conf files, or in its /etc/hosts file, so it won’t be able to determine the new IP for api.myapp.com. The solution to this is likely to use CoreOS and its etcd service which, in my limited understanding, acts like a shared ENV for all machines registered into the same CoreOS cluster. This is the next toy I’m going to play with setting up.

选项B:使用/ etc / hosts文件条目

这应该是更快,更容易的方式这样做,但我不能让它工作。表面上,你只需将/ etc / hosts条目的值输入到api.myapp.conf和app.myapp.conf文件中,但是我无法使此方法起作用。

See 07002 for instructions on how to make this method work.


upstream api_upstream{
    server API:3000;

考虑到我的/ etc / hosts文件中有一个条目,如: API我认为它只是拉入的值,但似乎不是。


转载注明原文:如何配置Docker端口映射以使用Nginx作为上游代理? - 代码日志