在本站全部Docker化后,目前我使用Traefik对Docker容器的公网映射进行统一管理。其标签化配置,自动续签SSL证书,以及原生的QUIC支持都是很好的特性。

唯一的问题是我迁移的时候没有考虑到以后静态站点的增长需求。此前对于每一个子域名我都拉了一个基础的nginx容器,把www文件夹映射进去。这虽然提供了 不必的 安全性,但是增加了服务器负载。最主要的问题是,一旦我希望添加一个静态站点,哪怕只有一个index.html 都需要走以下流程:

  1. www文件夹下新建目录,放入静态资源
  2. 新建nginx的站点配置文件,基本是把之前的抄过来改一下host
  3. docker-compose.yml里新加一个服务,也是把以前的段落复制粘贴改名称
  4. 把以上文件移到服务器上
  5. docker compose up -d
  6. 添加DNS记录

这无疑增加了创意落地为现实耗费的时间精力。

我仔细观察了一下,www的目录被我收拾得还不错,基本上子目录的名称就是子域名,于是就有了想法根据请求头自动切换资源目录的想法。并在AI的帮助下做成了。

申请通配符证书

为了尽可能减少每次新增站点所需的工作量,我配置Traefik为我自动申请*.pengs.toppengs.top的通配符证书,这样一个证书就可以为所有子域名提供SSL支持,缺点是需要你的DNS解析商支持(应该基本上都支持吧)

这一部分可以参看:如何使用Traefik通过Cloudflare DNS验证申请泛域名证书

新建Docker Compose Service

docker-compose.yml内新增服务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
static-sites:
image: nginx:alpine
container_name: static-sites
restart: unless-stopped
volumes:
- "./base/nginx/nginx.conf:/etc/nginx/nginx.conf:ro"
- "./base/nginx/sites-enabled/static-sites.conf:/etc/nginx/conf.d/default.conf:ro"
- "./web:/var/www:ro"


labels:
- "traefik.enable=true"
- "traefik.docker.network=docker-services_proxy"


- "traefik.http.routers.static-sites.rule=HostRegexp(`^[a-z0-9-]+\\.pengs\\.top$$`)"
- "traefik.http.routers.static-sites.priority=1"
- "traefik.http.routers.static-sites.entrypoints=websecure"
- "traefik.http.services.static-sites.loadbalancer.server.port=80"
- "traefik.http.services.static-sites.loadbalancer.server.scheme=http"

这里需要你自行修改域名。

新建nginx配置文件

上面的配置中,我们将static-sites.conf穿透进了Docker容器中,现在来创建它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
server {
listen 80 default_server;
listen [::]:80;
server_name ~^(?<subdomain>[^.]+)\.pengs\.top$;

gzip on;
gzip_disable "msie6";
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_buffers 16 8k;
gzip_min_length 256;
gzip_types application/atom+xml application/geo+json application/javascript application/x-javascript application/json application/ld+json application/manifest+json application/rdf+xml application/rss+xml application/xhtml+xml application/xml font/eot font/otf font/ttf image/svg+xml text/css text/javascript text/plain text/xml;

# 动态根目录:子域名对应文件夹
root /var/www/$subdomain;
index index.html index.htm;

location / {
try_files $uri $uri/ /index.html =404;
add_header Cache-Control private;
}

# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|webp|mp4|mkv)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
}

额,看起来这么长,其实主要就是用正则表达式匹配了subdomain然后访问对应目录。多出来的那部分内容,一方面是增加了gzip压缩,利用服务器的cpu资源换取更少的流量流出,如果不需要刻意注释掉。另外的就是增加了一些不会改变的资源的缓存。

拉起!

ssh登陆上服务器使用docker compose up -d拉起服务,然后到你的www目录下新建一个目录,再去dns那里添加记录就能访问到对应资源了。

祝安好!