Categories
SysOps

How to use regex to dynamically define server name

Use regex to define server names when using Nginx to dynamically serve or route traffic.

The most straightforward configuration to dynamically serve projects using dedicated directories, return 404 if the project is not found.

# Server configuration
# 
# Serve PROJECT.projects.example.org from /var/www/html/PROJECT directory
# except when PROJECT is www or contains word admin
#
server {
  listen 80;

  server_name ~^(?!www\.|admin)(?<project>\w+)\.users\.example\.org$;
  root /var/www/html/$project;
  index index.html;
  location / {
    try_files $uri $uri/ =404;
  }
}

Serve user pages, redirect to the main page when the user directory is not found.

# Server configuration
#
# Serve USER.users.example.org from /var/www/html/USER directory
# except when USER is www, root or contains word admin
#
server {
  listen 80;

  server_name ~^(?!www\.|root\.|admin)(?<user>\w+)\.users\.example\.org$;
  root /var/www/html/$user;
  index index.html;
  location / {
    try_files $uri $uri/ @default;
  }

  location @default {
    return 301 http://www.example.org;
  }
}

Serve the status page for a specific application by proxying to the internal network.

# Server configuration
#
# Serve APPLICATION.SERVER.status.example.org 
# by proxying to APPLICATION.SERVER.internal.example.org
#
server {
  listen 80;

  server_name ~^(?<application>\w+)\.(?<server>\w+)\.status\.example\.org$;
  index index.html;
    location / {
      resolver 8.8.8.8;
      proxy_pass https://$application.$server.internal.example.org$request_uri;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header Host $application.$server.internal.example.org;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Serve specific application and port by proxying to internal network using defined maps, return 500 internal server error if not specified.

# Server configuration
#
# Serve APPLICATION-PORT.looking-glass.example.org by proxying to internal network  using defined maps
# For example http://rabbitmq-rabbitadmin.looking-glass.example.org 
# will proxy request to https://10.0.11.1:15672
#
map $application $internal_server {
  elasticsearch 10.0.10.1;
  rabbitmq      10.0.11.1;
}

map $port $internal_port {
  elasticsearch 9200;
  rabbitadmin   15672;
  amqp          5672;
}

server {
  listen 80;

  server_name ~^(?<application>\w+)-(?<port>\w+)\.looking-glass\.example\.org$;
  location / {
    proxy_pass https://$internal_server:$internal_port$request_uri;
  }
}