Void Linux handles services differently from most distributions. Instead of systemd, it uses runit, which means enabling and managing Nginx follows a different pattern than what you’re used to on Debian or RHEL. Once you get the hang of it, runit is actually simpler and faster to work with.
This guide walks through a full Nginx setup on Void Linux, from installation through PHP-FPM integration and virtual host configuration. If you prefer Apache, check out the LAMP stack on Void Linux guide instead.
Current as of March 2026. Tested on Void Linux (glibc) with Nginx 1.28.3 and PHP-FPM 8.4.7
Prerequisites
- Void Linux (glibc, x86_64) with a working internet connection
- Root access or a user with sudo privileges
- Tested versions: Nginx 1.28.3, PHP-FPM 8.4.7
Step 1: Update the System
Start by syncing the XBPS repository index and upgrading all installed packages. Void Linux uses XBPS as its package manager, which is lightweight and fast.
sudo xbps-install -Su
If the package manager itself gets updated, XBPS will ask you to run the command again. Just rerun it until no more updates are pending.
Step 2: Install Nginx
Install the Nginx package from the Void repositories:
sudo xbps-install -y nginx
Confirm the installed version:
nginx -v
The output should show version 1.28.3 or newer:
nginx version: nginx/1.28.3
Void Linux uses runit instead of systemd. To enable a service, you create a symlink from /etc/sv/ into /var/service/. Runit picks it up automatically within a few seconds.
sudo ln -s /etc/sv/nginx /var/service/nginx
Verify that Nginx is running:
sudo sv status nginx
You should see output confirming the service is up with a PID:
run: nginx: (pid 1842) 5s
Step 3: Configure Nginx
Void Linux ships Nginx with a minimal default config. Replace it with a production-ready configuration that includes proper worker settings, gzip compression, and a server block pointing to a custom document root.
Open the main configuration file:
sudo vi /etc/nginx/nginx.conf
Replace the contents with the following configuration:
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /run/nginx.pid;
events {
worker_connections 1024;
multi_accept on;
}
http {
include /etc/nginx/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"';
access_log /var/log/nginx/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_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
include /etc/nginx/conf.d/*.conf;
server {
listen 80 default_server;
server_name _;
root /srv/www/nginx;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
}
Void Linux does not create a default document root for Nginx, so you need to create it manually:
sudo mkdir -p /srv/www/nginx
Also create the conf.d directory for virtual host configs and the log directory:
sudo mkdir -p /etc/nginx/conf.d
sudo mkdir -p /var/log/nginx
Test the configuration for syntax errors:
sudo nginx -t
A valid config produces:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Reload Nginx to apply the new configuration:
sudo sv reload nginx
Step 4: Test the Default Page
Create a simple HTML page in the document root to confirm Nginx is serving files correctly.
echo '<!DOCTYPE html><html><head><title>Nginx on Void Linux</title></head><body><h1>Nginx is working on Void Linux</h1></body></html>' | sudo tee /srv/www/nginx/index.html
Test it with curl:
curl -s http://localhost
The response should contain your test page HTML:
<!DOCTYPE html><html><head><title>Nginx on Void Linux</title></head><body><h1>Nginx is working on Void Linux</h1></body></html>
If you see the HTML output, Nginx is serving content from /srv/www/nginx as expected.
Step 5: Set Up PHP-FPM
Most web applications (WordPress, MediaWiki, Nextcloud) require PHP. On Void Linux, PHP-FPM runs as a separate service that Nginx forwards requests to. For a similar setup on Debian, see the PHP 8.4 on Debian guide.
Install PHP-FPM along with commonly needed extensions:
sudo xbps-install -y php-fpm php-mysql php-gd php-intl
PHP-FPM 8.4 on Void Linux listens on 127.0.0.1:9000 by default and runs under the _phpfpm user and group. No changes to the pool configuration are needed for a standard setup.
Enable the PHP-FPM service with runit:
sudo ln -s /etc/sv/php-fpm8.4 /var/service/php-fpm8.4
Check that the service is running:
sudo sv status php-fpm8.4
Expected output:
run: php-fpm8.4: (pid 2156) 3s
Now configure Nginx to pass PHP requests to PHP-FPM. Open the main config file and add a location block for PHP inside the server block:
sudo vi /etc/nginx/nginx.conf
Add the following location block inside the server { } section, after the existing location / block:
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
Also update the index directive in the server block to include index.php:
index index.php index.html index.htm;
Test the config and reload:
sudo nginx -t && sudo sv reload nginx
Create a PHP info page to verify the integration works:
echo '<?php phpinfo(); ?>' | sudo tee /srv/www/nginx/info.php
Test it:
curl -s http://localhost/info.php | head -5
You should see HTML output containing PHP version information. If you get a blank page or “File not found”, double check that SCRIPT_FILENAME uses $document_root and that /srv/www/nginx/info.php exists.
Remove the info page once you’ve confirmed PHP works. Leaving it exposed is a security risk:
sudo rm /srv/www/nginx/info.php
Step 6: Configure Virtual Hosts
To serve multiple websites from the same Nginx instance, use separate server blocks. The main nginx.conf already includes /etc/nginx/conf.d/*.conf, so each virtual host gets its own file in that directory.
Create a virtual host config for a sample domain:
sudo vi /etc/nginx/conf.d/example.com.conf
Add the following server block:
server {
listen 80;
server_name example.com www.example.com;
root /srv/www/example.com;
index index.php index.html;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~* \.(css|js|jpg|jpeg|png|gif|ico|svg|woff|woff2)$ {
expires 30d;
add_header Cache-Control "public, no-transform";
}
}
Create the document root for this virtual host:
sudo mkdir -p /srv/www/example.com
For additional domains, repeat the process: create a new .conf file in /etc/nginx/conf.d/ with the appropriate server_name and root directives. Each site stays isolated in its own config file, which makes maintenance straightforward.
Test and reload after adding any new virtual host:
sudo nginx -t && sudo sv reload nginx
Step 7: Enable Gzip Compression
The configuration from Step 3 already includes gzip settings. If you skipped that step or want to tune compression separately, here is the recommended gzip block to place inside the http { } section of /etc/nginx/nginx.conf:
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 5;
gzip_min_length 256;
gzip_types
text/plain
text/css
application/json
application/javascript
text/xml
application/xml
application/xml+rss
text/javascript
image/svg+xml
application/x-font-ttf
font/opentype;
A few notes on these settings. gzip_comp_level 5 provides a good balance between CPU usage and compression ratio. Going higher than 6 gives diminishing returns. gzip_min_length 256 skips tiny responses where compression overhead isn’t worth it. The gzip_vary directive tells caches to store both compressed and uncompressed versions.
Verify compression is active after reloading:
curl -sI -H "Accept-Encoding: gzip" http://localhost | grep -i content-encoding
If gzip is working, the response header will include:
Content-Encoding: gzip
Nginx Commands Quick Reference
Void Linux uses sv instead of systemctl for service management. Here are the most common Nginx operations:
| Action | Command |
|---|---|
| Test configuration | sudo nginx -t |
| Reload (graceful) | sudo sv reload nginx |
| Restart | sudo sv restart nginx |
| Stop | sudo sv stop nginx |
| Start | sudo sv start nginx |
| Check status | sudo sv status nginx |
| Show version | nginx -v |
| Show compiled modules | nginx -V 2>&1 | tr ' ' '\n' | grep module |
Always run nginx -t before reloading. A failed reload on a syntax error will keep the old config running, but it’s better to catch mistakes before they hit the service.
Nginx vs Apache on Void Linux
Both web servers are available in the Void repositories. The choice depends on your workload and familiarity. Here’s how they compare on Void specifically:
| Item | Nginx | Apache (httpd) |
|---|---|---|
| Package name | nginx | apache |
| Config path | /etc/nginx/nginx.conf | /etc/apache/httpd.conf |
| Default docroot | None (create manually) | /srv/www/htdocs |
| PHP integration | FastCGI via PHP-FPM (port 9000) | mod_php or PHP-FPM via proxy |
| Runit service name | nginx | apache |
| Concurrency model | Event-driven, async | Prefork or event MPM |
| .htaccess support | No | Yes |
| Static file performance | Excellent | Good |
| Reverse proxy | Built-in, high performance | Requires mod_proxy |
Nginx is the better choice for reverse proxying, serving static content, and handling high concurrency. Apache makes more sense if you need .htaccess support or are migrating a legacy application that depends on mod_rewrite rules. For a WordPress deployment using Nginx on Debian or Ubuntu, the WordPress with Nginx on Ubuntu/Debian guide covers the full stack. The official Nginx documentation is the best reference for advanced configuration options.