nginx
NGINX is a robust, small, high performance web server and reverse proxy server. It is a good alternative to popular web servers like Apache and lighttpd.
Installation
Before immediately installing the www-servers/nginx package, first take a good look at the USE flags for NGINX.
Expanded USE flags
NGINX uses modules to enhance its features. To simplify the maintenance of this modular approach, the NGINX ebuild uses USE_EXPAND flags to denote which modules should be installed.
- HTTP related modules can be enabled through the NGINX_MODULES_HTTP variable
- Stream (generic TCP/UDP proxying) related modules can be enabled through the NGINX_MODULES_STREAM variable
- Mail (POP3/IMAP4/SMTP proxying) related modules can be enabled through the NGINX_MODULES_MAIL variable
These variables need to be set in /etc/portage/package.use, if it is a file, or in a file inside it, for example /etc/portage/package.use/nginx. The variables descriptions can be found in /var/db/repos/gentoo/profiles/desc/nginx_modules_http.desc , /var/db/repos/gentoo/profiles/desc/nginx_modules_stream.desc , and /var/db/repos/gentoo/profiles/desc/nginx_modules_mail.desc .
For example, to enable the fastcgi module:
/etc/portage/package.use/nginxwww-servers/nginxNGINX_MODULES_HTTP:fastcgi
USE flags
USE flags for www-servers/nginx Robust, small and high performance HTTP and reverse proxy server
+http
Enable core HTTP support
+http-cache
Enable HTTP cache support
+http2
Enable HTTP2 module support
+modules
Enable loadable module support
+pcre2
Enable support for pcre2
aio
Enable asynchronous I/O support
debug
Enable support for debugging log
http3
Enable HTTP3 module support
ktls
Enable Kernel TLS offload (kTLS)
libatomic
Use dev-libs/libatomic_ops instead of builtin atomic operations
mail
Enable POP3/IMAP4/SMTP mail proxy server
pcre
Add support for Perl Compatible Regular Expressions
pcre-jit
Enable JIT for pcre
rtmp
NGINX-based Media Streaming Server
selinux
!!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur
ssl
Enable HTTPS module for http. Enable SSL/TLS support for POP3/IMAP/SMTP for mail.
stream
Enable generic TCP/UDP proxying and load balancing
test
Enable dependencies and/or preparations necessary to run tests (usually controlled by FEATURES=test but can be toggled independently)
threads
Add threads support for various packages. Usually pthreads
vim-syntax
Pulls in related vim syntax scripts
Emerge
With the USE flags set, install www-servers/nginx :
root #emerge --ask www-servers/nginxInstallation verification
The default NGINX configuration defines an HTTP virtual server listening on loopback address but does not define a root directory. To test out the installation, use an existing directory or create a new root directory, for example /var/www/localhost/htdocs:
root #mkdir -p /var/www/localhost/htdocsThen, uncomment the root directive inside the server block:
/etc/nginx/nginx.confSetting the root directiveserver{ listen127.0.0.1; server_namelocalhost; # Substitute the directory below for the one you use. root/var/www/localhost/htdocs; }
You can copy a sample welcome page to the root directory. For example, if /var/www/localhost/htdocs was chosen, use the following command to copy the welcome page to the root:
root #cp /usr/share/nginx/index.html /var/www/localhost/htdocsThe NGINX package installs an init service script and a systemd unit allowing administrators to stop, start, or restart the service. If running OpenRC, issue the next command to start the NGINX service:
root #rc-service nginx startIf using systemd, use the following command to start NGINX:
root #systemctl start nginx.serviceTo verify that NGINX is properly running, point a web browser to http://localhost or use a command-line tool like curl:
user $curl http://localhostConfiguration
The NGINX configuration is specified in the /etc/nginx/nginx.conf file.
Single site access
The following example shows a single-site access, without dynamic capabilities (such as PHP).
/etc/nginx/nginx.confGentoo's default configurationusernginxnginx; worker_processesauto; events{ # NGINX refuses to start if the 'events' section is not present. Yet, # NGINX does not seem to care whether this section is non-empty. } http{ # Maximum hash table size is increased to accommodate for a large # mime.types file that is shipped on Gentoo. types_hash_max_size4096; include/etc/nginx/mime.types.nginx; sendfileon; server{ listen127.0.0.1; server_namelocalhost; # Substitute the directory below for the one you use. root/var/www/localhost/htdocs; } }
Multiple site access
It is possible to leverage the include directive to split the configuration in multiple files:
/etc/nginx/nginx.confMultisite configurationusernginxnginx; worker_processesauto; events{ # NGINX refuses to start if the 'events' section is not present. Yet, # NGINX does not seem to care whether this section is non-empty. } http{ # Maximum hash table size is increased to accommodate for a large # mime.types file that is shipped on Gentoo. types_hash_max_size4096; include/etc/nginx/mime.types.nginx; sendfileon; include/etc/nginx/conf.d/*.conf; }
/etc/nginx/conf.d/local.confSimple hostserver{ listen127.0.0.1; server_namelocalhost; root/var/www/localhost/htdocs; }
/etc/nginx/conf.d/local-ssl.confSimple SSL hostserver{ # Specifying port with no address. listen443ssl; server_namehost.tld; ssl_certificate/etc/ssl/nginx/host.tld.pem; ssl_certificate_key/etc/ssl/nginx/host.tld.key; }
PHP support
Add the following lines to the NGINX configuration to enable PHP support. In this example NGINX is exchanging information with the PHP process via a UNIX socket.
/etc/nginx/nginx.confEnabling PHP support# ... http{ # ... server{ # ... location~\.php${ # Test for non-existent scripts or throw a 404 error # Without this line, nginx will blindly send any request ending in .php to php-fpm try_files$uri=404; include/etc/nginx/fastcgi_params; fastcgi_passunix:/run/php-fpm.socket; } } }
To support this setup, PHP needs to be built with FastCGI Process Manager support (dev-lang/php ), which is handled through the fpm USE flag:
root #echo "dev-lang/php fpm" >> /etc/portage/package.use/phpRebuild PHP with the fpm USE flag enabled:
root #emerge --ask dev-lang/phpUsing UNIX socket communication is the preferred and recommended configuration
For PHP 7.0 and newer PHP versions use following configuration:
/etc/php/fpm-php8.2/fpm.d/www.confRunning PHP with UNIX socket supportlisten=/run/php-fpm.socket listen.owner=nginx
Set the timezone in the php-fpm php.ini file. Substitute the <PUT_TIMEZONE_HERE> text in the FileBox below with the appropriate timezone information:
/etc/php/fpm-php8.2/php.iniSetup timezone in php.inidate.timezone=<PUT_TIMEZONE_HERE>
Start the php-fpm daemon:
root #rc-service php-fpm startAdd php-fpm to the default runlevel:
root #rc-update add php-fpm defaultRestart nginx with changed configuration:
root #rc-service nginx restartAlternatively, for systemd:
root #systemctl enable php-fpm@8.2
root #systemctl start php-fpm@8.2
root #systemctl restart nginx.serviceIP address access list
The next example shows how to allow access to a particular URL (in this case /nginx_status) only to:
- certain hosts (e.g. 192.0.2.1 127.0.0.1)
- and IP networks (e.g. 198.51.100.0/24)
/etc/nginx/nginx.confEnabling and configuring an IP access lists for /nginx_status pagehttp{ server{ location/nginx_status{ stub_statuson; allow127.0.0.1/32; allow192.0.2.1/32; allow198.51.100.0/24; denyall; } } }
Basic authentication
NGINX allows limiting access to resources by validating the user name and password:
/etc/nginx/nginx.confEnabling and configuring user authentication for the / locationhttp{ server{ location/{ auth_basic"Authenticationfailed"; auth_basic_user_filedomain.htpasswd; } } }
The domain.htpasswd file can be generated using:
user $echo -n 'foo:' >> domain.htpasswdThis will create the domain.htpasswd file, containing a row for the user 'foo'.
The string with the user name should end with ':', this is the separator field between the user name and the password.
user $openssl passwd >> domain.htpasswdThis will add the password to the line for the user 'foo'. The password will be asked on the standard input. Once it's over, the file could be opened and will contain something like this:
/etc/nginx/domain.htpasswdContent of the domain.htpasswd file, for user foo with a ciphered passwordfoo:1ドル$lpC3de5Y$dnh6jegS1qlfZVo7rGExz/
The password is not in plain text, rather it is encrypted with OpenSSL.
Geolocation using GeoIP2
The GeoIP2 module makes use of GeoIP2 databases by Maxmind or similar. Using Maxmind is already supported in Gentoo through net-misc/geoipupdate . However, registration of an account is required in order to obtain a free license key and download the free database.
Downloading Maxmind GeoIP2 databases
Once an account is created, install and configure geoipupdate:
root #emerge --ask net-misc/geoipupdateEnter the account and license key:
/etc/GeoIP.confAdd your account infoAccountID YOURID LicenseKey YOURKEY EditionIDs GeoLite2-ASN GeoLite2-City GeoLite2-Country
After that, you'll need to download the databases:
root #geoipupdate
In order receive updates automatically in the future, add this command to a weekly cronjob or systemd timer.
Add GeoIP2 support to NGINX
To enable to modules and rebuild NGINX:
/etc/portage/package.use/nginxAdd the modules to NGINXwww-servers/nginx NGINX_MODULES_HTTP: geo geoip2
The geoip module only supports the GeoIP legacy database.
Rebuild NGINX with the third party modules enabled:
root #emerge --ask www-servers/nginxOnce NGINX has been rebuild, point NGINX to the databases and the GeoIP2 variables:
/etc/nginx/nginx.confPointing to the GeoIP2 databases and its valueshttp {
# ...
geoip2 /usr/share/GeoIP/GeoLite2-City.mmdb {
auto_reload 5m;
$geoip2_metadata_city_build metadata build_epoch;
$geoip2_data_city_name city names en;
$geoip2_data_city_geonameid city geoname_id;
$geoip2_data_continent_code continent code;
$geoip2_data_continent_geonameid continent geoname_id;
$geoip2_data_continent_name continent names en;
$geoip2_data_country_geonameid country geoname_id;
$geoip2_data_country_code iso_code;
$geoip2_data_country_name names en;
$geoip2_data_country_is_eu is_in_european_union;
$geoip2_data_location_accuracyradius location accuracy_radius;
$geoip2_data_location_latitude location latitude;
$geoip2_data_location_longitude location longitude;
$geoip2_data_location_metrocode location metro_code;
$geoip2_data_location_timezone location time_zone;
$geoip2_data_postal_code postal code;
$geoip2_data_rcountry_geonameid registered_country geoname_id;
$geoip2_data_rcountry_iso registered_country iso_code;
$geoip2_data_rcountry_name registered_country names en;
$geoip2_data_rcountry_is_eu registered_country is_in_european_union;
$geoip2_data_region_geonameid subdivisions 0 geoname_id;
$geoip2_data_region_iso subdivisions 0 iso_code;
$geoip2_data_region_name subdivisions 0 names en;
}
geoip2 /usr/share/GeoIP/GeoLite2-ASN.mmdb {
auto_reload 5m;
$geoip2_data_autonomous_system_number autonomous_system_number;
$geoip2_data_autonomous_system_organization autonomous_system_organization;
}
...
}
The auto_reload option will allow updating the database without restarting NGINX.
For the GeoIP2 values to show up in a PHP application, assign them as fastcgi_param values:
/etc/nginx/fastcgi.confAdd GeoIP2 support to PHP# ... fastcgi_param GEOIP2_CITY_BUILD_DATE $geoip2_metadata_city_build; fastcgi_param GEOIP2_CITY $geoip2_data_city_name; fastcgi_param GEOIP2_CITY_GEONAMEID $geoip2_data_city_geonameid; fastcgi_param GEOIP2_CONTINENT_CODE $geoip2_data_continent_code; fastcgi_param GEOIP2_CONTINENT_GEONAMEID $geoip2_data_continent_geonameid; fastcgi_param GEOIP2_CONTINENT_NAME $geoip2_data_continent_name; fastcgi_param GEOIP2_COUNTRY_GEONAMEID $geoip2_data_country_geonameid; fastcgi_param GEOIP2_COUNTRY_CODE $geoip2_data_country_code; fastcgi_param GEOIP2_COUNTRY_NAME $geoip2_data_country_name; fastcgi_param GEOIP2_COUNTRY_IN_EU $geoip2_data_country_is_eu; fastcgi_param GEOIP2_LOCATION_ACCURACY_RADIUS $geoip2_data_location_accuracyradius; fastcgi_param GEOIP2_LATITUDE $geoip2_data_location_latitude; fastcgi_param GEOIP2_LONGITUDE $geoip2_data_location_longitude; fastcgi_param GEOIP2_LOCATION_METROCODE $geoip2_data_location_metrocode; fastcgi_param GEOIP2_LOCATION_TIMEZONE $geoip2_data_location_timezone; fastcgi_param GEOIP2_POSTAL_CODE $geoip2_data_postal_code; fastcgi_param GEOIP2_REGISTERED_COUNTRY_GEONAMEID $geoip2_data_rcountry_geonameid; fastcgi_param GEOIP2_REGISTERED_COUNTRY_ISO $geoip2_data_rcountry_iso; fastcgi_param GEOIP2_REGISTERED_COUNTRY_NAME $geoip2_data_rcountry_name; fastcgi_param GEOIP2_REGISTERED_COUNTRY_IN_EU $geoip2_data_rcountry_is_eu; fastcgi_param GEOIP2_REGION_GEONAMEID $geoip2_data_region_geonameid; fastcgi_param GEOIP2_REGION $geoip2_data_region_iso; fastcgi_param GEOIP2_REGION_NAME $geoip2_data_region_name; fastcgi_param GEOIP2_ASN $geoip2_data_autonomous_system_number; fastcgi_param GEOIP2_ASN_ORG $geoip2_data_autonomous_system_organization;
Usage
Service control
OpenRC
Start NGINX web server:
root #rc-service nginx startStop NGINX web server:
root #rc-service nginx stopAdd NGINX to the default runlevel so that the service starts automatically on system reboot:
root #rc-update add nginx defaultReload NGINX configuration without dropping connections:
root #rc-service nginx reloadRestart the NGINX service:
root #rc-service nginx restartsystemd
Start NGINX web server:
root #systemctl start nginxStop NGINX web server:
root #systemctl stop nginxCheck the status of the service:
root #systemctl status nginxEnable service to start automatically on system reboot:
root #systemctl enable nginxReload NGINX configuration without dropping connections:
root #systemctl reload nginxRestart the NGINX service:
root #systemctl restart nginxTroubleshooting
In case of problems, the following commands can help troubleshoot the situation.
Validate configuration
Verify that the running NGINX configuration has no errors:
root #rc-service nginx configtestnginx | * Checking NGINX's configuration ... nginx |nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx |nginx: configuration file /etc/nginx/nginx.conf test is successful [ ok ]
Alternatively, if using systemd:
root #/usr/sbin/nginx -tnginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
By running nginx with the -t option, it will validate the configuration file without actually starting the nginx daemon. Use the -c option with the full path to the file to test configuration files in non-default locations. See nginx(8) for details.
Verify processes are running
Check if nginx processes are running:
user $ps aux | egrep 'nginx|PID'PID TTY STAT TIME COMMAND 26092 ? Ss 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf 26093 ? S 0:00 nginx: worker proces
Verify bound addresses and ports
Verify NGINX daemon is listening on the right TCP port (such as 80 for HTTP or 443 for HTTPS):
root #ss -tulpn | grep :80tcp LISTEN 0 0 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=6253,fd=52),("nginx",pid=6252,fd=52))
See also
- Apache — an efficient, extensible web server. It is one of the most popular web servers used the Internet.
- Lighttpd — a fast and lightweight web server.
External resources
- https://nginx.org/en/docs/beginners_guide.html - A nginx beginner's guide. Helpful for those who do not know much about nginx.
- https://github.com/nginxinc/nginx-wiki - The archived NGINX wiki.
- https://github.com/h5bp/server-configs-nginx - H5BP nginx config.
- https://gentoo.org/support/news-items/2025-07-05-nginx-packaging-changes.html