NGINX Workshop
Running Modern APIs with
NGINX Unit and NGINX web server
All Things Open
19-Oct-2020
Today’s hosts
Timo Stark 🇩🇪
• Product Management Engineer, NGINX
• @linux_lenny
Liam Crilly 🇬🇧
• Senior Director, Product Management, NGINX
• @liamcrilly
What we’re going to build
API Client Internet / WAN API Gateway Backend APIs
Agenda
1. Introducing NGINX
2. Running APIs with NGINX
Unit
3. Q&A
4. Break (15 mins)
5. Deploying NGINX web
server as an API gateway
6. Q&A
5
“... when I started NGINX,
I focused on a very specific
problem – how to handle more
customers per a single server.”
- Igor Sysoev, NGINX creator and founder
Introducing NGINX
6
2004
• NGINX
0.1
2007
• “Viable”
2011
• NGINX, Inc.
• NGINX 1.0
2013
• NGINX Plus R1
2018
• NGINX Unit 1.0
• Controller 1.0
2019
• Controller 2.0
(API mgmt.)
• NGINX Plus
R19
• Acquired by
F5 Networks
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
Agenda
1. Introducing NGINX
2. Running APIs with
NGINX Unit
3. Break / Q&A
4. Deploying NGINX web
server as an API
gateway
5. Q&A
What we’re going to build
API Client Internet / WAN API Gateway Backend APIs
What is NGINX Unit
10
“NGINX Unit is a polyglot app
server, a reverse proxy, and a static
file server, available for Unix-like
systems”
NGINX Unit
11
Flexible
Performance
Security
8 Supported App
Languages
NGINX Unit
Architecture
Unit enables
NGINX Unit
Architecture
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
16
Process overview
17
Installing NGINX Unit (simple)
18
CentOS / RHEL(*)
• yum install unit unit-go unit-
devel unit-php
Ubuntu / Debian(*)
• apt-get install unit unit-dev
unit-go unit-php
Docker
• docker pull nginx/unit:1.20.0-
full
MacOS / MacBook
• Docker
Unit configuration
19
curl –s --unix-socket /var/run/control.unit.sock localhost
1
2
3
4
5
6
7
8
{
"certificates": {
...
},
"config": {
...
}
}
TLS Certificates for
the listeners
General
configuration object
Unit config
20
curl –s --unix-socket /var/run/control.unit.sock localhost/config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
20
22
"settings": {
"http": {
...
}
},
"listeners": {
...
},
"routes": [
{
...
},
],
"applications": {
...
},
"upstreams": {
...
},
"access_log": "/var/log/access.log"
}
Instace wide settings
Bind ip addr and port
Control the unit-
router
Our applications
Proxy upstreams
access-logs
Unit routes 1
21
curl –s --unix-socket /var/run/control.unit.sock
localhost/config/routes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
20
22
"django": [
{
"match": {
"uri": "/static/*"
},
"action": {
"share": "/var/apphome/python/"
}
},
{
"action": {
"pass": "applications/django_project"
}
}
],
name
Routing pattern
definition
Action if pattern
matches
Unit routes 2
22
curl –s --unix-socket /var/run/control.unit.sock
localhost/config/routes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
20
22
23
"wordpress": [
{
"match": {
"uri": [
"*.php",
"*.php/*",
"/wp-admin/"
]
},
"action": {
"pass": "applications/wordpress/direct"
}
},
{
"action": {
"share": "/var/apphome/wordpress",
"fallback": {
"pass": "applications/wordpress/index"
}
}
}
]
name
Routing pattern
definition
Action if pattern
matches
Fallback action
with static file share
$ curl –-unix-socket /var/run/unit.control.sock
–-data-binary "@.unit.conf.json"
http://localhost/config
$ curl –-unix-socket /var/run/unit.control.sock
–-data-binary "UpdatedSecret"
http://localhost/config/applications/app/environment/APISEC
Unit in docker
24
• Use the nginx/unit base images
• Make use of the /docker-entrypoint-d features
◦ Apply initial configurtion
◦ Apply initial uploding of certificates for TLS encryption
◦ Run Shell-scripts
What we have now
Developers
Machine
Backend APIs
AWS EC2
AWS
Container
Registry
push pull
API Gateway
Agenda
1. Introducing NGINX
2. Running APIs with
NGINX Unit
3. Break / Q&A
4. Deploying NGINX web
server as an API
gateway
5. Q&A
Agenda
1. Introducing NGINX
2. Running APIs with
NGINX Unit
3. Break / Q&A
4. Deploying NGINX web
server as an API
gateway
5. Q&A
What we’re going to build
API Client Internet / WAN API Gateway Backend APIs
#1 40%“Most websites use NGINX” of NGINX deployments
are as an API gateway
Source: NGINX User survey 2017, 2018, 2019Source: Netcraft April 2019 Web Server Survey
Installing NGINX (official)
30
http://nginx.org/en/linux_packages.html
• RHEL/Centos
• Debian
• Ubuntu
• SLES
• Alpine
Installing NGINX (simple)
31
CentOS / RHEL
• yum install nginx
Ubuntu / Debian
• apt-get install nginx
Docker
• docker pull nginx
MacOS / MacBook
• Homebrew
• Docker
NGINX Open Source Cycle
Stable retired
Mainline forked
Mainline “bump”
New stable
Critical bugfix
Stable
1.even.0
Mainline
1.odd.0
April
• Mainline
• New features
• 8-12 releases per year
• Stable
• Critical bug fixes only
• 1-2 releases per year
Define our API gateway
33
• Create api_gateway.conf
• $ mkdir
/etc/nginx/conf.d/my_apis
• $ nginx -s reload
• $ curl localhost:8080
/etc/nginx/conf.d/api_gateway.conf
1
2
3
4
5
6
7
8
9
10
11
12
server {
listen 8080;
# TLS config goes here (for production)
include conf.d/my_apis/*.conf;
# Invalid resource
location / {
return 400;
}
}
$ curl http://localhost:8080/
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx/1.15.10</center>
</body>
</html>
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
Define JSON error responses
36
/etc/nginx/conf.d/api_gateway.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
server {
listen 8080;
# TLS config goes here (for production use)
include conf.d/my_apis/*.conf;
# Invalid resource
location / {
return 400;
}
# Error responses
default_type application/json;
error_page 400 = @400;
location @400 {
return 400 '{"status":400,"message":"Bad request"}n';
}
}
• error_page to
named location
(@)
• Download full
error set
◦ github.com/lcrilly/
nginx-api-gateway
Enable TLS
37
/etc/nginx/conf.d/api_gateway.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
server {
listen 8080;
# TLS config goes here (for production use)
listen 443 ssl;
ssl_certificate /etc/nginx/ssl/space.nginx.org.crt;
ssl_certificate_key /etc/nginx/ssl/space.nginx.org.key;
include conf.d/my_apis/*.conf;
# Invalid resource
location / {
return 400;
}
• Can listen on
plaintext and
SSL/TLS ports
simulateously
◦ But don’t!
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
🪐
Publish the Space API
API Client Internet / WAN API Gateway Space API
Microservices routing
Events
microservice
Images
microservice
/api/space/planets/*
/api/space/events/*
/api/planets/images/*
Planets
microservice
Define the backend servers
41
• Upstream servers
(backends)
• Multiple servers will
be load balanced
• Next step is to define
the API itself
/etc/nginx/conf.d/api_backends.conf
1
2
3
4
5
6
7
8
9
10
11
upstream planets-svc {
server 172.31.46.145:8080;
}
upstream events-svc {
server 172.31.46.145:8085;
}
upstream images-svc {
server 172.31.46.145:8090;
}
Define the API
42
• Nested locations
• Location (URI) matching
◦ Exact (=)
◦ Regex (~)
◦ Prefix ( )
• Policies can apply at
any level
/etc/nginx/conf.d/my_apis/space.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
location /api/space/ {
location = /api/space/planets {
proxy_pass http://planets-svc;
}
location /api/space/planets/ {
proxy_pass http://planets-svc;
}
location ~ ^/api/space/images/.+.(svg|png)$ {
proxy_pass http://images-svc;
}
location /api/space/events {
proxy_pass http://events-svc;
}
}
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
Rate limiting
44
/etc/nginx/conf.d/api_gateway.conf
1
2
3
4
limit_req_zone $remote_addr zone=perip:1m rate=2r/s;
server {
listen 8080;
• Rate limit is
configured and
monitored at a global
level
• Limit is applied where
we want it
◦ Per API gateway
◦ Per API definition 
◦ Per URI/route
/etc/nginx/conf.d/my_apis/space.conf
1
2
3
4
5
6
7
8
9
10
location /api/space/ {
limit_req zone=perip nodelay; _
limit_req_status 429; _
location = /api/space/planets {
proxy_pass http://planets-svc;
}
location /api/space/planets/ {
proxy_pass http://planets-svc;
}
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
NGINX authentication options
46
API
Gateway
HTTP
Basic
Client Cert
JWT
• NGINX Plus
API Key
Custom
Token
• External API
HTTP Basic authentication
47
• Other auth options
replace auth_basic
directives
◦ auth_jwt (JWT)
◦ auth_request ( API key)
◦ auth_request (custom)
• Exception is client
certs at server level
◦ ssl_client_certificate
/etc/nginx/conf.d/my_apis/space.conf
1
2
3
4
5
6
7
8
9
10
location /api/space/ {
auth_basic "Space API"; __
auth_basic_user_file conf.d/api_clients.htpasswd; _
limit_req zone=perip;
limit_req_status 429;
location = /api/space/planets {
proxy_pass http://planets-svc;
}
$ cd /etc/nginx/conf.d
$ wget http://files.liamcrilly.com/api_clients.htpasswd
API key authentication (example)
48
• Requests must pass
auth_request test
• Internal location
performs API key
validation logic
◦ Returns validation status
back to auth_request
• Keys can be SHA-256
protected with njs
/etc/nginx/conf.d/my_apis/space.conf
1
2
…
16
17
18
19
20
21
22
23
24
25
26
27
28
29
location /api/space/ {
auth_request /_validate_apikey;
…
}
location = /_validate_apikey {
internal;
if ($http_apikey = "") {
return 401; # Unauthorized
}
if ($api_client_name = "") {
return 403; # Forbidden
}
return 204; # OK (no content)
}
/etc/nginx/conf.d/apikey_clients.conf
1
2
3
4
5
map $http_apikey $api_client_name {
default "";
"7B5zIqmRGXmrJTFmKa99vcit" "client_one";
"QzVV6y1EmQFbbxOfRCwyJs35" "client_two";
}
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
HTTP method matching
50
• limit_except directive
controls HTTP
methods
• Disable
authentication for
easier testing
/etc/nginx/conf.d/my_apis/space.conf
1
2
3
4
5
6
7
8
9
10
…
19
20
21
22
23
location /api/space/ {
auth_basic "Space API";
auth_basic_user_file conf.d/api_clients.htpasswd;
limit_req zone=perip;
limit_req_status 429;
location = /api/space/planets {
proxy_pass http://planets-svc;
}
location /api/space/events {
limit_except GET POST { deny all; } _
proxy_pass http://events-svc;
}
}
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
JSON request validation [1/2]
52
• Load JavaScript
module
◦ nginx-module-njs
• Use JSON.parse() to
test request body for
valid JSON
/etc/nginx/nginx.conf
1
2
3
4
5
6
7
8
9
10
11
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
load_module modules/ngx_http_js_module.so; _
events {
worker_connections 1024;
}
/etc/nginx/conf.d/json_validation.js
1
2
3
4
5
6
7
8
9
10
11
12
13
export default { parseRequestBody };
function parseRequestBody(r) {
try {
if (r.variables.request_body) {
JSON.parse(r.variables.request_body);
}
return r.variables.upstream;
} catch (e) {
r.error('JSON.parse exception');
return '127.0.0.1:10415'; // Address for error response
}
}
JSON request validation [2/2]
53
• NGINX hates to buffer
• Use mirror module to
force early-reading of
$request_body
• Variable evaluation
controls timing of JS
code execution /etc/nginx/conf.d/api_gateway.conf
10
11
12
13
14
# Request body validation
location /_get_request_body {
internal;
return 204;
}
/etc/nginx/conf.d/json_validation.conf
1
2
3
4
5
6
7
8
js_import conf.d/json_validation.js;
js_set $json_validated json_validation.parseRequestBody;
server {
listen 127.0.0.1:10415; # This is the error response of json_validator()
return 415; # Unsupported media type
include conf.d/my_apis/errors_json.conf;
}
/etc/nginx/conf.d/my_apis/space.conf
8
9
10
11
12
13
location = /api/space/events {
limit_except GET POST { deny all; }
set $upstream events-svc;
mirror /_get_request_body; # Force early-reading of request body
proxy_pass http://$json_validated$request_uri;
}
How did we do?
• Error handling
• API definition
• Rate limiting
• Authentication
• HTTP methods
• JSON validation
Agenda
1. Introducing NGINX
2. Running APIs with
NGINX Unit
3. Break / Q&A
4. Deploying NGINX web
server as an API
gateway
5. Q&A
Resources
• NGINX Unit
◦ https://unit.nginx.org/
• Official NGINX open source downloads
◦ http://nginx.org/en/linux_packages.html
• Configuration files and code samples
◦ https://github.com/nginx/unit-examples
◦ https://github.com/lcrilly/nginx-api-gateway
• NGINX Plus developer license
◦ https://www.nginx.com/developer-license/
◦ Code: ato2020workshop
Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server
fin

More Related Content

PDF
DNS - Domain Name System
PDF
클라우드 네이티브 데이터베이스 서비스로 Oracle RAC 전환 - 김지훈 :: AWS 클라우드 마이그레이션 온라인
PDF
Apache Server Tutorial
PDF
AWS Builders - Industry Edition: DevSecOps on AWS - 시작은 IAM 부터
PPTX
Apache web service
PPTX
Domain name system (dns)
PDF
신규 미디어서비스 소개 : 손쉬운 라이브 소스 클라우드 입수부터 간편한 라이브 스트리밍 구축까지 – 임석영 AWS 솔루션즈 아키텍트:: A...
PPTX
High Performance Object Storage in 30 Minutes with Supermicro and MinIO
DNS - Domain Name System
클라우드 네이티브 데이터베이스 서비스로 Oracle RAC 전환 - 김지훈 :: AWS 클라우드 마이그레이션 온라인
Apache Server Tutorial
AWS Builders - Industry Edition: DevSecOps on AWS - 시작은 IAM 부터
Apache web service
Domain name system (dns)
신규 미디어서비스 소개 : 손쉬운 라이브 소스 클라우드 입수부터 간편한 라이브 스트리밍 구축까지 – 임석영 AWS 솔루션즈 아키텍트:: A...
High Performance Object Storage in 30 Minutes with Supermicro and MinIO

What's hot (20)

PDF
AWS와 함께 하는 클라우드 컴퓨팅 - 홍민우 AWS 매니저
PDF
Dns security
PPTX
Storage basics
PDF
ログ管理のベストプラクティス
PPTX
Snowflake essentials
PDF
Amazon DocumentDB vs MongoDB 의 내부 아키텍쳐 와 장단점 비교
PDF
IT Infrastructure Automation with Ansible
PPT
slide on DNS
PPTX
From cache to in-memory data grid. Introduction to Hazelcast.
PDF
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
PPTX
Change Data Capture to Data Lakes Using Apache Pulsar and Apache Hudi - Pulsa...
PDF
Amazon OpenSearch Deep dive - 내부구조, 성능최적화 그리고 스케일링
PPT
Understanding nas (network attached storage)
PPT
Storage Managment
PDF
Building large scale transactional data lake using apache hudi
PDF
[2017 AWS Startup Day] AWS 비용 최대 90% 절감하기: 스팟 인스턴스 Deep-Dive
PPTX
AWS S3 | Tutorial For Beginners | AWS S3 Bucket Tutorial | AWS Tutorial For B...
PDF
202110 AWS Black Belt Online Seminar AWS Site-to-Site VPN
PPTX
Active directory architecture
PPTX
Linux shell env
AWS와 함께 하는 클라우드 컴퓨팅 - 홍민우 AWS 매니저
Dns security
Storage basics
ログ管理のベストプラクティス
Snowflake essentials
Amazon DocumentDB vs MongoDB 의 내부 아키텍쳐 와 장단점 비교
IT Infrastructure Automation with Ansible
slide on DNS
From cache to in-memory data grid. Introduction to Hazelcast.
Amazon RDS Proxy 집중 탐구 - 윤석찬 :: AWS Unboxing 온라인 세미나
Change Data Capture to Data Lakes Using Apache Pulsar and Apache Hudi - Pulsa...
Amazon OpenSearch Deep dive - 내부구조, 성능최적화 그리고 스케일링
Understanding nas (network attached storage)
Storage Managment
Building large scale transactional data lake using apache hudi
[2017 AWS Startup Day] AWS 비용 최대 90% 절감하기: 스팟 인스턴스 Deep-Dive
AWS S3 | Tutorial For Beginners | AWS S3 Bucket Tutorial | AWS Tutorial For B...
202110 AWS Black Belt Online Seminar AWS Site-to-Site VPN
Active directory architecture
Linux shell env
Ad

Similar to Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server (20)

PPTX
What's new in NGINX Plus R19
PPTX
Service Discovery using etcd, Consul and Kubernetes
PPTX
KONG-APIGateway.pptx
PDF
ITB2019 NGINX Overview and Technical Aspects - Kevin Jones
PPTX
Ansible benelux meetup - Amsterdam 27-5-2015
PPTX
Docker Enterprise Workshop - Technical
PPTX
What’s New in NGINX Plus R16?
PDF
Load Balancing Applications with NGINX in a CoreOS Cluster
PDF
DSLing your System For Scalability Testing Using Gatling - Dublin Scala User ...
PDF
MesosCon - Be a microservices hero
PDF
NGINX Unit: Rebooting our Universal Web App Server
PDF
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
PDF
Sprint 17
PDF
NGINX: Basics and Best Practices EMEA
PDF
Introduction to CloudStack API
PPTX
signalr
PDF
Load Balancing Applications on Kubernetes with NGINX
PDF
What_s_New_in_OpenShift_Container_Platform_4.6.pdf
PDF
Node.js to the rescue
PPTX
DCUS17 : Docker networking deep dive
What's new in NGINX Plus R19
Service Discovery using etcd, Consul and Kubernetes
KONG-APIGateway.pptx
ITB2019 NGINX Overview and Technical Aspects - Kevin Jones
Ansible benelux meetup - Amsterdam 27-5-2015
Docker Enterprise Workshop - Technical
What’s New in NGINX Plus R16?
Load Balancing Applications with NGINX in a CoreOS Cluster
DSLing your System For Scalability Testing Using Gatling - Dublin Scala User ...
MesosCon - Be a microservices hero
NGINX Unit: Rebooting our Universal Web App Server
Workshop KrakYourNet2016 - Web applications hacking Ruby on Rails example
Sprint 17
NGINX: Basics and Best Practices EMEA
Introduction to CloudStack API
signalr
Load Balancing Applications on Kubernetes with NGINX
What_s_New_in_OpenShift_Container_Platform_4.6.pdf
Node.js to the rescue
DCUS17 : Docker networking deep dive
Ad

More from NGINX, Inc. (20)

PDF
【NGINXセミナー】 Ingressを使ってマイクロサービスの運用を楽にする方法
PDF
【NGINXセミナー】 NGINXのWAFとは?その使い方と設定方法 解説セミナー
PDF
【NGINXセミナー】API ゲートウェイとしてのNGINX Plus活用方法
PPTX
Get Hands-On with NGINX and QUIC+HTTP/3
PPTX
Managing Kubernetes Cost and Performance with NGINX & Kubecost
PDF
Manage Microservices Chaos and Complexity with Observability
PDF
Accelerate Microservices Deployments with Automation
PDF
Unit 2: Microservices Secrets Management 101
PDF
Unit 1: Apply the Twelve-Factor App to Microservices Architectures
PDF
NGINX基本セミナー(セキュリティ編)~NGINXでセキュアなプラットフォームを実現する方法!
PDF
Easily View, Manage, and Scale Your App Security with F5 NGINX
PDF
NGINXセミナー(基本編)~いまさら聞けないNGINXコンフィグなど基本がわかる!
PDF
Keep Ahead of Evolving Cyberattacks with OPSWAT and F5 NGINX
PPTX
Install and Configure NGINX Unit, the Universal Application, Web, and Proxy S...
PPTX
Protecting Apps from Hacks in Kubernetes with NGINX
PPTX
NGINX Kubernetes API
PPTX
Successfully Implement Your API Strategy with NGINX
PPTX
Installing and Configuring NGINX Open Source
PPTX
Shift Left for More Secure Apps with F5 NGINX
PPTX
How to Avoid the Top 5 NGINX Configuration Mistakes.pptx
【NGINXセミナー】 Ingressを使ってマイクロサービスの運用を楽にする方法
【NGINXセミナー】 NGINXのWAFとは?その使い方と設定方法 解説セミナー
【NGINXセミナー】API ゲートウェイとしてのNGINX Plus活用方法
Get Hands-On with NGINX and QUIC+HTTP/3
Managing Kubernetes Cost and Performance with NGINX & Kubecost
Manage Microservices Chaos and Complexity with Observability
Accelerate Microservices Deployments with Automation
Unit 2: Microservices Secrets Management 101
Unit 1: Apply the Twelve-Factor App to Microservices Architectures
NGINX基本セミナー(セキュリティ編)~NGINXでセキュアなプラットフォームを実現する方法!
Easily View, Manage, and Scale Your App Security with F5 NGINX
NGINXセミナー(基本編)~いまさら聞けないNGINXコンフィグなど基本がわかる!
Keep Ahead of Evolving Cyberattacks with OPSWAT and F5 NGINX
Install and Configure NGINX Unit, the Universal Application, Web, and Proxy S...
Protecting Apps from Hacks in Kubernetes with NGINX
NGINX Kubernetes API
Successfully Implement Your API Strategy with NGINX
Installing and Configuring NGINX Open Source
Shift Left for More Secure Apps with F5 NGINX
How to Avoid the Top 5 NGINX Configuration Mistakes.pptx

Recently uploaded (20)

PDF
“A New Era of 3D Sensing: Transforming Industries and Creating Opportunities,...
PDF
STKI Israel Market Study 2025 version august
PPTX
AI IN MARKETING- PRESENTED BY ANWAR KABIR 1st June 2025.pptx
PDF
The influence of sentiment analysis in enhancing early warning system model f...
PDF
Enhancing plagiarism detection using data pre-processing and machine learning...
PPT
Galois Field Theory of Risk: A Perspective, Protocol, and Mathematical Backgr...
PPTX
GROUP4NURSINGINFORMATICSREPORT-2 PRESENTATION
PPTX
Microsoft Excel 365/2024 Beginner's training
PDF
Taming the Chaos: How to Turn Unstructured Data into Decisions
PPTX
Build Your First AI Agent with UiPath.pptx
PPTX
2018-HIPAA-Renewal-Training for executives
PDF
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
PPTX
MicrosoftCybserSecurityReferenceArchitecture-April-2025.pptx
PDF
sustainability-14-14877-v2.pddhzftheheeeee
PDF
Comparative analysis of machine learning models for fake news detection in so...
PDF
Credit Without Borders: AI and Financial Inclusion in Bangladesh
PPTX
Modernising the Digital Integration Hub
PPTX
Chapter 5: Probability Theory and Statistics
PDF
NewMind AI Weekly Chronicles – August ’25 Week III
PPT
Module 1.ppt Iot fundamentals and Architecture
“A New Era of 3D Sensing: Transforming Industries and Creating Opportunities,...
STKI Israel Market Study 2025 version august
AI IN MARKETING- PRESENTED BY ANWAR KABIR 1st June 2025.pptx
The influence of sentiment analysis in enhancing early warning system model f...
Enhancing plagiarism detection using data pre-processing and machine learning...
Galois Field Theory of Risk: A Perspective, Protocol, and Mathematical Backgr...
GROUP4NURSINGINFORMATICSREPORT-2 PRESENTATION
Microsoft Excel 365/2024 Beginner's training
Taming the Chaos: How to Turn Unstructured Data into Decisions
Build Your First AI Agent with UiPath.pptx
2018-HIPAA-Renewal-Training for executives
ENT215_Completing-a-large-scale-migration-and-modernization-with-AWS.pdf
MicrosoftCybserSecurityReferenceArchitecture-April-2025.pptx
sustainability-14-14877-v2.pddhzftheheeeee
Comparative analysis of machine learning models for fake news detection in so...
Credit Without Borders: AI and Financial Inclusion in Bangladesh
Modernising the Digital Integration Hub
Chapter 5: Probability Theory and Statistics
NewMind AI Weekly Chronicles – August ’25 Week III
Module 1.ppt Iot fundamentals and Architecture

Session: A Reference Architecture for Running Modern APIs with NGINX Unit and NGINX Web Server

  • 1. NGINX Workshop Running Modern APIs with NGINX Unit and NGINX web server All Things Open 19-Oct-2020
  • 2. Today’s hosts Timo Stark 🇩🇪 • Product Management Engineer, NGINX • @linux_lenny Liam Crilly 🇬🇧 • Senior Director, Product Management, NGINX • @liamcrilly
  • 3. What we’re going to build API Client Internet / WAN API Gateway Backend APIs
  • 4. Agenda 1. Introducing NGINX 2. Running APIs with NGINX Unit 3. Q&A 4. Break (15 mins) 5. Deploying NGINX web server as an API gateway 6. Q&A
  • 5. 5 “... when I started NGINX, I focused on a very specific problem – how to handle more customers per a single server.” - Igor Sysoev, NGINX creator and founder
  • 6. Introducing NGINX 6 2004 • NGINX 0.1 2007 • “Viable” 2011 • NGINX, Inc. • NGINX 1.0 2013 • NGINX Plus R1 2018 • NGINX Unit 1.0 • Controller 1.0 2019 • Controller 2.0 (API mgmt.) • NGINX Plus R19 • Acquired by F5 Networks
  • 8. Agenda 1. Introducing NGINX 2. Running APIs with NGINX Unit 3. Break / Q&A 4. Deploying NGINX web server as an API gateway 5. Q&A
  • 9. What we’re going to build API Client Internet / WAN API Gateway Backend APIs
  • 10. What is NGINX Unit 10 “NGINX Unit is a polyglot app server, a reverse proxy, and a static file server, available for Unix-like systems”
  • 16. 16
  • 18. Installing NGINX Unit (simple) 18 CentOS / RHEL(*) • yum install unit unit-go unit- devel unit-php Ubuntu / Debian(*) • apt-get install unit unit-dev unit-go unit-php Docker • docker pull nginx/unit:1.20.0- full MacOS / MacBook • Docker
  • 19. Unit configuration 19 curl –s --unix-socket /var/run/control.unit.sock localhost 1 2 3 4 5 6 7 8 { "certificates": { ... }, "config": { ... } } TLS Certificates for the listeners General configuration object
  • 20. Unit config 20 curl –s --unix-socket /var/run/control.unit.sock localhost/config 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 20 22 "settings": { "http": { ... } }, "listeners": { ... }, "routes": [ { ... }, ], "applications": { ... }, "upstreams": { ... }, "access_log": "/var/log/access.log" } Instace wide settings Bind ip addr and port Control the unit- router Our applications Proxy upstreams access-logs
  • 21. Unit routes 1 21 curl –s --unix-socket /var/run/control.unit.sock localhost/config/routes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 20 22 "django": [ { "match": { "uri": "/static/*" }, "action": { "share": "/var/apphome/python/" } }, { "action": { "pass": "applications/django_project" } } ], name Routing pattern definition Action if pattern matches
  • 22. Unit routes 2 22 curl –s --unix-socket /var/run/control.unit.sock localhost/config/routes 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 20 22 23 "wordpress": [ { "match": { "uri": [ "*.php", "*.php/*", "/wp-admin/" ] }, "action": { "pass": "applications/wordpress/direct" } }, { "action": { "share": "/var/apphome/wordpress", "fallback": { "pass": "applications/wordpress/index" } } } ] name Routing pattern definition Action if pattern matches Fallback action with static file share
  • 23. $ curl –-unix-socket /var/run/unit.control.sock –-data-binary "@.unit.conf.json" http://localhost/config $ curl –-unix-socket /var/run/unit.control.sock –-data-binary "UpdatedSecret" http://localhost/config/applications/app/environment/APISEC
  • 24. Unit in docker 24 • Use the nginx/unit base images • Make use of the /docker-entrypoint-d features ◦ Apply initial configurtion ◦ Apply initial uploding of certificates for TLS encryption ◦ Run Shell-scripts
  • 25. What we have now Developers Machine Backend APIs AWS EC2 AWS Container Registry push pull API Gateway
  • 26. Agenda 1. Introducing NGINX 2. Running APIs with NGINX Unit 3. Break / Q&A 4. Deploying NGINX web server as an API gateway 5. Q&A
  • 27. Agenda 1. Introducing NGINX 2. Running APIs with NGINX Unit 3. Break / Q&A 4. Deploying NGINX web server as an API gateway 5. Q&A
  • 28. What we’re going to build API Client Internet / WAN API Gateway Backend APIs
  • 29. #1 40%“Most websites use NGINX” of NGINX deployments are as an API gateway Source: NGINX User survey 2017, 2018, 2019Source: Netcraft April 2019 Web Server Survey
  • 31. Installing NGINX (simple) 31 CentOS / RHEL • yum install nginx Ubuntu / Debian • apt-get install nginx Docker • docker pull nginx MacOS / MacBook • Homebrew • Docker
  • 32. NGINX Open Source Cycle Stable retired Mainline forked Mainline “bump” New stable Critical bugfix Stable 1.even.0 Mainline 1.odd.0 April • Mainline • New features • 8-12 releases per year • Stable • Critical bug fixes only • 1-2 releases per year
  • 33. Define our API gateway 33 • Create api_gateway.conf • $ mkdir /etc/nginx/conf.d/my_apis • $ nginx -s reload • $ curl localhost:8080 /etc/nginx/conf.d/api_gateway.conf 1 2 3 4 5 6 7 8 9 10 11 12 server { listen 8080; # TLS config goes here (for production) include conf.d/my_apis/*.conf; # Invalid resource location / { return 400; } }
  • 34. $ curl http://localhost:8080/ <html> <head><title>400 Bad Request</title></head> <body> <center><h1>400 Bad Request</h1></center> <hr><center>nginx/1.15.10</center> </body> </html>
  • 36. Define JSON error responses 36 /etc/nginx/conf.d/api_gateway.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 server { listen 8080; # TLS config goes here (for production use) include conf.d/my_apis/*.conf; # Invalid resource location / { return 400; } # Error responses default_type application/json; error_page 400 = @400; location @400 { return 400 '{"status":400,"message":"Bad request"}n'; } } • error_page to named location (@) • Download full error set ◦ github.com/lcrilly/ nginx-api-gateway
  • 37. Enable TLS 37 /etc/nginx/conf.d/api_gateway.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 server { listen 8080; # TLS config goes here (for production use) listen 443 ssl; ssl_certificate /etc/nginx/ssl/space.nginx.org.crt; ssl_certificate_key /etc/nginx/ssl/space.nginx.org.key; include conf.d/my_apis/*.conf; # Invalid resource location / { return 400; } • Can listen on plaintext and SSL/TLS ports simulateously ◦ But don’t!
  • 39. 🪐 Publish the Space API API Client Internet / WAN API Gateway Space API
  • 41. Define the backend servers 41 • Upstream servers (backends) • Multiple servers will be load balanced • Next step is to define the API itself /etc/nginx/conf.d/api_backends.conf 1 2 3 4 5 6 7 8 9 10 11 upstream planets-svc { server 172.31.46.145:8080; } upstream events-svc { server 172.31.46.145:8085; } upstream images-svc { server 172.31.46.145:8090; }
  • 42. Define the API 42 • Nested locations • Location (URI) matching ◦ Exact (=) ◦ Regex (~) ◦ Prefix ( ) • Policies can apply at any level /etc/nginx/conf.d/my_apis/space.conf 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 location /api/space/ { location = /api/space/planets { proxy_pass http://planets-svc; } location /api/space/planets/ { proxy_pass http://planets-svc; } location ~ ^/api/space/images/.+.(svg|png)$ { proxy_pass http://images-svc; } location /api/space/events { proxy_pass http://events-svc; } }
  • 44. Rate limiting 44 /etc/nginx/conf.d/api_gateway.conf 1 2 3 4 limit_req_zone $remote_addr zone=perip:1m rate=2r/s; server { listen 8080; • Rate limit is configured and monitored at a global level • Limit is applied where we want it ◦ Per API gateway ◦ Per API definition  ◦ Per URI/route /etc/nginx/conf.d/my_apis/space.conf 1 2 3 4 5 6 7 8 9 10 location /api/space/ { limit_req zone=perip nodelay; _ limit_req_status 429; _ location = /api/space/planets { proxy_pass http://planets-svc; } location /api/space/planets/ { proxy_pass http://planets-svc; }
  • 46. NGINX authentication options 46 API Gateway HTTP Basic Client Cert JWT • NGINX Plus API Key Custom Token • External API
  • 47. HTTP Basic authentication 47 • Other auth options replace auth_basic directives ◦ auth_jwt (JWT) ◦ auth_request ( API key) ◦ auth_request (custom) • Exception is client certs at server level ◦ ssl_client_certificate /etc/nginx/conf.d/my_apis/space.conf 1 2 3 4 5 6 7 8 9 10 location /api/space/ { auth_basic "Space API"; __ auth_basic_user_file conf.d/api_clients.htpasswd; _ limit_req zone=perip; limit_req_status 429; location = /api/space/planets { proxy_pass http://planets-svc; } $ cd /etc/nginx/conf.d $ wget http://files.liamcrilly.com/api_clients.htpasswd
  • 48. API key authentication (example) 48 • Requests must pass auth_request test • Internal location performs API key validation logic ◦ Returns validation status back to auth_request • Keys can be SHA-256 protected with njs /etc/nginx/conf.d/my_apis/space.conf 1 2 … 16 17 18 19 20 21 22 23 24 25 26 27 28 29 location /api/space/ { auth_request /_validate_apikey; … } location = /_validate_apikey { internal; if ($http_apikey = "") { return 401; # Unauthorized } if ($api_client_name = "") { return 403; # Forbidden } return 204; # OK (no content) } /etc/nginx/conf.d/apikey_clients.conf 1 2 3 4 5 map $http_apikey $api_client_name { default ""; "7B5zIqmRGXmrJTFmKa99vcit" "client_one"; "QzVV6y1EmQFbbxOfRCwyJs35" "client_two"; }
  • 50. HTTP method matching 50 • limit_except directive controls HTTP methods • Disable authentication for easier testing /etc/nginx/conf.d/my_apis/space.conf 1 2 3 4 5 6 7 8 9 10 … 19 20 21 22 23 location /api/space/ { auth_basic "Space API"; auth_basic_user_file conf.d/api_clients.htpasswd; limit_req zone=perip; limit_req_status 429; location = /api/space/planets { proxy_pass http://planets-svc; } location /api/space/events { limit_except GET POST { deny all; } _ proxy_pass http://events-svc; } }
  • 52. JSON request validation [1/2] 52 • Load JavaScript module ◦ nginx-module-njs • Use JSON.parse() to test request body for valid JSON /etc/nginx/nginx.conf 1 2 3 4 5 6 7 8 9 10 11 user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; load_module modules/ngx_http_js_module.so; _ events { worker_connections 1024; } /etc/nginx/conf.d/json_validation.js 1 2 3 4 5 6 7 8 9 10 11 12 13 export default { parseRequestBody }; function parseRequestBody(r) { try { if (r.variables.request_body) { JSON.parse(r.variables.request_body); } return r.variables.upstream; } catch (e) { r.error('JSON.parse exception'); return '127.0.0.1:10415'; // Address for error response } }
  • 53. JSON request validation [2/2] 53 • NGINX hates to buffer • Use mirror module to force early-reading of $request_body • Variable evaluation controls timing of JS code execution /etc/nginx/conf.d/api_gateway.conf 10 11 12 13 14 # Request body validation location /_get_request_body { internal; return 204; } /etc/nginx/conf.d/json_validation.conf 1 2 3 4 5 6 7 8 js_import conf.d/json_validation.js; js_set $json_validated json_validation.parseRequestBody; server { listen 127.0.0.1:10415; # This is the error response of json_validator() return 415; # Unsupported media type include conf.d/my_apis/errors_json.conf; } /etc/nginx/conf.d/my_apis/space.conf 8 9 10 11 12 13 location = /api/space/events { limit_except GET POST { deny all; } set $upstream events-svc; mirror /_get_request_body; # Force early-reading of request body proxy_pass http://$json_validated$request_uri; }
  • 54. How did we do? • Error handling • API definition • Rate limiting • Authentication • HTTP methods • JSON validation
  • 55. Agenda 1. Introducing NGINX 2. Running APIs with NGINX Unit 3. Break / Q&A 4. Deploying NGINX web server as an API gateway 5. Q&A
  • 56. Resources • NGINX Unit ◦ https://unit.nginx.org/ • Official NGINX open source downloads ◦ http://nginx.org/en/linux_packages.html • Configuration files and code samples ◦ https://github.com/nginx/unit-examples ◦ https://github.com/lcrilly/nginx-api-gateway • NGINX Plus developer license ◦ https://www.nginx.com/developer-license/ ◦ Code: ato2020workshop
  • 58. fin

Editor's Notes

  • #7: NGINX 1.0 and Unit 1.0 released 12th Apr (International Day of Human Space Flight – Yuri Gagarin) 2020 – let’s pretend it didn’t happen!
  • #11: *** ADD RELOAD COMMANDS *** Other error formats are available
  • #13: Let’s now take a look at the architecture for NGINX Unit This is how we built Unit for performance, security and consistency We’ll start at the top of this diagram And drill-in on the various processes *click*
  • #14: When Unit starts up we get the “main” process the “controller” process and the “router” process The controller process exposes an HTTP interface for API configuration By default it is a Unix socket but can also listen as a TCP port on the network API calls are handled by the controller process Configuration is analyzed by the controller and passed to the main process And then into the router process *click*
  • #15: The router is interesting There are several threads: a main thread and a number of workers Whereas configuration requests are handled by the controller process Client requests for applications are handled by the router process The router accepts client HTTP connections but only when you ask Unit to bind an application to a specific port do you enable that application Such changes do not reload the workers, but simply modify their configuration
  • #16: The router process transfers requests to the application processes We don’t include PHP, Python or Go with Unit That is, we don’t compile them in We use system-level interpreters – which means we can have several of them, all co-existing on the same instance. In this example we have PHP5 and PHP7 running different applications
  • #17: GO, however, is a different animal ;) Unlike PHP and Python, GO applications listen on HTTP ports directly GO provides a network-level web server as a builtin facility Therefore in order for a GO application to run within Unit we replace the ‘http’ listener with a ‘unit’ listener So without Unit it will listen directly With Unit it will not listen on a port, but communicate with the Unit router using shared memory But why would you run a GO application with Unit? This brings us back to the benefits of a consistent application stack. You have the same control and configuration for GO as you do for PHP and Python And so it will work the same way as the rest of your distributed application Greatly simplifying the deployment and DevOps workload if you use nodejs "http", then you need to proxy http over a socket connection, that has additional overhead Unit adds dynamic control to your "http" in nodejs with routing and etc...  all the features that we to add in the future, also it should be more scalable... lots of things in nodejs http are written in javascript, while Unit is in C the idea is that people will no more need in additional proxy layer in front of their nodejs apps
  • #20: *** ADD RELOAD COMMANDS *** Other error formats are available
  • #24: How to apply new Unit configuration
  • #34: We’re going to use port 8080 for all of the APIs – if that’s a conflict for you then choose another and map 8080 to it Single server{} benefits TLS footprint and use of keepalives This is the first config reload – make sure it’s working
  • #43: Nested locations not useful yet – we use them for policies Exact (=), regex (~) and prefix () matching
  • #49: Might also use an external auth server with proxy_pass to perform OAuth 2.0 token introspection (see blog)
  • #58: Resources