How to Set Up a Web Server on FreeBSD with nginx
A complete walkthrough installing nginx, enabling it as a proper rc.conf-managed service, and serving a first site — the FreeBSD-idiomatic way, not a generic Linux tutorial adapted.
FreeBSD’s rc.conf-based service management differs meaningfully from systemd-based Linux distributions — this walks through installing and running nginx the FreeBSD way.
Step 1: install nginx
pkg install nginx
Step 2: enable the service in rc.conf
sysrc nginx_enable=YES
sysrc is the correct, idempotent way to edit /etc/rc.conf — it avoids the classic mistake of hand-editing the file and introducing a duplicate or malformed entry.
Step 3: review the default configuration
cat /usr/local/etc/nginx/nginx.conf
The package installs a working default configuration serving from /usr/local/www/nginx-dist — confirm this path before changing anything.
Step 4: point nginx at your actual site content
# /usr/local/etc/nginx/nginx.conf
server {
listen 80;
server_name example.com;
root /usr/local/www/example;
}
Step 5: start the service
service nginx start
Step 6: verify it’s actually running and listening
service nginx status
sockstat -4 -l | grep nginx
Step 7: open the firewall if pf is enabled
# /etc/pf.conf
pass in on em0 proto tcp to port { 80, 443 }
pfctl -f /etc/pf.conf
A correctly running nginx that’s still unreachable externally is frequently just a firewall rule, not an nginx problem.
Step 8: set up TLS with a certificate
pkg install py311-certbot
certbot certonly --webroot -w /usr/local/www/example -d example.com
Step 9: reload nginx after configuration changes, rather than restarting
service nginx reload
reload re-reads the configuration without dropping active connections — the right choice for routine configuration changes, reserving a full restart for situations that genuinely require it.
Why sysrc matters more than it looks
Using sysrc instead of a text editor for rc.conf isn’t just a style preference — it prevents the specific, common failure mode of ending up with two conflicting nginx_enable lines after an edit, which can produce confusing, inconsistent service behavior that’s genuinely hard to diagnose without checking the raw file. It’s a small habit that avoids a real class of self-inflicted configuration bugs.