Set up OpenResty as a high-performance web server and API gateway with embedded Lua scripting capabilities, SSL certificates, and advanced caching optimization for production workloads.
Prerequisites
- Root or sudo access
- At least 2GB RAM
- Basic understanding of web servers
What this solves
OpenResty transforms NGINX into a powerful application platform by embedding LuaJIT, enabling dynamic content generation, API gateway functionality, and real-time request processing. This tutorial configures OpenResty for production use with SSL certificates, performance optimizations, and Lua scripting for custom logic that would typically require separate application servers.
Step-by-step installation
Add OpenResty repository
Install the official OpenResty repository to get the latest stable version with all required modules.
sudo apt update
wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" | sudo tee /etc/apt/sources.list.d/openresty.list
sudo apt update
Install OpenResty
Install OpenResty with essential modules for Lua scripting, SSL support, and performance optimization.
sudo apt install -y openresty openresty-opm openresty-restydoc
Create directory structure
Set up proper directory structure for OpenResty configuration, Lua scripts, and SSL certificates.
sudo mkdir -p /etc/openresty/conf.d
sudo mkdir -p /etc/openresty/lua
sudo mkdir -p /etc/openresty/ssl
sudo mkdir -p /var/log/openresty
sudo mkdir -p /var/cache/openresty
Configure main OpenResty settings
Create the main configuration file with performance optimizations and Lua integration enabled.
user www-data;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
error_log /var/log/openresty/error.log warn;
pid /var/run/openresty.pid;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
http {
include /usr/local/openresty/nginx/conf/mime.types;
default_type application/octet-stream;
# Lua package path
lua_package_path "/etc/openresty/lua/?.lua;;";
lua_code_cache on;
# Performance optimizations
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/javascript application/xml+rss
application/json application/xml;
# Security headers
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
# Rate limiting
limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone $binary_remote_addr zone=web:10m rate=5r/s;
# Logging format
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for" '
'$request_time $upstream_response_time';
access_log /var/log/openresty/access.log main;
# Cache zones
proxy_cache_path /var/cache/openresty levels=1:2 keys_zone=web_cache:10m max_size=1g inactive=60m;
include /etc/openresty/conf.d/*.conf;
}
Generate SSL certificate
Create a self-signed SSL certificate for development or prepare directory for production certificates.
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/openresty/ssl/server.key \
-out /etc/openresty/ssl/server.crt \
-subj "/C=US/ST=State/L=City/O=Organization/CN=example.com"
Create Lua utility library
Set up a common Lua library for shared functions and utilities across your applications.
local _M = {}
-- JSON response helper
function _M.json_response(data, status)
status = status or 200
ngx.status = status
ngx.header.content_type = "application/json"
ngx.say(require("cjson").encode(data))
ngx.exit(status)
end
-- Input validation
function _M.validate_required_fields(data, required_fields)
for _, field in ipairs(required_fields) do
if not data[field] or data[field] == "" then
return false, "Missing required field: " .. field
end
end
return true
end
-- Rate limiting helper
function _M.check_rate_limit(key, limit, window)
local dict = ngx.shared.rate_limit
local current = dict:get(key) or 0
if current >= limit then
return false
end
local ok, err = dict:incr(key, 1, 0, window)
if not ok then
ngx.log(ngx.ERR, "Rate limit error: ", err)
return false
end
return true
end
-- Database connection helper
function _M.get_redis_connection()
local redis = require "resty.redis"
local red = redis:new()
red:set_timeouts(1000, 1000, 1000)
local ok, err = red:connect("127.0.0.1", 6379)
if not ok then
ngx.log(ngx.ERR, "Redis connection failed: ", err)
return nil
end
return red
end
return _M
Configure virtual host with Lua integration
Create a virtual host configuration that demonstrates Lua scripting for API endpoints and dynamic content.
server {
listen 80;
listen 443 ssl http2;
server_name example.com www.example.com;
# SSL configuration
ssl_certificate /etc/openresty/ssl/server.crt;
ssl_certificate_key /etc/openresty/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# HSTS header
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
# Document root
root /var/www/html;
index index.html index.htm;
# Rate limiting for web pages
limit_req zone=web burst=20 nodelay;
# Static file caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# API endpoint with Lua
location /api/ {
limit_req zone=api burst=10 nodelay;
# CORS headers for API
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
# Handle preflight requests
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "Content-Type, Authorization";
add_header Content-Length 0;
return 204;
}
access_by_lua_block {
local utils = require("utils")
-- API key validation
local api_key = ngx.var.http_x_api_key
if not api_key then
utils.json_response({error = "API key required"}, 401)
end
-- Rate limiting per API key
local limit_key = "api:" .. api_key
if not utils.check_rate_limit(limit_key, 100, 3600) then
utils.json_response({error = "Rate limit exceeded"}, 429)
end
}
location = /api/health {
content_by_lua_block {
local utils = require("utils")
local response = {
status = "ok",
timestamp = ngx.time(),
server = ngx.var.hostname
}
utils.json_response(response)
}
}
location = /api/users {
content_by_lua_block {
local utils = require("utils")
local cjson = require("cjson")
if ngx.var.request_method == "GET" then
-- Simulate user data retrieval
local users = {
{id = 1, name = "John Doe", email = "john@example.com"},
{id = 2, name = "Jane Smith", email = "jane@example.com"}
}
utils.json_response({data = users})
elseif ngx.var.request_method == "POST" then
-- Handle user creation
ngx.req.read_body()
local body = ngx.req.get_body_data()
if not body then
utils.json_response({error = "Request body required"}, 400)
end
local ok, data = pcall(cjson.decode, body)
if not ok then
utils.json_response({error = "Invalid JSON"}, 400)
end
local valid, err = utils.validate_required_fields(data, {"name", "email"})
if not valid then
utils.json_response({error = err}, 400)
end
-- Simulate user creation
local new_user = {
id = math.random(1000, 9999),
name = data.name,
email = data.email,
created_at = os.date("%Y-%m-%d %H:%M:%S")
}
utils.json_response({data = new_user}, 201)
else
utils.json_response({error = "Method not allowed"}, 405)
end
}
}
}
# Dynamic content with caching
location /dynamic/ {
proxy_cache web_cache;
proxy_cache_valid 200 5m;
proxy_cache_key "$request_uri$is_args$args";
content_by_lua_block {
local utils = require("utils")
-- Generate dynamic content
local content = {
message = "Hello from OpenResty Lua!",
timestamp = os.date("%Y-%m-%d %H:%M:%S"),
request_id = ngx.var.request_id,
client_ip = ngx.var.remote_addr
}
ngx.header.content_type = "text/html"
ngx.say("Dynamic Content ")
ngx.say("" .. content.message .. "
")
ngx.say("Generated at: " .. content.timestamp .. "
")
ngx.say("Request ID: " .. content.request_id .. "
")
ngx.say("Your IP: " .. content.client_ip .. "
")
ngx.say("")
}
}
# Main location
location / {
try_files $uri $uri/ =404;
}
}
Create sample HTML page
Set up a basic HTML page to test the web server functionality.
sudo mkdir -p /var/www/html
sudo tee /var/www/html/index.html > /dev/null <<'EOF'
OpenResty with Lua
OpenResty with Lua Scripting
Your OpenResty server is running successfully with Lua integration!
Available Endpoints
API Health Check
GET /api/health
Returns server status and timestamp
Users API
GET /api/users - List all users
POST /api/users - Create new user
Requires X-API-Key header
Dynamic Content
GET /dynamic/
Generates dynamic HTML content with caching
EOF
Set proper permissions
Configure correct ownership and permissions for OpenResty files and directories.
sudo chown -R www-data:www-data /var/www/html
sudo chown -R www-data:www-data /var/log/openresty
sudo chown -R www-data:www-data /var/cache/openresty
sudo chmod 755 /var/www/html
sudo chmod 644 /var/www/html/index.html
sudo chmod 750 /etc/openresty
sudo chmod 640 /etc/openresty/nginx.conf
sudo chmod 600 /etc/openresty/ssl/server.key
sudo chmod 644 /etc/openresty/ssl/server.crt
Create systemd service
Set up a systemd service file for proper OpenResty management and auto-start on boot.
[Unit]
Description=OpenResty HTTP Server
After=network.target remote-fs.target nss-lookup.target
Wants=network.target
[Service]
Type=forking
PIDFile=/var/run/openresty.pid
ExecStartPre=/usr/local/openresty/bin/openresty -t -c /etc/openresty/nginx.conf
ExecStart=/usr/local/openresty/bin/openresty -c /etc/openresty/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
Restart=on-failure
RestartSec=5
User=www-data
Group=www-data
[Install]
WantedBy=multi-user.target
Enable and start OpenResty
Start the OpenResty service and enable it to start automatically on system boot.
sudo systemctl daemon-reload
sudo systemctl enable openresty
sudo systemctl start openresty
Configure firewall
Open HTTP and HTTPS ports in the firewall to allow web traffic.
sudo ufw allow 'Nginx Full'
sudo ufw enable
Performance optimization
Configure kernel parameters
Optimize kernel settings for high-performance web serving and connection handling.
# Network optimizations
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 12582912 16777216
net.ipv4.tcp_wmem = 4096 12582912 16777216
net.core.netdev_max_backlog = 5000
net.ipv4.tcp_congestion_control = bbr
net.ipv4.tcp_slow_start_after_idle = 0
File handling
fs.file-max = 2097152
Memory management
vm.swappiness = 10
sudo sysctl -p /etc/sysctl.d/99-openresty.conf
Optimize systemd limits
Increase system limits for the OpenResty service to handle more concurrent connections.
[Service]
LimitNOFILE=65535
LimitNPROC=4096
LimitCORE=infinity
sudo mkdir -p /etc/systemd/system/openresty.service.d
sudo systemctl daemon-reload
sudo systemctl restart openresty
Set up logging and monitoring
Configure log rotation
Set up automatic log rotation to prevent disk space issues and maintain log history.
/var/log/openresty/*.log {
daily
missingok
rotate 52
compress
delaycompress
notifempty
create 640 www-data www-data
sharedscripts
postrotate
if [ -f /var/run/openresty.pid ]; then
kill -USR1 cat /var/run/openresty.pid
fi
endscript
}
Create monitoring script
Set up a basic monitoring script to check OpenResty status and performance metrics.
#!/bin/bash
OpenResty monitoring script
LOGFILE="/var/log/openresty/monitor.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
echo "[$TIMESTAMP] Starting OpenResty health check" >> $LOGFILE
Check if OpenResty is running
if ! systemctl is-active --quiet openresty; then
echo "[$TIMESTAMP] ERROR: OpenResty is not running" >> $LOGFILE
systemctl restart openresty
exit 1
fi
Check HTTP response
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" http://localhost/)
if [ "$HTTP_STATUS" != "200" ]; then
echo "[$TIMESTAMP] ERROR: HTTP check failed with status $HTTP_STATUS" >> $LOGFILE
fi
Check HTTPS response
HTTPS_STATUS=$(curl -s -k -o /dev/null -w "%{http_code}" https://localhost/)
if [ "$HTTPS_STATUS" != "200" ]; then
echo "[$TIMESTAMP] ERROR: HTTPS check failed with status $HTTPS_STATUS" >> $LOGFILE
fi
Check API endpoint
API_STATUS=$(curl -s -H "X-API-Key: test123" -o /dev/null -w "%{http_code}" http://localhost/api/health)
if [ "$API_STATUS" != "200" ]; then
echo "[$TIMESTAMP] ERROR: API health check failed with status $API_STATUS" >> $LOGFILE
fi
echo "[$TIMESTAMP] Health check completed" >> $LOGFILE
sudo chmod 755 /usr/local/bin/openresty-monitor.sh
Schedule monitoring with cron
Set up automated monitoring to run every 5 minutes and alert on issues.
sudo crontab -e
/5 * /usr/local/bin/openresty-monitor.sh
Verify your setup
# Check OpenResty status
sudo systemctl status openresty
Test configuration syntax
sudo /usr/local/openresty/bin/openresty -t -c /etc/openresty/nginx.conf
Test HTTP response
curl -I http://localhost/
Test HTTPS response
curl -k -I https://localhost/
Test API endpoint
curl -H "X-API-Key: test123" http://localhost/api/health
Test dynamic content
curl http://localhost/dynamic/
Check logs
sudo tail -f /var/log/openresty/access.log
sudo tail -f /var/log/openresty/error.log
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Service fails to start | Configuration syntax error | sudo /usr/local/openresty/bin/openresty -t -c /etc/openresty/nginx.conf |
| API returns 401 errors | Missing X-API-Key header | Add -H "X-API-Key: your-key" to curl requests |
| Lua script errors | Syntax error in Lua code | Check error log: sudo tail /var/log/openresty/error.log |
| SSL certificate warnings | Self-signed certificate | Use -k flag with curl or install proper SSL certificate |
| Permission denied errors | Incorrect file ownership | sudo chown -R www-data:www-data /var/www/html |
| High memory usage | Lua code cache disabled | Ensure lua_code_cache on; in production |
Next steps
- Setup nginx reverse proxy with SSL certificates and security hardening for load balancing
- Install and configure Redis 7 with clustering and security hardening for session storage
- Configure OpenResty with PostgreSQL connection pooling for database integration
- Implement OpenResty JWT authentication with OAuth2 integration
- Optimize Linux system performance with kernel parameters and system tuning for better server performance
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# OpenResty Installation and Configuration Script
# Production-quality installer for OpenResty with Lua scripting support
# Colors for output
readonly RED='\033[0;31m'
readonly GREEN='\033[0;32m'
readonly YELLOW='\033[1;33m'
readonly NC='\033[0m' # No Color
# Global variables
DOMAIN=${1:-"example.com"}
TOTAL_STEPS=8
# Cleanup function for rollback
cleanup() {
echo -e "${RED}Installation failed. Cleaning up...${NC}"
systemctl stop openresty 2>/dev/null || true
case "$PKG_MGR" in
apt) apt-get remove -y openresty openresty-opm openresty-restydoc 2>/dev/null || true ;;
dnf|yum) $PKG_MGR remove -y openresty openresty-opm openresty-restydoc 2>/dev/null || true ;;
esac
rm -rf /etc/openresty /var/log/openresty /var/cache/openresty
}
trap cleanup ERR
# Usage message
usage() {
echo "Usage: $0 [domain_name]"
echo "Example: $0 mysite.com"
exit 1
}
# Validate domain format
if [[ ! "$DOMAIN" =~ ^[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]] && [[ "$DOMAIN" != "example.com" ]]; then
echo -e "${RED}Error: Invalid domain format${NC}"
usage
fi
# Check if running as root or with sudo
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root or with sudo${NC}"
exit 1
fi
echo -e "${GREEN}OpenResty Installation Starting...${NC}"
echo -e "${YELLOW}Domain: $DOMAIN${NC}"
# Auto-detect distribution
echo "[1/$TOTAL_STEPS] Detecting system..."
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_INSTALL="apt install -y"
PKG_UPDATE="apt update"
WEBUSER="www-data"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_INSTALL="dnf install -y"
PKG_UPDATE="dnf update -y"
WEBUSER="nginx"
# Fallback to yum for older systems
if ! command -v dnf >/dev/null 2>&1; then
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
fi
;;
amzn)
PKG_MGR="yum"
PKG_INSTALL="yum install -y"
PKG_UPDATE="yum update -y"
WEBUSER="nginx"
;;
*)
echo -e "${RED}Unsupported distribution: $ID${NC}"
exit 1
;;
esac
else
echo -e "${RED}Cannot detect distribution${NC}"
exit 1
fi
echo -e "${GREEN}Detected: $PRETTY_NAME (Package manager: $PKG_MGR)${NC}"
# Update system packages
echo "[2/$TOTAL_STEPS] Updating system packages..."
$PKG_UPDATE
# Install prerequisites
echo "[3/$TOTAL_STEPS] Installing prerequisites..."
case "$PKG_MGR" in
apt)
$PKG_INSTALL wget gnupg2 lsb-release ca-certificates
;;
dnf|yum)
$PKG_INSTALL wget ca-certificates
;;
esac
# Add OpenResty repository
echo "[4/$TOTAL_STEPS] Adding OpenResty repository..."
case "$PKG_MGR" in
apt)
wget -qO - https://openresty.org/package/pubkey.gpg | apt-key add -
echo "deb http://openresty.org/package/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/openresty.list
apt update
;;
dnf|yum)
wget -O /etc/yum.repos.d/openresty.repo https://openresty.org/package/rhel/openresty.repo
;;
esac
# Install OpenResty
echo "[5/$TOTAL_STEPS] Installing OpenResty..."
$PKG_INSTALL openresty openresty-opm openresty-restydoc
# Create directory structure
echo "[6/$TOTAL_STEPS] Creating directory structure..."
mkdir -p /etc/openresty/{conf.d,lua,ssl}
mkdir -p /var/log/openresty
mkdir -p /var/cache/openresty
# Set proper permissions
chown -R root:root /etc/openresty
chown -R $WEBUSER:$WEBUSER /var/log/openresty /var/cache/openresty
chmod 755 /etc/openresty/{conf.d,lua,ssl}
chmod 755 /var/log/openresty /var/cache/openresty
# Create main configuration
echo "[7/$TOTAL_STEPS] Creating configuration files..."
cat > /etc/openresty/nginx.conf << EOF
user $WEBUSER;
worker_processes auto;
worker_cpu_affinity auto;
worker_rlimit_nofile 65535;
error_log /var/log/openresty/error.log warn;
pid /var/run/openresty.pid;
events {
worker_connections 4096;
use epoll;
multi_accept on;
}
http {
include /usr/local/openresty/nginx/conf/mime.types;
default_type application/octet-stream;
# Lua package path
lua_package_path "/etc/openresty/lua/?.lua;;";
lua_code_cache on;
# Performance optimizations
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
keepalive_requests 1000;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_comp_level 6;
gzip_types text/plain text/css text/xml text/javascript
application/javascript application/xml+rss
application/json application/xml;
# Security headers
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy strict-origin-when-cross-origin always;
# Rate limiting
limit_req_zone \$binary_remote_addr zone=api:10m rate=10r/s;
limit_req_zone \$binary_remote_addr zone=web:10m rate=5r/s;
# Logging format
log_format main '\$remote_addr - \$remote_user [\$time_local] "\$request" '
'\$status \$body_bytes_sent "\$http_referer" '
'"\$http_user_agent" "\$http_x_forwarded_for" '
'\$request_time \$upstream_response_time';
access_log /var/log/openresty/access.log main;
# Cache zones
proxy_cache_path /var/cache/openresty levels=1:2 keys_zone=web_cache:10m max_size=1g inactive=60m;
include /etc/openresty/conf.d/*.conf;
}
EOF
# Generate SSL certificate
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout /etc/openresty/ssl/server.key \
-out /etc/openresty/ssl/server.crt \
-subj "/C=US/ST=State/L=City/O=Organization/CN=$DOMAIN" 2>/dev/null
chmod 600 /etc/openresty/ssl/server.key
chmod 644 /etc/openresty/ssl/server.crt
# Create Lua utility library
cat > /etc/openresty/lua/utils.lua << 'EOF'
local _M = {}
-- JSON response helper
function _M.json_response(data, status)
status = status or 200
ngx.status = status
ngx.header["Content-Type"] = "application/json"
ngx.say(require("cjson").encode(data))
ngx.exit(status)
end
-- Rate limiting check
function _M.check_rate_limit(zone, burst)
burst = burst or 5
local delay, err = ngx.var["limit_req_status"]
if delay and delay ~= "" then
if tonumber(delay) > 0 then
ngx.sleep(delay)
end
end
end
return _M
EOF
# Create default site configuration
cat > /etc/openresty/conf.d/default.conf << EOF
server {
listen 80;
listen [::]:80;
server_name $DOMAIN;
return 301 https://\$server_name\$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name $DOMAIN;
ssl_certificate /etc/openresty/ssl/server.crt;
ssl_certificate_key /etc/openresty/ssl/server.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
root /var/www/html;
index index.html;
# Rate limiting
limit_req zone=web burst=10 nodelay;
# Lua hello world endpoint
location /api/hello {
content_by_lua_block {
local utils = require "utils"
utils.json_response({
message = "Hello from OpenResty + Lua!",
timestamp = ngx.time(),
server = "OpenResty/" .. ngx.var.nginx_version
})
}
}
location / {
try_files \$uri \$uri/ =404;
}
}
EOF
# Create web root and sample page
mkdir -p /var/www/html
cat > /var/www/html/index.html << EOF
<!DOCTYPE html>
<html>
<head>
<title>OpenResty Server</title>
</head>
<body>
<h1>OpenResty is running!</h1>
<p>Server: $DOMAIN</p>
<p><a href="/api/hello">Test Lua API endpoint</a></p>
</body>
</html>
EOF
chown -R $WEBUSER:$WEBUSER /var/www/html
chmod 755 /var/www/html
chmod 644 /var/www/html/index.html
# Configure and start services
echo "[8/$TOTAL_STEPS] Starting OpenResty service..."
systemctl enable openresty
systemctl start openresty
# Configure firewall if present
if command -v ufw >/dev/null 2>&1; then
ufw allow 80/tcp
ufw allow 443/tcp
elif command -v firewall-cmd >/dev/null 2>&1; then
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
fi
# Final verification
echo -e "${GREEN}Verifying installation...${NC}"
if systemctl is-active --quiet openresty; then
echo -e "${GREEN}✓ OpenResty service is running${NC}"
else
echo -e "${RED}✗ OpenResty service failed to start${NC}"
exit 1
fi
if curl -s -k https://localhost/api/hello | grep -q "Hello from OpenResty"; then
echo -e "${GREEN}✓ Lua API endpoint is working${NC}"
else
echo -e "${YELLOW}! Lua API endpoint test failed (service may still be starting)${NC}"
fi
echo -e "${GREEN}OpenResty installation completed successfully!${NC}"
echo -e "${YELLOW}Configuration files:${NC}"
echo " Main config: /etc/openresty/nginx.conf"
echo " Site config: /etc/openresty/conf.d/default.conf"
echo " Lua scripts: /etc/openresty/lua/"
echo " SSL certs: /etc/openresty/ssl/"
echo -e "${YELLOW}Test URLs:${NC}"
echo " HTTP: http://$DOMAIN"
echo " HTTPS: https://$DOMAIN"
echo " API: https://$DOMAIN/api/hello"
echo -e "${YELLOW}Logs:${NC}"
echo " Error log: /var/log/openresty/error.log"
echo " Access log: /var/log/openresty/access.log"
Review the script before running. Execute with: bash install.sh