Nginx map 在配置前端项目多版本中的应用

TL;DR

Nginx 的配置中有一个指令 map 可用于定义变量及其取值, 根据这个定义的变量可以动态的配置静态站点的目录.

实验目标

用户访问 v1.dev.example.com 和 v2.dev.example.com 分别得到 /var/www/html/v1/var/www/html/v2 的目录 中的静态资源.

必要条件

  • 泛解析(wildcard)的域名指向同一台服务器
  • 在系统中配置好前端静态资源的多个版本对应的多个目录

语法知识

map 指令

Syntax: map string $variable { … }

Default: —

Context: http

Code

map $http_host $name {
    hostnames;

    default       0;

    example.com   1;
    *.example.com 1;
    example.org   2;
    *.example.org 2;
    .example.net  3;
    wap.*         4;
}

map $http_user_agent $mobile {
    default       0;
    "~Opera Mini" 1;
}

实际例子

1. 提取 ver 变量

map $host $ver {
  default                    "";
  "~^(?<prefix>[A-z0-9-]+)\." $prefix;
}

通过从 host 中匹配正则取值.

2. 配置静态资源的路径

location / {
  include snippets/proxy.conf;

  root /var/www/html/$ver;
  try_files $uri $uri/index.html /index.html =404;
}

3. 配置 server 块 server_name

server {
  listen 80;
  server_name *.dev.example.com;
  #...
}

拓展思维

现在配置静态资源的目录是给定死的, 能否利用 CI/CD 工具动态的生成呢? 这样一个 git 分支或 tag 就和一个部署的网站建立了关系.

例如, 如果是 gitlab ci 就可以利用 only 字段指定分支, 然后 runner 中运行的脚本可以根据 $CI_COMMIT_BRANCH 环境变量结合 sed 来获得对应的目录名.

export FOLDER_NAME=$(echo $CI_COMMIT_BRANCH | sed 's/\./-/g')

参考

关于本文如您有任何想法和意见,欢迎与我们联系,邮箱地址zhi@uqugu.com
您对本文有什么看法,喜欢或者不喜欢都可以发表意见。