nginx ignition: managing nginx virtual hosts, SSL and streams from a browser
An user interface for the nginx web server, aimed at developers and enthusiasts that don't want to manage configuration files manually
At a glance
- What is it?
- nginx ignition is a browser-based interface for nginx that handles virtual hosts, SSL certificates, TCP/UDP streams and traffic statistics without manual configuration files. The project explicitly targets homelab and developer use, and the README states it is not aimed at enterprise or highly complex environments.
- Who is it for?
- Use nginx ignition for a homelab, a developer workstation, or a single-node server where ease of management outweighs the need for direct nginx directive control. The README states the project is not aimed at being enterprise-ready or feature-complete for highly complex environments, so treat that as a scope boundary rather than a shortfall.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 1 day ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 11, 2026, and from our analysis. They are not legal advice.
Editorial analysis
nginx ignition puts a web interface in front of nginx, with a stated homelab scope
Managing nginx by editing its configuration files is precise but unforgiving: a syntax error silences a virtual host, and adding a new route means knowing the right directive for every option. nginx ignition replaces that workflow with a browser interface at port 8090, where virtual hosts, routes, SSL certificates and stream proxies are fields and toggles rather than text.
The project is written in Go on the backend and React on the frontend, and it ships a custom-compiled nginx binary with modules not included in standard nginx distributions. It supports Docker, Docker Swarm, Tailscale, NetBird VPNs and TrueNAS as native integrations.
The README's Goals section sets a firm boundary: this project is not aimed at being enterprise-ready or feature-complete for highly complex environments. Anyone who needs directives the UI does not expose should manage configuration files directly. For anyone else, nginx ignition also offers a mode where it generates the configuration files without running nginx itself, useful when a separate process already owns the nginx service lifecycle.
Quick test via Docker runs the UI at port 8090 with SQLite in seconds
Testing nginx ignition before committing to an install requires one Docker command.
docker run -p 8090:8090 -p 80:80 dillmann/nginx-ignitionAfter a few seconds, the interface is at http://localhost:8090, and a setup wizard guides through creating the first user account. Port 8090 is the application UI; port 80 is where nginx listens for incoming traffic. Port 443 is not exposed in the quick-test command, so HTTPS termination is not available in this mode.
By default, an embedded SQLite database stores all configuration. SQLite is sufficient for exploring the interface and testing routes, but the README recommends PostgreSQL for production environments, with a link to the database configuration documentation. The database driver is set through environment variables, and the Docker image accepts the full list of configuration properties documented in docs/configuration-properties.md.
Docker Compose with PostgreSQL 18 uses seven environment variables and a 64-character JWT secret
The docker-compose.yml at the repository root is the recommended production setup. It defines a postgres service using the postgres:18-alpine image and an nginx-ignition service that waits for postgres to pass its health check before starting.
The nginx-ignition service reads its database and security configuration from environment variables.
environment:
NGINX_IGNITION_DATABASE_DRIVER: postgres
NGINX_IGNITION_DATABASE_HOST: postgres
NGINX_IGNITION_DATABASE_PORT: 5432
NGINX_IGNITION_DATABASE_NAME: nginx_ignition
NGINX_IGNITION_DATABASE_USERNAME: nginx_ignition
NGINX_IGNITION_DATABASE_PASSWORD: PlaceYourSuperSecretDatabasePasswordHere
NGINX_IGNITION_SECURITY_JWT_SECRET: PlaceYourSecretJwtPrivateKeyHereButRememberThatShouldHave64CharsThe placeholder for NGINX_IGNITION_SECURITY_JWT_SECRET is exactly 64 characters, and its text ends with RememberThatShouldHave64Chars. Both the application and postgres services are on a dedicated bridge network named nginx-ignition-network, and the application exposes ports 8090, 80 and 443. Health checks on both services poll every 5 seconds with a timeout of 5 seconds and three retries before declaring failure. The application health endpoint is at http://localhost:8090/api/health/liveness.
Native packages reach Linux distributions, Windows and macOS arm64; Intel Macs have no package
The releases page offers native packages for seven platforms. Linux distributions get architecture-specific packages: .deb for Debian and Ubuntu, .rpm for RedHat and Fedora, .apk for Alpine Linux, .pkg.tar.zst for Arch Linux, and .ipk for OpenWrt. All five Linux formats have both amd64 and arm64 variants. Windows ships as a ZIP archive for both amd64 and arm64.
MacOS is the exception. The packages table lists only arm64 for macOS, with no amd64 entry. The Makefile confirms this: the .backend-build target includes GOOS=darwin GOARCH=arm64 but no darwin/amd64 entry. A developer on an Intel Mac cannot install a native package; the Docker image is the only path for that hardware.
Check the platform list before choosing a native install on macOS. ARM-based Macs (Apple Silicon) are covered, and all common Linux server architectures are covered, but the gap in amd64 macOS support means Docker is the only installation path for Intel Mac users.
The Docker image recompiles nginx 1.31.6 from source with Lua, NJS, VTS and GeoIP2 modules
The Dockerfile uses nginx:1.31.6-alpine as its builder stage, then compiles a custom nginx binary from the nginx 1.31.6 source with additional dynamic modules. The compile step adds five modules not included in stock nginx: ngx_devel_kit (required for Lua support), lua-nginx-module, nginx-module-vts (virtual host traffic status), ngx_http_geoip2_module (GeoIP2 geolocation) and njs (NGINX JavaScript). Two Lua runtime libraries, lua-resty-core and lua-resty-lrucache, are cloned alongside.
Lua scripting in route configuration and the traffic statistics dashboard both depend on these custom modules. Without lua-nginx-module, custom Lua code in routes would not execute. Without nginx-module-vts, the traffic statistics dashboard would have no data to read. The compile flags also include --with-http_ssl_module, --with-http_v2_module and --with-stream, enabling HTTPS, HTTP/2 and TCP/UDP stream proxying at the nginx level.
The go.mod file puts the Go module under github.com/lucasdillmann/nginx-ignition and requires Go 1.27.1. It replaces several upstream dependencies, including netbirdio forks of dexidp/dex and pion/* libraries, which are the dependencies behind the NetBird VPN integration.
Routing includes gRPC upstreams, Lua and JavaScript hooks, SNI-based streams, and circuit breakers
Routes in nginx ignition cover more than standard HTTP proxying. gRPC and gRPCS upstreams are supported alongside regular HTTP targets, which matters for services that expose a gRPC API rather than a REST one. Routes can also deliver a static response, redirect a request, or serve files from a directory without forwarding to a backend at all.
Two scripting hooks are available per route: custom JavaScript code runs through the njs module, and custom Lua code runs through lua-nginx-module. Both require the Docker image, since those modules are not present in a standard nginx installation.
Streams extend routing to the transport layer. TCP, UDP and Unix socket streams can all be proxied, with SNI-based routing allowing a single port to forward traffic to different backends based on the TLS server name. Load balancing is available across stream upstreams, and circuit breakers are listed as a stream feature, limiting connections to a failing backend.
Load balancing also applies to HTTP upstreams through virtual host configuration. Caching configuration is available for content delivery, and all access and error logs include built-in automatic rotation per host.
SSL uses Let's Encrypt ACME, 2FA protects the admin UI, and ABAC controls per-host access
SSL certificate management covers three paths: Let's Encrypt via ACME, self-signed certificates, and certificates you supply. The ACME path handles certificate issuance and renewal automatically; the other two are for environments without outbound port 80 access or where an external CA is required.
The admin interface itself is protected by two-factor authentication. Per-host access can be restricted through attribute-based access control (ABAC) and access lists that combine basic HTTP authentication with source IP address checks. A virtual host with ABAC and access list settings can require both a valid credential and an allowed source IP before serving content.
The interface supports 11 languages: Brazilian Portuguese, English, Chinese (Simplified), German, French, Hindi, Spanish, Vietnamese, Russian, Bengali and Japanese. This multi-language support is labeled a beta feature in the README, which notes that translation issues are expected and asks users to raise issues on the repository if they find them.
For existing nginx setups, the flexible execution mode generates configuration files without taking over the nginx process, so a team that already manages nginx can use nginx ignition as a config file generator while keeping their current deployment process.
Editorial conclusion
Use nginx ignition for a homelab, a developer workstation, or a single-node server where ease of management outweighs the need for direct nginx directive control. The README states the project is not aimed at being enterprise-ready or feature-complete for highly complex environments, so treat that as a scope boundary rather than a shortfall. Production installs should replace the SQLite default with PostgreSQL and set NGINX_IGNITION_SECURITY_JWT_SECRET to 64 characters, as the docker-compose.yml placeholder demonstrates. Intel Mac users have no native package; the Makefile targets darwin/arm64 only, so Docker is the path on that hardware.
Frequently asked questions
How do I install nginx ignition?
The fastest path is Docker: run docker run -p 8090:8090 -p 80:80 dillmann/nginx-ignition and open http://localhost:8090 after a few seconds. For production, use the docker-compose.yml from the repository, which connects to PostgreSQL 18. Native packages for Linux, Windows and macOS arm64 are on the releases page.
Does nginx ignition support HTTPS and Let's Encrypt?
SSL certificate management supports Let's Encrypt via ACME, self-signed certificates, and custom certificates. The ACME option automates certificate issuance and renewal.
What database does nginx ignition use?
SQLite is embedded and used by default, requiring no extra setup. The README recommends PostgreSQL for production, and the docker-compose.yml shows the configuration using NGINX_IGNITION_DATABASE_DRIVER and related environment variables.
Can nginx ignition run on macOS?
Native packages are available for macOS arm64 only; there is no amd64 macOS package. Intel Mac users can run nginx ignition via the Docker image instead.
Is nginx ignition suitable for production use?
The README states the project is not aimed at being enterprise-ready or feature-complete for highly complex environments. It targets homelab and developer environments. For production, the README recommends PostgreSQL over the default SQLite database.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lucasdillmann-nginx-ignition)