alwaystest / Blog

24 stars 2 forks source link

docker-nginx-letsencrypt #64

Open alwaystest opened 7 years ago

alwaystest commented 7 years ago

docker-nginx-letsencrypt

标签(空格分隔): Docker Nginx LetsEncrypt


申请了一个域名,自己配了DNS解析,搞了一个Nginx服务器,顺便加上了LetsEncrypt的HTTPS证书。

好多技术,要是不能自己亲手操作一遍,理解总是会有偏差。

freedom的网站有点诡异哦,看不到注册的入口,只有挑好了想要的域名之后一路下一步,最后就能到注册页面。

在域名提供商处申请好域名后,需要给域名指定要使用的NameServer,就是DNS解析数据的提供商啦。一般的话,默认就使用了域名提供商自己的NameServer了。

NameServer我用了DnsPod的。填写信息的时候发现域名输入没有限制诶,愿意的话输一个www.baidu.com也没问题的哦。后来发现输入的是主机记录(域名前缀)。要添加域名的时候则提示已经被占用,注册者的联系方式可以通过WhoIs来查出来。所以想要购买一个已经被占有的域名的时候,可以去WhoIs查查看。

知乎 · 为什么域名根服务器只能有13台呢?

之前错误的以为13组域名根服务器里存储了所有的域名信息,犯过这次错才发现不是这样子的,13组根服务器起到的是指路的作用。

不想装LetsEncrypt的CertBot,使用Docker包装一下就省的以后还要考虑卸载什么的。

找到一个自动HTTPS证书自动续期的方案 Github

测试部署的时候可以在Environment里添加LETSENCRYPT_TEST = trueACME_CA_URI=https://acme-staging.api.letsencrypt.org/directory

主要方案就是使用Nginx反向代理,启动一个Nginx的容器监听80,443端口,同时,这个Nginx实例还被用来实现实现签发HTTPS证书。

实际的WebContainer运行起来之后,Host的80端口被占用了,每次指定一个不冲突的端口也比较麻烦,直接Expose,容器启动后随机分配一个Host端口,但是这样又给反向代理的配置造成了麻烦,所幸有Docker-gen可以用来解决这个问题。通过动态生成Nginx配置文件解决了这个问题。

本来我还有一个想法是想在更新HTTPS证书的时候不要中断服务,但是看起来即便使用这个方案,也是可能中断一下服务的。

docker_kill "${_nginx_proxy_container}" SIGHUP

又看见了SIGHUP,之前ssh断开导致执行的程序终止就是它,今天发现这个信号量居然用做重载Configuration。

不知道reload container和reload Nginx配置在速度上有多大区别。


最后大概的结构是这样子的。

入口处是Nginx服务器监听并且转发80和443端口的请求。反向代理,将真正的响应使用HTTPS的方式返回给用户。

Docker-gen用来监听container的活动,如果有符合条件的容器启动或停止,则根据容器的端口和Environment中的变量使用template生成Nginx的config,并且让网关Nginx容器reload使规则生效。

letsencrypt-nginx-proxy-companion 容器里面也有一个Docker-gen,监听符合条件的容器启动和停止,根据Environment中指定的域名去检查和更新HTTPS证书。同时启动一个服务,定时检查证书有效期,并且及时更新。

这样子每当服务器上启动了一个expose 80 端口的容器(或者其他端口也行),Docker-gen就会根据服务容器的域名在网关Nginx上生成相应的反向代理规则。重启Nginx网关。

letsencrypt-nginx-proxy-companion会根据Env中指定的域名申请证书,申请证书的时候会让Nginx网关使用指定的配置,在网站指定目录下放一些文件,通过让别的服务器使用指定域名访问这些文件来证明要申请证书的域名对应的服务器在我们的管理下。具体申请证书用的并不是Let's Encrypt提供的Client,而是simp_le

对于Frp这种服务来讲,由于它本身启用特权模式后就可以在Client端指定Server端绑定哪个端口,这样特别灵活,但是不适用于Docker的环境,因为Expose的端口并不能在容器中随意更改。但是我还是想要把所有的Web访问加上HTTPS,所以麻烦点就麻烦点吧。

配置方案是这样子的,容器本身的Dashbord端口和接收frpc连接的端口不做HTTPS,直接绑定到Host端口。然后Expose 80端口用来处理外部访问。网关Nginx把相关域名的请求转发给Frps处理。将处理结果使用HTTPS返回给用户。

这样子损失了frpc特权模式灵活指定端口的优势,并且目前只能使用URL区分服务,而不能用SubDomain,所以多少有些不方便。根据我的需求,大不了每次改了frpc的配置以后再去服务器重新构建一遍镜像呗,反正变动也不频繁。至于修改Docker-gen的template来实现这个,再学Go的模板语法好烦哦,什么时候我突然对Go兴趣大发再考虑吧。

相对而言目前我更偏好NodeJS和Kotlin。