登录

在一台主机docker上跑着数个不同的网站容器,如何把80和443端口流量正确的转发给对应容器呢?

求助。。有dalao写过教程的话把文章链接贴出来也行。。百度了一圈已经昏迷。。

# Docker
PHP中文网 PHP中文网 2495 天前 1194 次浏览

全部回复(2) 我要回复

  • 習慣沉默

    習慣沉默2017-06-20 10:07:52

    折腾了一个下午,找到了docker的解决方案
    github:https://github.com/JrCs/docke...

    把重要重点部分摘出来

    Separate Containers (recommended method)

    nginx proxy can also be run as two separate containers using the jwilder/docker-gen
    image and the official nginx image.

    You may want to do this to prevent having the docker socket bound to a publicly exposed container service (avoid to mount the docker socket in the nginx exposed container). It's better in a security point of view.

    To run nginx proxy as a separate container you'll need:

    1) To mount the template file nginx.tmpl into the docker-gen container. You can get the latest official nginx.tmpl with a command like:

    curl https://raw.githubusercontent.com/jwilder/nginx-proxy/master/nginx.tmpl > /path/to/nginx.tmpl

    2) Set the NGINX_DOCKER_GEN_CONTAINER environment variable to the name or id of the docker-gen container.

    Examples:

    • First start nginx (official image) with volumes:

    $ docker run -d -p 80:80 -p 443:443 \
        --name nginx \
        -v /etc/nginx/conf.d  \
        -v /etc/nginx/vhost.d \
        -v /usr/share/nginx/html \
        -v /path/to/certs:/etc/nginx/certs:ro \
        --label com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true \
        nginx
    • Second start the docker-gen container with the shared volumes and the template file:

    $ docker run -d \
        --name nginx-gen \
        --volumes-from nginx \
        -v /path/to/nginx.tmpl:/etc/docker-gen/templates/nginx.tmpl:ro \
        -v /var/run/docker.sock:/tmp/docker.sock:ro \
        jwilder/docker-gen \
        -notify-sighup nginx -watch -wait 5s:30s /etc/docker-gen/templates/nginx.tmpl /etc/nginx/conf.d/default.conf
    • Then start this container (NGINX_DOCKER_GEN_CONTAINER variable must contain the docker-gen container name or id):

    $ docker run -d \
        --name nginx-letsencrypt \
        -e "NGINX_DOCKER_GEN_CONTAINER=nginx-gen" \
        --volumes-from nginx \
        -v /path/to/certs:/etc/nginx/certs:rw \
        -v /var/run/docker.sock:/var/run/docker.sock:ro \
        jrcs/letsencrypt-nginx-proxy-companion

    Then start any containers to be proxied as described previously.

    • If for some reason you can't use the docker --volumes-from option, you can specify the name or id of the nginx container with NGINX_PROXY_CONTAINER variable.

    Let's Encrypt

    To use the Let's Encrypt service to automatically create a valid certificate for virtual host(s).

    Set the following environment variables to enable Let's Encrypt support for a container being proxied. This environment variables need to be declared in each to-be-proxied application containers.

    • LETSENCRYPT_HOST

    • LETSENCRYPT_EMAIL

    The LETSENCRYPT_HOST variable most likely needs to be the same as the VIRTUAL_HOST variable and must be publicly reachable domains. Specify multiple hosts with a comma delimiter.

    The following environment variables are optional and parameterize the way the Let's Encrypt client works.

    • LETSENCRYPT_KEYSIZE

    The LETSENCRYPT_KEYSIZE variable determines the size of the requested key (in bit, defaults to 4096).

    multi-domain (SAN) certificates

    If you want to create multi-domain (SAN) certificates add the base domain as the first domain of the LETSENCRYPT_HOST environment variable.

    test certificates

    If you want to create test certificates that don't have the 5 certs/week/domain limits define the LETSENCRYPT_TEST environment variable with a value of true (in the containers where you request certificates with LETSENCRYPT_HOST). If you want to do this globally for all containers, set ACME_CA_URI as described below.

    Automatic certificate renewal

    Every hour (3600 seconds) the certificates are checked and every certificate that will expire in the next 30 days (90 days / 3) are renewed.

    Example:
    $ docker run -d \
        --name example-app \
        -e "VIRTUAL_HOST=example.com,www.example.com,mail.example.com" \
        -e "LETSENCRYPT_HOST=example.com,www.example.com,mail.example.com" \
        -e "LETSENCRYPT_EMAIL=foo@bar.com" \
        tutum/apache-php

    Optional container environment variables

    Optional letsencrypt-nginx-proxy-companion container environment variables for custom configuration.

    • ACME_CA_URI - Directory URI for the CA ACME API endpoint (default: https://acme-v01.api.letsencrypt.org/directory). If you set it's value to https://acme-staging.api.letsencrypt.org/directory letsencrypt will use test servers that don't have the 5 certs/week/domain limits. You can also create test certificates per container (see let's encrypt test certificates)

    For example

    $ docker run -d \
        -e "ACME_CA_URI=https://acme-staging.api.letsencrypt.org/directory" \
        -v /path/to/certs:/etc/nginx/certs:rw \
        --volumes-from nginx-proxy \
        -v /var/run/docker.sock:/var/run/docker.sock:ro \
        jrcs/letsencrypt-nginx-proxy-companion
    • DEBUG - Set it to true to enable debugging of the entrypoint script and generation of LetsEncrypt certificates, which could help you pin point any configuration issues.

    • The "com.github.jrcs.letsencrypt_nginx_proxy_companion.nginx_proxy=true" label - set this label on the nginx-proxy container to tell the docker-letsencrypt-nginx-proxy-companion container to use it as the proxy.

    • ACME_TOS_HASH - Let´s you pass an alternative TOS hash to simp_le, to support other CA´s ACME implentation.

    Examples:

    If you want other examples how to use this container, look at:

    • Karl Fathi's Examples

    • More examples from Karl

    • George Ilyes' Examples

    • Dmitry's simple docker-compose example

    注意,这里有个坑,也怪我自己没看清楚,如果镜像已经expose端口就设置VIRTUAL_HOST、LETSENCRYPT_HOST、LETSENCRYPT_EMAIL就行,如果没有就得在设置好三个环境变量之后自己加入--expose 容器内应用服务端口 参数启动。如果容器是discourse这样的,就得在app.yml内设置好环境变量之后把端口映射的80:80改为未占用端口:80,然后再保存重建启动。

    回复
    0
  • 大家讲道理

    大家讲道理2017-06-20 10:07:52

    由于容器只能直接绑定宿主机的端口,例如我有10个web容器,那么这些容器都需要80或者443,这样-p参数不可行,所以要么是通过一个容器作为网关反向代理容器,用nginx,nginx容器进行-p,其他得php-fpm,node这样得web容器,通过nginx做反向代理来进行访问,证书也直接交给nginx服务器,进行443转发就可以实现了。

    其实这些都是基础只是和docker没关系

    这篇文章是一个lnmp环境,
    /a/11...

    如果是多个php-fpm或者node或者python后端服务的话,那么nginx应该是下面这样得

    server{
      listen 80;
      server_name web1;
      location /{
        proxy_pass  ....
      }
    }
    
    server{
      listen 80;
      server_name web2;
      location /{
        proxy_pass  ....
      }
    
    }
    
    server{
      listen 80;
      server_name web3;
      location /{
        proxy_pass  ....
      }
    }

    回复
    0
  • 取消 回复 发送