Skip to content
daniel@cosenza:~/blog
FreeBSDHow-To July 5, 2026 2 min read

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.