This episode builds a complete web stack on Void: nginx with PHP-FPM, and MariaDB or PostgreSQL as the database. You will enable all the services via runit symlinks and manage the logs in /var/log/nginx with svlogd.

It's time to put Void to work for a real workload: web servers and databases. Episode 12 guides you through building an nginx + PHP-FPM + database stack, enabling everything as runit services, and managing their logs. This is the foundation of almost every modern web application.
The stack we build is the classic LEMP pattern (Linux, nginx, MariaDB, PHP). You'll see how each component lives as an independent runit service, and how logs are managed with svlogd — not journald.
Let's start with the web server.
Install nginx and enable it as a runit service:
sudo xbps-install -S nginx
sudo ln -s /etc/sv/nginx /var/service/
sudo sv start nginxThe ln -s /etc/sv/nginx /var/service/ command makes nginx start automatically at boot. Check that the service is actually running:
sv status nginx
ss -tlnp | grep :80The output of ss -tlnp | grep :80 shows nginx listening on port 80 — a sign the web server is active.
Place the site configuration in /etc/nginx/conf.d/. Example server block:
server {
listen 80;
server_name example.com;
root /srv/http/example;
index index.html index.php;
}After writing the configuration, test the syntax then reload nginx:
sudo nginx -t
sudo sv reload nginxThe nginx -t command validates the syntax before it's applied. sv reload nginx makes nginx read the new configuration without downtime.
For dynamic pages, install PHP-FPM:
sudo xbps-install -S php php-fpm
sudo ln -s /etc/sv/php-fpm /var/service/
sudo sv start php-fpmThe php-fpm package provides the FastCGI Process Manager service. Add the extensions your application needs, for example php-pdo_mysql for the database.
Connect nginx to PHP-FPM via a server block:
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
include fastcgi.conf;
}Test the integration by creating a test file:
echo '<?php phpinfo(); ?>' | sudo tee /srv/http/example/index.phpThen open http://localhost/index.php in your browser — you'll see the phpinfo page if PHP-FPM is working.
Install and initialize MariaDB:
sudo xbps-install -S mariadb mariadb-connector-c
sudo mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
sudo ln -s /etc/sv/mariadbd /var/service/
sudo sv start mariadbdThe mysql_install_db command initializes the data directory for the first time. Once the service is active, secure the installation:
sudo mysql_secure_installationAs an alternative, PostgreSQL is also available:
sudo xbps-install -S postgresql
sudo -u postgres initdb -D /var/lib/postgresql/data
sudo ln -s /etc/sv/postgresql /var/service/
sudo sv start postgresqlThe initdb -D /var/lib/postgresql/data command creates a new database cluster. Once the service is active, create a user and database:
sudo -u postgres psql -c "CREATE USER app WITH PASSWORD 'secret';"
sudo -u postgres createdb -O app appdbnginx logs on Void are managed by svlogd. The log directory structure:
/etc/sv/nginx/log/run : script directing logs to svlogd
/var/log/nginx/current : active log being written continuouslyRead the log live:
tail -f /var/log/nginx/currentThe tail -f /var/log/nginx/current command shows the nginx access log in real time. Old log files are rotated and archived by svlogd automatically.
When a site isn't responding, the right diagnosis sequence:
sv status nginx php-fpm mariadbd
tail -n 20 /var/log/nginx/current
sudo sv restart nginxCheck the status of all services, read the nginx log, then restart the component having trouble. This habit solves the majority of web stack problems.
Episode 12 built a complete web stack on Void: nginx with PHP-FPM as the dynamic frontend, MariaDB or PostgreSQL as the database, all enabled as runit services, with logs managed by svlogd in /var/log/nginx.
Key takeaways:
/var/service/nginx symlink.nginx -t validates the configuration before reloading./var/log/nginx/current.sv status helps diagnose the stack in order.In the next episode, episode 13, we will cover firewalls with nftables — writing rulesets with the nft CLI, enabling IP forwarding and NAT for a gateway, and applying a persistent firewall on Void.