使用Docker使用自动SSL生成设置Nginx反向代理
什么是反向代理?它的优点是什么?
什么是反向代理?
反向代理是坐在许多其他服务器的前面的服务器,并将客户端请求转发到相应的服务器。
然后,代理服务器还接收并将服务器的响应转发给客户端。
你为什么要使用这样的设置?
有几个好理由。
此设置可用于设置负载均衡器,缓存或者免受攻击的保护。
我没有在这里进入细节。
相反,将介绍如何利用反向代理的概念来在同一服务器上设置多个服务。
与我们在上面看到的图像相同。
我们可以做的是在反向代理模式下在Docker容器中运行ngnix服务器。
其他Web服务也可以在其各自的容器中运行。
Nginx容器将以某种方式配置,即它知道哪种Web服务其中包含哪个容器。
这是节省不同服务器中托管每个服务的成本的好方法。
由于反向代理服务器,我们可以在同一Linux服务器中运行多个服务。
将nginx设置为反向代理,用于使用Docker在同一服务器上部署多个服务
让我向我们展示如何进行配置上述设置。
使用以下步骤,我们可以使用与其自身各个域或者子域的每个独立容器安装在nginx下运行的多个基于Web的应用程序容器。
首先,让我们看看你需要什么来遵循本教程。
准备工作
我们将需要以下知识轻松使用本教程。
Althogh,你也可以在没有它们的情况下获得。
- Linux系统/服务器。我们可以使用Linode Cloud Service轻松地在几分钟内部署Linux服务器。
- 熟悉Linux命令和终端。
- Docker的基础知识。
- 我们应该在Linux服务器上安装Docker和Docker Compose。请阅读我们的教程,请在CentOS上安装Docker和Docker。
- 我们还应该拥有一个域(以便我们可以在子域上设置服务)。
我使用theitroad.com作为教程中的示例域名。
请确保根据我们自己的域或者子域更改它。
除了上述外,还请确保以下内容:
更改域名的DNS记录
在域名提供程序的A/AAAA或者CNAME记录面板中,确保域和子域(包括WWW)指向我们服务器的IP地址。
这是我们参考的示例:
|主机名| IP地址| TTL |
| --- - | --- | - - |
| theitroad.com | 172.105.50.178 |默认|
| * | 172.105.50.178 |默认|
| sub0.theitroad.com | 172.105.50.178 |默认|
| sub1.theitroad.com | 172.105.50.178 |默认|
要确保所有容器应用程序处于缓解状态,并且在部署后,从未在内存中运行,则必须在系统上具有必要的交换空间。
我们可以随时根据系统上的可用内存调整交换。
我们可以根据单个服务器上的App容器捆绑并估算其累积内存使用情况来决定交换空间。
第1步:设置nginx反向代理容器
从设置nginx反向代理开始。
创建名为"Reverse-Proxy"的目录并切换到它:
mkdir reverse-proxy && cd reverse-proxy
创建名为"docker-compose.yml""的文件,在我们喜欢的基于终端的文本编辑器中打开它,如Vim或者Nano。
对于nginx反向代理,我将使用jwilder/nginx-proxy镜像。
在docker-compose.yml文件中复制并粘贴以下内容:
version: "3.7" services: reverse-proxy: image: "jwilder/nginx-proxy:latest" container_name: "reverse-proxy" volumes: - "html:/usr/share/nginx/html" - "dhparam:/etc/nginx/dhparam" - "vhost:/etc/nginx/vhost.d" - "certs:/etc/nginx/certs" - "/run/docker.sock:/tmp/docker.sock:ro" restart: "always" networks: - "net" ports: - "80:80" - "443:443"
现在让我们通过Compose文件的重要部分:
- 我们已声明四个卷,HTML,DHPA内存,VHOST和CERT。他们持久数据,即使在容器下降后,你肯定想要保留。 "HTML"和"vHost"卷"在下一步允许的"加密容器部署"中会非常重要。
他们旨在一起工作。
- Docker Soocker在容器内安装只读。这一个是反向代理容器生成nginx的配置文件的必要条件,检测具有特定环境变量的其他容器。
- 重新启动策略设置为"始终"。其他选项包括"失败"和"除非停止"。在这种情况下,似乎更合适。
- 端口80和443分别绑定到HTTP和HTTPS的主机。
- 最后,它使用不同的网络,而不是默认的桥接网络。
Using a user defined network is very important. This will help in isolating all the containers that are to be proxied, along with enabling the reverse proxy container to forward the clients to their desired/intended containers and also let the containers communicate with each other (Which is not possible with the default bridge network unless icc is set to true for the daemon).
请记住,yml对标签和展示率非常挑战。
第2步:设置用于自动SSL证书生成的容器
为此,我们可以使用JRCS/LetSencrypt-Nginx-Proxy-Companion容器图像。
在同一`docker compose.yml上使用之前使用的文件,添加以下行:
letsencrypt: image: "jrcs/letsencrypt-nginx-proxy-companion:latest" container_name: "letsencrypt-helper" volumes: - "html:/usr/share/nginx/html" - "dhparam:/etc/nginx/dhparam" - "vhost:/etc/nginx/vhost.d" - "certs:/etc/nginx/certs" - "/run/docker.sock:/var/run/docker.sock:ro" environment: NGINX_PROXY_CONTAINER: "reverse-proxy" DEFAULT_EMAIL: "Hyman@theitroad" restart: "always" depends_on: - "reverse-proxy" networks: - "net"
在此服务定义中:
- 我们正在使用与反向代理容器的相同的精确卷。 "HTML"和"vHost"卷分享是让Letsencrypt成功的Acme挑战所必需的。
此容器将在容器中生成"/etc/nginx/certs"内的证书"。这就是我们使用反向代理容器共享此卷的原因。 "DhParam"卷"卷将包含DHParam文件。安装套接字以检测具有特定环境变量的其他容器。
- 其中我们已定义两个环境变量。 "nginx_proxy_container"变量指向反向代理容器。将其设置为容器的名称。 "default_email"是为每个域/子域生成证书而使用的电子邮件。
- 设置了
depends_on
选项,以便此服务等待首先启动的反向代理,然后才能启动。 - 最后,这个容器也共享相同的网络。这对于两个容器进行通信是必要的。
第3步:完成Docker Compose文件
完成服务定义后,使用以下行完成Docker撰写文件:
volumes: certs: html: vhost: dhparam: networks: net: external: true
网络NET
设置为外部,因为代理容器也必须使用此网络。
如果我们将网络留给"Docker-Commspose"创建,网络名称将取决于当前目录。
这将创建一个奇怪的网络。
除此之外,其他容器必须将该网络设置为外部,否则这些文件也必须驻留在同一目录中,其中都不是理想的。
因此,使用创建网络
docker network create net
以下是docker-compose.yml
文件的整个内容。
version: "3.7" services: reverse-proxy: image: "jwilder/nginx-proxy:latest" container_name: "reverse-proxy" volumes: - "html:/usr/share/nginx/html" - "dhparam:/etc/nginx/dhparam" - "vhost:/etc/nginx/vhost.d" - "certs:/etc/nginx/certs" - "/run/docker.sock:/tmp/docker.sock:ro" restart: "always" networks: - "net" ports: - "80:80" - "443:443" letsencrypt: image: "jrcs/letsencrypt-nginx-proxy-companion:latest" container_name: "letsencrypt-helper" volumes: - "html:/usr/share/nginx/html" - "dhparam:/etc/nginx/dhparam" - "vhost:/etc/nginx/vhost.d" - "certs:/etc/nginx/certs" - "/run/docker.sock:/var/run/docker.sock:ro" environment: NGINX_PROXY_CONTAINER: "reverse-proxy" DEFAULT_EMAIL: "Hyman@theitroad" restart: "always" depends_on: - "reverse-proxy" networks: - "net" volumes: certs: html: vhost: dhparam: networks: net: external: true
最后,我们可以使用以下命令部署这两个容器(NGNIX并允许允许的加密):
docker-compose up -d
第4步:验证NGNIX反向代理是否正常工作
将前端服务的容器需要定义两个环境变量。
Virtual_host
:用于生成反向代理配置
letsencrypt_host
:为生成必要的证书
确保对这两个变量有正确的值。
我们可以使用像这样的反向代理运行nginx-dummy镜像:
docker run --rm --name nginx-dummy -e VIRTUAL_HOST=sub.theitroad.com -e LETSENCRYPT_HOST=sub.theitroad.com -e VIRTUAL_PORT=80 --network net -d nginx:latest
现在,如果我们转到上一个命令中使用的子域,则应查看NGNIX Server的消息。
一旦成功测试它,我们可以停止运行的Docker容器:
docker stop nginx-dummy
如果我们不使用它,我们也可能停止NGNIX反向代理:
docker-compose down
第5步:使用反向代理运行其他服务容器
设置其他容器的过程使其可以被置于代理非常简单。
我将在一瞬间用两个NextCloud部署实例来展示它。
让我先告诉你你在这里做什么。
不要与任何端口绑定
容器可以留出为前端提供的端口。
反向代理容器将自动检测到该。
(可选)定义Virtual_Port
如果反向代理容器无法检测到端口,则可以定义名为"virtual_port"的另一个环境变量,其中包含前端的端口或者我们想要获取代理的服务,如"80"或者"7765"。
设置Let’s Encrypt 特定于容器的电子邮件
我们可以覆盖"Default_email"变量",并为特定容器/Web服务的域/子域/子域/子域/子域/子域证书设置一个特定的电子邮件地址,通过将电子邮件ID设置为环境变量"letsencrypt_email"。
这适用于每个Docker。
既然你知道所有这些东西,让我向我们展示部署使用nginx代理容器来代理的nextcloud实例的命令,并将启用TLS(SSL/HTTPS)。
This is NOT AN IDEAL deployment. The following command is used for demonstrative purpose only.
docker run --name nextcloud --network net -e VIRTUAL_HOST="sub0.theitroad.com" -e LETSENCRYPT_HOST="sub0.theitroad.com" -d nextcloud:19.0.2
在该示例中,我们将与反向代理容器相同的网络,定义了两个环境变量,具有适当的子域(相应设置)。
几分钟后,我们应该在Sub0.theitroad.com上看到NextCloud运行。
在浏览器中打开它以验证。
我们可以在不同的子域内像上个子域一样部署另一个下列实例,如下所示:
docker run --name anothernextcloud --network net -e VIRTUAL_HOST="sub1.theitroad.com" -e LETSENCRYPT_HOST="sub1.theitroad.com" -d nextcloud:19.0.2
现在,我们应该看到在同一服务器上的不同子域上运行的不同的NextCloud实例。
使用此方法,我们可以在不同子域的同一服务器上部署不同的Web应用程序,这非常方便。