Install Tengine web server from source and packages, configure virtual hosts with SSL certificates, and optimize performance with dynamic upstream health checks and security hardening.
Prerequisites
- Root or sudo access
- Domain name pointing to your server
- At least 2GB RAM
- Basic Linux command line knowledge
What this solves
Tengine is a high-performance web server based on Nginx that adds advanced features like dynamic upstream management, health checks, and enhanced performance monitoring. This tutorial shows you how to install Tengine, configure virtual hosts with SSL certificates, and optimize it for production use with security hardening and performance tuning.
Step-by-step installation
Update system packages
Start by updating your package manager to ensure you get the latest versions and security patches.
sudo apt update && sudo apt upgrade -y
Install build dependencies
Install the required packages for compiling Tengine from source, including development tools and libraries.
sudo apt install -y build-essential libpcre3-dev zlib1g-dev libssl-dev libgeoip-dev curl wget
Create Tengine user
Create a dedicated system user for running Tengine with minimal privileges for security.
sudo useradd --system --home /var/cache/tengine --shell /sbin/nologin --comment "Tengine web server" --user-group tengine
Download and compile Tengine
Download the latest Tengine source code and compile it with essential modules including SSL support and dynamic upstream.
cd /tmp
wget http://tengine.taobao.org/download/tengine-3.1.0.tar.gz
tar -xzf tengine-3.1.0.tar.gz
cd tengine-3.1.0
./configure \
--prefix=/etc/tengine \
--sbin-path=/usr/sbin/tengine \
--modules-path=/usr/lib/tengine/modules \
--conf-path=/etc/tengine/tengine.conf \
--error-log-path=/var/log/tengine/error.log \
--http-log-path=/var/log/tengine/access.log \
--pid-path=/var/run/tengine.pid \
--lock-path=/var/run/tengine.lock \
--http-client-body-temp-path=/var/cache/tengine/client_temp \
--http-proxy-temp-path=/var/cache/tengine/proxy_temp \
--http-fastcgi-temp-path=/var/cache/tengine/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/tengine/uwsgi_temp \
--http-scgi-temp-path=/var/cache/tengine/scgi_temp \
--user=tengine \
--group=tengine \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_dav_module \
--with-http_flv_module \
--with-http_mp4_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_random_index_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_xslt_module \
--with-http_image_filter_module \
--with-http_geoip_module \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-stream_ssl_preread_module \
--with-stream_realip_module \
--with-stream_geoip_module \
--with-http_slice_module \
--with-file-aio \
--with-http_v2_module
make -j$(nproc)
sudo make install
Create directory structure
Set up the required directories with proper ownership and permissions for Tengine operation.
sudo mkdir -p /var/cache/tengine/{client_temp,proxy_temp,fastcgi_temp,uwsgi_temp,scgi_temp}
sudo mkdir -p /var/log/tengine
sudo mkdir -p /etc/tengine/conf.d
sudo mkdir -p /var/www/html
sudo chown -R tengine:tengine /var/cache/tengine
sudo chown -R tengine:tengine /var/log/tengine
sudo chown -R tengine:tengine /var/www/html
sudo chmod -R 755 /var/cache/tengine
sudo chmod -R 755 /var/log/tengine
Create main configuration file
Configure Tengine with optimized settings for performance, security, and dynamic upstream management.
user tengine;
worker_processes auto;
error_log /var/log/tengine/error.log warn;
pid /var/run/tengine.pid;
events {
worker_connections 2048;
use epoll;
multi_accept on;
}
http {
include /etc/tengine/mime.types;
default_type application/octet-stream;
# 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"';
access_log /var/log/tengine/access.log main;
# Performance optimizations
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 64M;
server_tokens off;
# Gzip compression
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/json
application/javascript
application/xml+rss
application/atom+xml
image/svg+xml;
# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
# Rate limiting
limit_req_zone $binary_remote_addr zone=login:10m rate=10r/m;
limit_req_zone $binary_remote_addr zone=global:10m rate=100r/s;
# Include virtual host configurations
include /etc/tengine/conf.d/*.conf;
# Default server block
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
# Security location blocks
location ~ /\. {
deny all;
}
location ~* \.(log|conf)$ {
deny all;
}
}
}
Create MIME types configuration
Set up proper MIME type mappings for different file extensions to ensure correct content serving.
types {
text/html html htm shtml;
text/css css;
text/xml xml;
image/gif gif;
image/jpeg jpeg jpg;
image/png png;
image/svg+xml svg svgz;
image/webp webp;
application/javascript js;
application/json json;
application/pdf pdf;
application/zip zip;
font/woff woff;
font/woff2 woff2;
}
Create systemd service
Set up a systemd service file for managing Tengine with automatic startup and proper service management.
[Unit]
Description=Tengine HTTP server
Documentation=http://tengine.taobao.org/
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/var/run/tengine.pid
ExecStartPre=/usr/sbin/tengine -t
ExecStart=/usr/sbin/tengine
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=mixed
KillSignal=SIGQUIT
TimeoutStopSec=5
PrivateTmp=true
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
Create default index page
Create a simple test page to verify Tengine installation and basic functionality.
Tengine Server
Welcome to Tengine!
Tengine web server is successfully installed and running.
Server: example.com
Enable and start Tengine
Enable the Tengine service to start automatically on boot and start it immediately.
sudo systemctl daemon-reload
sudo systemctl enable tengine
sudo systemctl start tengine
Configure SSL certificates and virtual hosts
Install Certbot for SSL certificates
Install Certbot to automatically obtain and manage SSL certificates from Let's Encrypt.
sudo apt install -y certbot python3-certbot-nginx
Create virtual host configuration
Configure a virtual host with SSL support and security headers for your domain.
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.php;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozTLS:10m;
ssl_session_tickets off;
# SSL Security
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# HSTS
add_header Strict-Transport-Security "max-age=63072000" always;
# Security headers
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Referrer-Policy "strict-origin-when-cross-origin";
# Rate limiting
limit_req zone=global burst=20 nodelay;
location / {
try_files $uri $uri/ =404;
}
# Static file caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js|woff|woff2)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Security location blocks
location ~ /\. {
deny all;
}
location ~* \.(log|conf|bak)$ {
deny all;
}
# Health check endpoint
location /health {
access_log off;
return 200 "healthy\n";
add_header Content-Type text/plain;
}
}
Create website directory
Create the directory structure for your website with proper ownership and permissions.
sudo mkdir -p /var/www/example.com
sudo chown -R tengine:tengine /var/www/example.com
sudo chmod -R 755 /var/www/example.com
Obtain SSL certificate
Use Certbot to obtain an SSL certificate for your domain. Replace example.com with your actual domain.
sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com --email admin@example.com --agree-tos --no-eff-email
Configure dynamic upstream and health checks
Configure upstream backend servers
Set up dynamic upstream configuration with health checks for load balancing and high availability.
upstream backend_servers {
# Dynamic upstream with health checks
server 203.0.113.10:8080 max_fails=3 fail_timeout=30s;
server 203.0.113.11:8080 max_fails=3 fail_timeout=30s backup;
# Load balancing method
least_conn;
# Health check configuration
check interval=3000 rise=2 fall=3 timeout=1000 type=http;
check_http_send "GET /health HTTP/1.0\r\n\r\n";
check_http_expect_alive http_2xx http_3xx;
}
Upstream status page
server {
listen 8080;
server_name localhost;
location /upstream_status {
check_status;
access_log off;
allow 127.0.0.1;
allow 203.0.113.0/24;
deny all;
}
}
Configure load balancer virtual host
Create a virtual host configuration that uses the upstream servers with advanced features.
server {
listen 80;
listen [::]:80;
server_name api.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name api.example.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/api.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/api.example.com/privkey.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:MozTLS:10m;
ssl_session_tickets off;
# Real IP configuration
real_ip_header X-Forwarded-For;
set_real_ip_from 203.0.113.0/24;
location / {
proxy_pass http://backend_servers;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
# Timeouts
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
# Buffer settings
proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 8 4k;
}
# Health check endpoint
location /lb-health {
access_log off;
return 200 "load balancer healthy\n";
add_header Content-Type text/plain;
}
}
Test configuration and reload
Test the Tengine configuration for syntax errors and reload to apply changes.
sudo tengine -t
sudo systemctl reload tengine
Performance optimization
Configure worker process optimization
Optimize worker processes and connections based on your server's CPU cores and expected load. Learn more about Linux process monitoring in our process monitoring guide.
# Check CPU cores
nproc
Check current limits
ulimit -n
# Update these values in the main configuration
worker_processes auto; # or number of CPU cores
worker_rlimit_nofile 65535;
events {
worker_connections 4096; # Increase based on ulimit
use epoll;
multi_accept on;
accept_mutex off;
}
Configure caching and compression
Set up advanced caching and compression for better performance.
# Add to http block in main config or include this file
Browser cache
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, no-transform";
add_header Vary Accept-Encoding;
access_log off;
}
Gzip compression settings
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied any;
gzip_comp_level 6;
gzip_types
text/plain
text/css
text/xml
text/javascript
text/x-component
application/javascript
application/json
application/xml
application/rss+xml
application/atom+xml
font/truetype
font/opentype
application/vnd.ms-fontobject
image/svg+xml;
File handle cache
open_file_cache max=200000 inactive=20s;
open_file_cache_valid 30s;
open_file_cache_min_uses 2;
open_file_cache_errors on;
Configure system-level optimizations
Optimize system limits for high-performance web serving. For more system optimization, check our kernel parameters guide.
# Add these lines to increase file descriptor limits
tengine soft nofile 65535
tengine hard nofile 65535
www-data soft nofile 65535
www-data hard nofile 65535
# Network performance optimizations
net.core.somaxconn = 65535
net.core.netdev_max_backlog = 5000
net.core.rmem_default = 262144
net.core.rmem_max = 16777216
net.core.wmem_default = 262144
net.core.wmem_max = 16777216
net.ipv4.tcp_rmem = 4096 65536 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_max_tw_buckets = 400000
net.ipv4.tcp_no_metrics_save = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_keepalive_time = 300
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_keepalive_intvl = 15
sudo sysctl -p /etc/sysctl.d/99-tengine.conf
Security hardening
Configure firewall rules
Set up firewall rules to allow only necessary traffic and protect your Tengine server.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 'Nginx Full'
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
Configure security headers and rate limiting
Implement additional security measures including rate limiting and security headers.
# Rate limiting zones
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
limit_req_zone $binary_remote_addr zone=api:10m rate=100r/s;
limit_req_zone $binary_remote_addr zone=global:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;
Security configuration to include in server blocks
Rate limiting
limit_req zone=global burst=20 nodelay;
limit_conn conn_limit_per_ip 20;
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;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
Hide server information
server_tokens off;
more_set_headers "Server: Web Server";
Deny access to sensitive files
location ~ /\.(ht|git|svn) {
deny all;
return 404;
}
location ~* \.(log|conf|sql|bak|backup|old)$ {
deny all;
return 404;
}
Set up automated certificate renewal
Configure automatic SSL certificate renewal to maintain security without manual intervention.
sudo systemctl enable certbot.timer
sudo systemctl start certbot.timer
sudo systemctl status certbot.timer
#!/bin/bash
/bin/systemctl reload tengine
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/tengine-reload.sh
Verify your setup
# Check Tengine status
sudo systemctl status tengine
Verify configuration
sudo tengine -t
Check version and modules
tengine -V
Test HTTP and HTTPS
curl -I http://localhost
curl -I https://example.com
Check upstream status (if configured)
curl http://localhost:8080/upstream_status
Verify SSL certificate
openssl s_client -connect example.com:443 -servername example.com < /dev/null
Check listening ports
sudo netstat -tlnp | grep tengine
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| Tengine fails to start | Configuration syntax error | sudo tengine -t to check syntax |
| Permission denied errors | Incorrect file ownership | sudo chown -R tengine:tengine /var/www/ |
| SSL certificate errors | Invalid certificate path | Check paths in /etc/letsencrypt/live/ |
| 502 Bad Gateway | Upstream servers down | Check upstream status and backend servers |
| High memory usage | Worker process misconfiguration | Adjust worker_connections and buffer sizes |
| Cannot bind to port 80/443 | Port already in use | sudo netstat -tlnp | grep :80 to find process |
| Compilation fails | Missing dependencies | Install build-essential and development libraries |
Next steps
- Configure NGINX reverse proxy with SSL termination for comparison with Nginx
- Set up NGINX web application firewall with ModSecurity for additional security
- Configure Tengine clustering and high availability
- Monitor Tengine performance with Prometheus and Grafana
- Configure Tengine Lua scripting for advanced logic
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'
# Configuration
TENGINE_VERSION="3.1.0"
DOMAIN="${1:-}"
TENGINE_USER="tengine"
# Usage function
usage() {
echo "Usage: $0 [domain_name]"
echo "Example: $0 example.com"
exit 1
}
# Error handling
cleanup() {
echo -e "${RED}Installation failed. Cleaning up...${NC}"
systemctl stop tengine 2>/dev/null || true
userdel $TENGINE_USER 2>/dev/null || true
rm -rf /tmp/tengine-* /etc/tengine /var/cache/tengine /var/log/tengine
exit 1
}
trap cleanup ERR
# Detect OS and package manager
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update && apt upgrade -y"
PKG_INSTALL="apt install -y"
BUILD_DEPS="build-essential libpcre3-dev zlib1g-dev libssl-dev libgeoip-dev curl wget libxslt1-dev libgd-dev"
;;
almalinux|rocky|centos|rhel|ol|fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf update -y"
PKG_INSTALL="dnf install -y"
BUILD_DEPS="gcc gcc-c++ make pcre-devel zlib-devel openssl-devel GeoIP-devel curl wget libxslt-devel gd-devel"
if ! command -v dnf >/dev/null 2>&1; then
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
fi
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum update -y"
PKG_INSTALL="yum install -y"
BUILD_DEPS="gcc gcc-c++ make pcre-devel zlib-devel openssl-devel GeoIP-devel curl wget libxslt-devel gd-devel"
;;
*)
echo -e "${RED}Unsupported distribution: $ID${NC}"
exit 1
;;
esac
else
echo -e "${RED}Cannot detect OS. /etc/os-release not found${NC}"
exit 1
fi
# Check if running as root
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}This script must be run as root${NC}"
exit 1
fi
echo -e "${GREEN}Installing Tengine Web Server on $PRETTY_NAME${NC}"
# Step 1: Update system
echo -e "${YELLOW}[1/8] Updating system packages...${NC}"
eval $PKG_UPDATE
# Step 2: Install dependencies
echo -e "${YELLOW}[2/8] Installing build dependencies...${NC}"
if [[ "$ID" =~ ^(almalinux|rocky|centos|rhel|ol|fedora|amzn)$ ]]; then
$PKG_INSTALL epel-release 2>/dev/null || true
if [[ "$ID" =~ ^(almalinux|rocky|centos|rhel|ol)$ ]]; then
$PKG_INSTALL "Development Tools" || $PKG_INSTALL @"Development Tools"
fi
fi
$PKG_INSTALL $BUILD_DEPS
# Step 3: Create tengine user
echo -e "${YELLOW}[3/8] Creating tengine user...${NC}"
if ! id "$TENGINE_USER" >/dev/null 2>&1; then
useradd --system --home /var/cache/tengine --shell /sbin/nologin --comment "Tengine web server" --user-group $TENGINE_USER
fi
# Step 4: Download and compile Tengine
echo -e "${YELLOW}[4/8] Downloading and compiling Tengine...${NC}"
cd /tmp
if [ ! -f "tengine-${TENGINE_VERSION}.tar.gz" ]; then
wget "http://tengine.taobao.org/download/tengine-${TENGINE_VERSION}.tar.gz"
fi
tar -xzf "tengine-${TENGINE_VERSION}.tar.gz"
cd "tengine-${TENGINE_VERSION}"
./configure \
--prefix=/etc/tengine \
--sbin-path=/usr/sbin/tengine \
--modules-path=/usr/lib/tengine/modules \
--conf-path=/etc/tengine/tengine.conf \
--error-log-path=/var/log/tengine/error.log \
--http-log-path=/var/log/tengine/access.log \
--pid-path=/var/run/tengine.pid \
--lock-path=/var/run/tengine.lock \
--http-client-body-temp-path=/var/cache/tengine/client_temp \
--http-proxy-temp-path=/var/cache/tengine/proxy_temp \
--http-fastcgi-temp-path=/var/cache/tengine/fastcgi_temp \
--http-uwsgi-temp-path=/var/cache/tengine/uwsgi_temp \
--http-scgi-temp-path=/var/cache/tengine/scgi_temp \
--user=$TENGINE_USER \
--group=$TENGINE_USER \
--with-http_ssl_module \
--with-http_realip_module \
--with-http_addition_module \
--with-http_sub_module \
--with-http_gunzip_module \
--with-http_gzip_static_module \
--with-http_secure_link_module \
--with-http_stub_status_module \
--with-http_auth_request_module \
--with-http_image_filter_module \
--with-http_geoip_module \
--with-threads \
--with-stream \
--with-stream_ssl_module \
--with-file-aio \
--with-http_v2_module
make -j$(nproc)
make install
# Step 5: Create directory structure
echo -e "${YELLOW}[5/8] Setting up directory structure...${NC}"
mkdir -p /var/cache/tengine/{client_temp,proxy_temp,fastcgi_temp,uwsgi_temp,scgi_temp}
mkdir -p /var/log/tengine
mkdir -p /etc/tengine/conf.d
mkdir -p /var/www/html
mkdir -p /etc/ssl/tengine
chown -R $TENGINE_USER:$TENGINE_USER /var/cache/tengine
chown -R $TENGINE_USER:$TENGINE_USER /var/log/tengine
chown -R $TENGINE_USER:$TENGINE_USER /var/www/html
chmod -R 755 /var/cache/tengine
chmod -R 755 /var/log/tengine
chmod 755 /var/www/html
# Step 6: Create main configuration
echo -e "${YELLOW}[6/8] Creating configuration files...${NC}"
cat > /etc/tengine/tengine.conf << 'EOF'
user tengine;
worker_processes auto;
error_log /var/log/tengine/error.log warn;
pid /var/run/tengine.pid;
events {
worker_connections 2048;
use epoll;
multi_accept on;
}
http {
include /etc/tengine/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/tengine/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
server_tokens off;
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml;
include /etc/tengine/conf.d/*.conf;
}
EOF
# Create default server configuration
cat > /etc/tengine/conf.d/default.conf << EOF
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
root /var/www/html;
index index.html index.htm;
location / {
try_files \$uri \$uri/ =404;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /var/www/html;
}
}
EOF
# Create default index page
cat > /var/www/html/index.html << EOF
<!DOCTYPE html>
<html>
<head>
<title>Tengine Server</title>
</head>
<body>
<h1>Welcome to Tengine!</h1>
<p>If you can see this page, the Tengine web server is successfully installed and working.</p>
</body>
</html>
EOF
chown $TENGINE_USER:$TENGINE_USER /var/www/html/index.html
# Step 7: Create systemd service
echo -e "${YELLOW}[7/8] Creating systemd service...${NC}"
cat > /etc/systemd/system/tengine.service << EOF
[Unit]
Description=The tengine HTTP and reverse proxy server
Documentation=http://tengine.taobao.org/
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/var/run/tengine.pid
ExecStartPre=/usr/sbin/tengine -t
ExecStart=/usr/sbin/tengine
ExecReload=/bin/kill -s HUP \$MAINPID
KillMode=mixed
KillSignal=SIGTERM
PrivateTmp=true
User=$TENGINE_USER
Group=$TENGINE_USER
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable tengine
# Configure firewall if active
if systemctl is-active --quiet firewalld; then
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
elif systemctl is-active --quiet ufw; then
ufw allow 80/tcp
ufw allow 443/tcp
fi
# Set SELinux contexts for RHEL-based systems
if command -v setsebool >/dev/null 2>&1; then
setsebool -P httpd_can_network_connect 1 2>/dev/null || true
semanage fcontext -a -t httpd_exec_t "/usr/sbin/tengine" 2>/dev/null || true
restorecon -R /etc/tengine /var/log/tengine /var/cache/tengine /usr/sbin/tengine 2>/dev/null || true
fi
# Step 8: Start and verify
echo -e "${YELLOW}[8/8] Starting Tengine and verifying installation...${NC}"
systemctl start tengine
# Verification
sleep 2
if systemctl is-active --quiet tengine; then
echo -e "${GREEN}✓ Tengine is running successfully${NC}"
else
echo -e "${RED}✗ Tengine failed to start${NC}"
exit 1
fi
if /usr/sbin/tengine -t >/dev/null 2>&1; then
echo -e "${GREEN}✓ Configuration syntax is valid${NC}"
else
echo -e "${RED}✗ Configuration syntax error${NC}"
exit 1
fi
# Display final information
echo -e "${GREEN}
=== Tengine Installation Complete ===
• Configuration: /etc/tengine/tengine.conf
• Virtual hosts: /etc/tengine/conf.d/
• Document root: /var/www/html
• Logs: /var/log/tengine/
• Service: systemctl {start|stop|restart|status} tengine
Next steps:
1. Configure your virtual hosts in /etc/tengine/conf.d/
2. Set up SSL certificates
3. Customize your configuration as needed
${NC}"
Review the script before running. Execute with: bash install.sh