A lightweight web-based dashboard for managing Nginx — built with FastAPI and Jinja2 templates, styled with Tailwind CSS.
| Page | Description |
|---|---|
| Dashboard | Live stats — active connections, requests/s, backend health, uptime |
| Virtual Hosts | View, toggle, and add Nginx server blocks |
| Upstreams | Manage upstream pools and individual backend health |
| Config Editor | Edit nginx.conf directly in the browser with line numbers |
- Auto-refreshing dashboard stats every 5 seconds
- Reload Nginx from the sidebar or topbar
- Toast notifications for all actions
- Dark UI built with Tailwind CSS
nginx-management/
├── app.py # FastAPI app factory — mounts static, registers routers
├── main.py # Uvicorn entrypoint (python main.py)
├── requirements.txt
├── .env.example
├── core/
│ ├── config.py # Settings via pydantic-settings (reads .env)
│ ├── models/
│ │ ├── server.py # Server Pydantic model
│ │ └── upstream.py # Upstream / Backend Pydantic models
│ ├── routers/
│ │ ├── pages.py # HTML page routes (/, /servers, /upstreams, /config)
│ │ └── api.py # JSON API routes (/api/*)
│ └── services/
│ ├── nginx.py # Nginx subprocess service (reload, test, read/write config)
│ └── store.py # In-memory data store (swap for DB when ready)
├── templates/
│ ├── base.html # Sidebar layout shell
│ ├── index.html # Dashboard
│ ├── servers.html # Virtual hosts
│ ├── upstreams.html # Upstream pools
│ └── config.html # Config editor
├── static/
│ ├── css/style.css
│ └── js/app.js
└── deploy/
├── deploy.sh # Install / update script
├── nginx-management.service # systemd unit file
└── nginx-management.conf # Nginx reverse proxy config
- Python 3.10+
# Clone the repository
git clone https://github.com/pphatdev/nginx-management.git
cd nginx-management
# Create and activate a virtual environment (recommended)
python -m venv .venv
# Windows
.venv\Scripts\activate
# macOS / Linux
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txtpython main.pyThen open http://localhost:9991 in your browser.
The server starts with hot-reload enabled by default (reload=True).
| Method | Path | Description |
|---|---|---|
GET |
/api/stats |
Current Nginx stats |
GET |
/api/servers |
List all virtual hosts |
POST |
/api/servers/{id}/toggle |
Toggle server active/inactive |
GET |
/api/upstreams |
List all upstream pools |
POST |
/api/config/save |
Save nginx.conf content |
POST |
/api/nginx/reload |
Trigger Nginx reload |
Interactive API docs are available at http://localhost:8000/docs.
| Package | Version | Purpose |
|---|---|---|
fastapi |
0.111.0 | Web framework |
uvicorn |
0.29.0 | ASGI server |
jinja2 |
3.1.4 | HTML templating |
python-multipart |
0.0.26 | Form data parsing |
Production deployment uses Gunicorn + Uvicorn workers behind Nginx, managed by systemd.
deploy/
├── deploy.sh # Install / update script
├── nginx-management.service # systemd unit file
├── nginx-management.conf # Nginx reverse proxy config
└── nginx-management-sudoers # sudoers drop-in (installed by deploy.sh)
# On the target server (Ubuntu 22.04+)
git clone https://github.com/pphatdev/nginx-management.git /var/www/nginx-management
cd /var/www/nginx-management
# Run the install script (requires root).
# --user defaults to www-data; pass --user=USERNAME to use a different account.
sudo bash deploy/deploy.sh --install
# or with an explicit user:
sudo bash deploy/deploy.sh --install --user=myappNote: The specified user must already exist on the system. If it doesn't, the script will exit with an error before making any changes. Create the user first with
sudo useradd --system --no-create-home myapp.
The script will:
- Install
python3,python3-venv,nginx, andufw - Create a virtualenv and install dependencies
- Copy
.env.example→.env(edit before starting) - Generate the systemd unit from the template, substituting the chosen user and install path
- Install the narrowly-scoped sudoers drop-in (see Permission model below)
- Install and enable the Nginx site config
The dashboard runs as an unprivileged user but needs to validate and reload
Nginx config (which typically requires root). deploy.sh installs a
narrowly-scoped sudoers drop-in that grants only the minimum commands:
# /etc/sudoers.d/nginx-management (generated by deploy.sh)
www-data ALL=(root) NOPASSWD: \
/usr/sbin/nginx -t, \
/usr/sbin/nginx -s reload, \
/usr/bin/tee /etc/nginx/nginx.conf
The application activates these elevated calls when NGINX_USE_SUDO=true is
set in .env (the default in .env.example). In development (NGINX_USE_SUDO
unset or false) commands run without sudo and config writes are skipped
gracefully if the file is not present.
Edit deploy/nginx-management.conf and replace example.com with your domain, then reload Nginx:
sudo nginx -t && sudo systemctl reload nginxsudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d your-domain.comcd /var/www/nginx-management
sudo bash deploy/deploy.sh --updateVerify the Nginx listener on 9991:
systemctl status nginx-management
curl -I http://127.0.0.1:9991
sudo nginx -tIf your FastAPI upstream listens on a different internal port (for example 8000), verify that separately from the Nginx listener.
journalctl -u nginx-management -f
sudo tail -n 100 /var/log/nginx/error.log
sudo ss -tulpn | grep -E '(:80|:443|:9991)'MIT — see LICENSE for details.