# How to Migrate from Linux to FreeBSD: Complete Guide
You know Linux. You have been running it for years -- maybe decades. You can configure systemd units in your sleep, write iptables rules from memory, and troubleshoot kernel panics from dmesg output alone.
Now you want to try FreeBSD, or your organization is evaluating it for a production workload. This guide is the bridge. It maps every concept you already know in Linux to its FreeBSD equivalent, gives you working commands you can run today, and warns you about the things that will trip you up if nobody tells you first.
Every command in this guide is tested on FreeBSD 14.x. Where Linux commands are shown, they reflect typical Debian/Ubuntu or RHEL/Fedora behavior.
Table of Contents
1. [Why Migrate from Linux to FreeBSD](#why-migrate-from-linux-to-freebsd)
2. [Conceptual Differences](#conceptual-differences)
3. [Package Management Translation](#package-management-translation)
4. [Service Management](#service-management)
5. [File System Transition](#file-system-transition)
6. [Networking](#networking)
7. [Firewall: iptables to PF](#firewall-iptables-to-pf)
8. [User Management](#user-management)
9. [Cron and Scheduled Tasks](#cron-and-scheduled-tasks)
10. [Shell Scripting Differences](#shell-scripting-differences)
11. [Docker to Jails](#docker-to-jails)
12. [Common Gotchas for Linux Users](#common-gotchas-for-linux-users)
13. [Linux to FreeBSD Command Cheat Sheet](#linux-to-freebsd-command-cheat-sheet)
14. [FAQ](#faq)
---
Why Migrate from Linux to FreeBSD
The reasons experienced sysadmins move to FreeBSD tend to cluster around five things.
**ZFS as a first-class citizen.** ZFS on FreeBSD is not a DKMS module bolted onto a kernel that was designed around ext4. It ships in the base system, is maintained by the FreeBSD kernel team, and the installer will set up a ZFS root for you during installation. Boot environments, snapshots, send/recv replication, inline compression, and native encryption all work out of the box with zero additional packages. For a deeper look at the file system options, see our [FreeBSD vs Linux](/blog/freebsd-vs-linux/) comparison.
**Jails.** FreeBSD jails predate Docker by thirteen years and provide OS-level isolation without a runtime daemon. A jail crash does not cascade. There is no equivalent of "the Docker daemon died and took all containers with it." Jails share the host kernel with near-zero overhead and integrate cleanly with ZFS and the network stack. Our [FreeBSD jails guide](/blog/freebsd-jails-guide/) covers the full setup.
**The BSD license.** The two-clause BSD license lets you do anything with the code -- embed it, modify it, ship it in proprietary products -- without copyleft obligations. This matters for appliance vendors, embedded systems, and organizations with legal teams that reject GPL dependencies.
**Performance and simplicity.** FreeBSD's network stack has been tuned for decades. Netflix runs its entire CDN -- which delivers a substantial fraction of all internet traffic in North America -- on FreeBSD. The system is coherent: one team maintains the kernel, the C library, the compiler, the bootloader, and the base utilities. There is no fragmentation across distributions.
**Stability of interfaces.** FreeBSD does not break userland APIs between releases. rc.conf works the same way it did in FreeBSD 5. There is no equivalent of the sysvinit-to-upstart-to-systemd migration that fractured the Linux ecosystem.
---
Conceptual Differences
This is the most important section in this guide. The technical differences (different commands, different paths) are easy to learn. The conceptual differences are what actually trip people up.
Base System vs. Distribution
Linux is a kernel. Everything else -- the shell, coreutils, init system, package manager -- comes from separate upstream projects assembled by a distribution. Ubuntu and Arch ship the same kernel but are radically different operating systems.
FreeBSD is a complete operating system. The kernel, the userland (libc, sh, cp, ls, grep, awk, sed, tar, fetch, and hundreds more), the compiler toolchain, and the documentation are all developed and released together as one unit. When you run freebsd-update fetch install, you are updating the entire base system atomically.
Third-party software lives in /usr/local. The base system lives in /, /usr/bin, /usr/sbin, /usr/lib. This separation is clean and absolute. If you delete everything under /usr/local, you still have a fully functional operating system.
/usr/local Is Not Optional
On Linux, /usr/local is a dusty convention most people ignore. On FreeBSD, it is where every package installs. NGINX goes to /usr/local/sbin/nginx. Its config goes to /usr/local/etc/nginx/. Python goes to /usr/local/bin/python3. If you are writing scripts that hardcode /usr/bin/python3, they will break.
rc.d vs. systemd
FreeBSD uses the rc.d init system. There are no unit files, no targets, no socket activation, no dependency trees, no journal. Services are controlled by shell scripts in /etc/rc.d/ (base system) and /usr/local/etc/rc.d/ (packages). Configuration is centralized in /etc/rc.conf.
This is simpler. Whether that simplicity is a feature or a limitation depends on your workload, but for the majority of server use cases, rc.d does everything you need with far less complexity.
---
Package Management Translation
If you are coming from Debian/Ubuntu, you use apt. From RHEL/Fedora, you use dnf or yum. On FreeBSD, the binary package manager is pkg.
Binary Packages with pkg
sh
# Search for a package
pkg search nginx
# Install a package
pkg install nginx
# Remove a package
pkg delete nginx
# Update the package database
pkg update
# Upgrade all installed packages
pkg upgrade
# Show info about an installed package
pkg info nginx
# List all installed packages
pkg info
# Find which package owns a file
pkg which /usr/local/sbin/nginx
# Lock a package to prevent upgrades
pkg lock nginx
Ports: Building from Source
The Ports Collection is FreeBSD's equivalent of a PPA, AUR, or source RPM -- except it covers over 34,000 packages and is an official, maintained part of the project.
sh
# Install the ports tree
portsnap fetch extract
# Build and install from ports
cd /usr/ports/www/nginx && make install clean
# Configure compile-time options
cd /usr/ports/www/nginx && make config
Ports let you toggle compile-time options that binary packages cannot. Need NGINX with a specific module? Ports. Need PostgreSQL compiled with a non-default option? Ports.
For a detailed comparison, see [pkg vs ports](/blog/freebsd-pkg-vs-ports/).
Translation Table: Package Management
| Task | Debian/Ubuntu | RHEL/Fedora | FreeBSD |
|------|---------------|-------------|---------|
| Install package | apt install nginx | dnf install nginx | pkg install nginx |
| Remove package | apt remove nginx | dnf remove nginx | pkg delete nginx |
| Search packages | apt search nginx | dnf search nginx | pkg search nginx |
| Update package DB | apt update | dnf check-update | pkg update |
| Upgrade all | apt upgrade | dnf upgrade | pkg upgrade |
| List installed | dpkg -l | rpm -qa | pkg info |
| File to package | dpkg -S /path | rpm -qf /path | pkg which /path |
| Show package info | apt show nginx | dnf info nginx | pkg info nginx |
| Clean cache | apt clean | dnf clean all | pkg clean |
---
Service Management
On Linux with systemd, you use systemctl. On FreeBSD, you use service and sysrc.
Starting and Stopping Services
sh
# Start a service
service nginx start
# Stop a service
service nginx stop
# Restart a service
service nginx restart
# Check status
service nginx status
# Reload configuration without restart
service nginx reload
Enabling and Disabling Services
On Linux: systemctl enable nginx. On FreeBSD, you add the service to /etc/rc.conf:
sh
# Enable a service (adds nginx_enable="YES" to /etc/rc.conf)
sysrc nginx_enable=YES
# Disable a service
sysrc nginx_enable=NO
# Check if a service is enabled
sysrc nginx_enable
# Start a service that is not enabled (one-time)
service nginx onestart
The sysrc command is the safe way to edit /etc/rc.conf. You can also edit the file directly, but sysrc handles quoting, deduplication, and validation.
Translation Table: Service Management
| Task | Linux (systemd) | FreeBSD |
|------|-----------------|---------|
| Start | systemctl start nginx | service nginx start |
| Stop | systemctl stop nginx | service nginx stop |
| Restart | systemctl restart nginx | service nginx restart |
| Status | systemctl status nginx | service nginx status |
| Enable at boot | systemctl enable nginx | sysrc nginx_enable=YES |
| Disable at boot | systemctl disable nginx | sysrc nginx_enable=NO |
| List all services | systemctl list-units | service -e (enabled) / service -l (all) |
| View logs | journalctl -u nginx | Check /var/log/ or service-specific log |
There is no journal on FreeBSD. Logs go to syslog and service-specific log files. This is straightforward and means your logs are plain text files you can grep, tail, and rotate with newsyslog.
---
File System Transition
Most Linux servers run ext4. Some use XFS. If you are migrating to FreeBSD, you almost certainly want ZFS.
ZFS on FreeBSD
The FreeBSD installer offers ZFS as a root filesystem option. Select it during install and you get:
- A ZFS pool called zroot on your boot disk
- Boot environments (you can snapshot before an upgrade and roll back in seconds)
- Inline compression (LZ4 by default -- free performance for most workloads)
- Copy-on-write (no fsck, no journal corruption, no repair after power loss)
sh
# List pools
zpool list
# List datasets
zfs list
# Create a new dataset
zfs create zroot/data/myapp
# Take a snapshot
zfs snapshot zroot/data/myapp@before-upgrade
# Roll back to snapshot
zfs rollback zroot/data/myapp@before-upgrade
# Enable compression
zfs set compression=lz4 zroot/data
# Send a snapshot to another host
zfs send zroot/data/myapp@snap | ssh remote zfs recv tank/backup/myapp
fstab Differences
FreeBSD uses /etc/fstab like Linux, but the format has small differences. Device names use the GEOM framework, not /dev/sdX.
# Linux fstab
/dev/sda1 /boot ext4 defaults 0 2
UUID=xxxx / ext4 errors=remount-ro 0 1
# FreeBSD fstab (UFS example)
/dev/ada0p2 / ufs rw 1 1
/dev/ada0p1 /boot ufs rw 1 1
With ZFS, most filesystems are managed by ZFS itself and do not appear in fstab at all. Only the boot pool and swap typically show up.
---
Networking
Linux networking has gone through multiple generations: ifconfig (deprecated), ip, Netplan, NetworkManager, systemd-networkd. FreeBSD uses ifconfig and /etc/rc.conf. That is it.
Interface Configuration
sh
# Show all interfaces
ifconfig
# Set a static IP
sysrc ifconfig_em0="inet 192.168.1.10 netmask 255.255.255.0"
# Set default gateway
sysrc defaultrouter="192.168.1.1"
# DHCP
sysrc ifconfig_em0="DHCP"
# Apply changes without reboot
service netif restart && service routing restart
# Set DNS
echo "nameserver 1.1.1.1" > /etc/resolv.conf
Note: FreeBSD interface names reflect the driver, not a generic scheme. You will see em0 (Intel), igb0 (Intel Gigabit), ix0 (Intel 10G), vtnet0 (virtio), bge0 (Broadcom). Run ifconfig to see your actual interface names.
Wireless Networking
Linux uses NetworkManager or wpa_supplicant with various frontends. FreeBSD uses wpa_supplicant directly.
sh
# /etc/wpa_supplicant.conf
network={
ssid="MyNetwork"
psk="mypassword"
}
sh
# /etc/rc.conf
wlans_iwn0="wlan0"
ifconfig_wlan0="WPA DHCP"
Translation Table: Networking
| Task | Linux | FreeBSD |
|------|-------|---------|
| Show interfaces | ip addr | ifconfig |
| Set static IP | Edit Netplan/NetworkManager | sysrc ifconfig_em0="inet ..." |
| DHCP | dhclient eth0 or Netplan | sysrc ifconfig_em0="DHCP" |
| Show routes | ip route | netstat -rn |
| Add route | ip route add 10.0.0.0/8 via 192.168.1.1 | route add 10.0.0.0/8 192.168.1.1 |
| DNS config | /etc/resolv.conf or systemd-resolved | /etc/resolv.conf |
| Restart networking | systemctl restart networking | service netif restart |
---
Firewall: iptables to PF
Linux uses iptables or its successor nftables. FreeBSD ships PF (Packet Filter), originally from OpenBSD. PF is widely considered easier to read and maintain than iptables.
Enabling PF
sh
sysrc pf_enable=YES
sysrc pflog_enable=YES
service pf start
PF Configuration
The PF config file is /etc/pf.conf. Here is a basic server configuration:
# /etc/pf.conf
# Macros
ext_if = "vtnet0"
tcp_services = "{ ssh, http, https }"
# Options
set block-policy drop
set skip on lo0
# Normalization
scrub in all
# Default deny
block in all
pass out all keep state
# Allow inbound services
pass in on $ext_if proto tcp to port $tcp_services
# Allow ICMP ping
pass in on $ext_if inet proto icmp icmp-type echoreq
Rule Translation Examples
# Linux iptables: Allow SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# FreeBSD PF equivalent:
pass in on $ext_if proto tcp to port ssh
# Linux iptables: Drop all incoming by default
iptables -P INPUT DROP
# FreeBSD PF equivalent:
block in all
# Linux iptables: Allow established connections
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# FreeBSD PF: handled automatically by "keep state" (which is on by default)
# Linux iptables: NAT/masquerade
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
# FreeBSD PF equivalent:
nat on $ext_if from 10.0.0.0/24 to any -> ($ext_if)
# Linux iptables: Port forward
iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80
# FreeBSD PF equivalent:
rdr on $ext_if proto tcp to port 8080 -> 127.0.0.1 port 80
Managing PF
sh
# Check syntax before loading
pfctl -nf /etc/pf.conf
# Load rules
pfctl -f /etc/pf.conf
# Show current rules
pfctl -sr
# Show state table
pfctl -ss
# Show statistics
pfctl -si
# Disable PF temporarily
pfctl -d
# Enable PF
pfctl -e
PF rules are evaluated top-to-bottom and are "last match wins" by default. This is different from iptables, which is "first match wins." You can add quick to a rule to make it match immediately, similar to iptables behavior.
---
User Management
Linux uses useradd, usermod, userdel. FreeBSD has those commands too (via the pw wrapper), but the idiomatic way is to use pw directly or adduser for interactive creation.
Creating Users
sh
# Interactive user creation (recommended for new users)
adduser
# Non-interactive with pw
pw useradd john -m -s /bin/sh -G wheel
# Add user to a group
pw groupmod wheel -m john
# Delete a user
pw userdel john -r
sudo and the wheel Group
FreeBSD does not install sudo by default. Install it:
sh
pkg install sudo
Then either edit the sudoers file:
sh
visudo
Or, more commonly, uncomment the wheel group line:
%wheel ALL=(ALL:ALL) ALL
Alternatively, FreeBSD ships doas in the base system (since FreeBSD 14). It is simpler than sudo:
sh
# /usr/local/etc/doas.conf
permit :wheel
Translation Table: User Management
| Task | Linux | FreeBSD |
|------|-------|---------|
| Add user (interactive) | adduser | adduser |
| Add user (scripted) | useradd -m -s /bin/bash john | pw useradd john -m -s /bin/sh |
| Delete user | userdel -r john | pw userdel john -r |
| Modify user | usermod -aG wheel john | pw groupmod wheel -m john |
| Change password | passwd john | passwd john |
| List groups | groups john | groups john |
| Lock account | usermod -L john | pw lock john |
| Unlock account | usermod -U john | pw unlock john |
---
Cron and Scheduled Tasks
FreeBSD has standard cron, plus a framework called periodic that Linux does not have.
Standard Cron
Works the same as Linux. Edit with crontab -e. System-wide cron jobs go in /etc/crontab.
sh
# User crontab
crontab -e
# System crontab
vi /etc/crontab
The periodic Framework
FreeBSD has three built-in periodic runs: daily, weekly, and monthly. These are configured in /etc/periodic.conf and executed by cron entries in /etc/crontab.
sh
# See what daily periodic tasks do
periodic daily
# Configure periodic tasks
vi /etc/periodic.conf
Example /etc/periodic.conf:
sh
# Disable daily security email
daily_status_security_enable="NO"
# Enable daily ZFS scrub check
daily_scrub_zfs_enable="YES"
# Set output email
daily_output="/var/log/daily.log"
You can add your own periodic scripts by dropping them into /usr/local/etc/periodic/daily/, /usr/local/etc/periodic/weekly/, or /usr/local/etc/periodic/monthly/. This is cleaner than scattering cron entries across multiple crontabs.
Translation Table: Scheduled Tasks
| Task | Linux | FreeBSD |
|------|-------|---------|
| Edit user cron | crontab -e | crontab -e |
| System cron | /etc/crontab | /etc/crontab |
| Systemd timers | systemctl list-timers | No equivalent (use cron or periodic) |
| Periodic daily tasks | /etc/cron.daily/ | /etc/periodic/daily/ |
| Log rotation | logrotate | newsyslog |
---
Shell Scripting Differences
This section will save you hours of debugging.
/bin/sh Is Not bash
On most Linux distributions, /bin/sh is a symlink to bash, or dash (a bash-compatible shell). On FreeBSD, /bin/sh is the Almquist shell (ash). It is POSIX-compliant but does not support bashisms.
Things that work in bash but break in FreeBSD /bin/sh:
sh
# Arrays -- not supported in sh
arr=(one two three) # FAILS
# [[ double brackets -- not supported
[[ -f /etc/rc.conf ]] # FAILS -- use [ -f /etc/rc.conf ]
# Process substitution -- not supported
diff <(ls /tmp) <(ls /var) # FAILS
# Here strings -- not supported
cat <<< "hello" # FAILS
# {1..10} brace expansion -- not supported
echo {1..10} # FAILS -- prints literal {1..10}
# == in test -- use = instead
[ "$var" == "value" ] # FAILS -- use [ "$var" = "value" ]
If you need bash, install it:
sh
pkg install bash
Then use #!/usr/local/bin/bash as your shebang. Note the path: it is /usr/local/bin/bash, not /usr/bin/bash and not /bin/bash.
GNU vs. BSD Utilities
The base system utilities on FreeBSD are BSD variants, not GNU. They accept different flags.
sh
# GNU sed: -i edits in place
sed -i 's/foo/bar/' file.txt # Linux (GNU)
sed -i '' 's/foo/bar/' file.txt # FreeBSD (BSD) -- needs empty string for -i
# GNU grep: -P for PCRE
grep -P '\d+' file.txt # Linux (GNU)
grep -E '[0-9]+' file.txt # FreeBSD -- use -E for extended regex
# GNU date: different format flags
date -d "2 days ago" # Linux (GNU)
date -v-2d # FreeBSD (BSD)
# GNU stat: different output
stat -c '%s' file.txt # Linux (GNU)
stat -f '%z' file.txt # FreeBSD (BSD)
# GNU readlink -f
readlink -f /path/to/link # Linux (GNU)
realpath /path/to/link # FreeBSD (use realpath instead)
# GNU xargs: -r flag
echo "" | xargs -r echo "notempty" # Linux (GNU) -- -r prevents empty run
# FreeBSD xargs does not run on empty input by default, so -r is unnecessary
If you have scripts that depend heavily on GNU tools, install coreutils:
sh
pkg install coreutils
GNU tools are installed with a g prefix: gdate, gstat, gsed, greadlink. This lets you use both BSD and GNU versions without conflicts.
---
Docker to Jails
If you are running Docker containers in production, FreeBSD jails are the native alternative. The mental model is similar -- an isolated environment with its own filesystem, networking, and process space -- but the implementation is fundamentally different.
Key Differences
| Aspect | Docker | FreeBSD Jails |
|--------|--------|---------------|
| Isolation | Namespaces + cgroups | Jail framework (kernel-level) |
| Runtime daemon | dockerd (single point of failure) | No daemon; jails managed by kernel |
| Image format | OCI layers | Base system extraction or ZFS clones |
| Networking | bridge/overlay/host | Inherited IP or VNET (full stack) |
| Storage | overlay2, volumes | ZFS datasets (native) |
| Orchestration | Docker Compose, Swarm, K8s | Bastille, pot, iocage |
Quick Jail Example
sh
# Create a ZFS dataset for jails
zfs create -o mountpoint=/jails zroot/jails
# Extract the base system into a jail
fetch https://download.freebsd.org/releases/amd64/14.2-RELEASE/base.txz
tar -xf base.txz -C /jails/webserver
# Minimal jail.conf
cat > /etc/jail.conf <
webserver {
host.hostname = "webserver";
path = "/jails/webserver";
ip4.addr = "192.168.1.50";
interface = "em0";
exec.start = "/bin/sh /etc/rc";
exec.stop = "/bin/sh /etc/rc.shutdown";
mount.devfs;
}
JAILCONF
# Start the jail
service jail start webserver
# Enter the jail
jexec webserver /bin/sh
# Install packages inside the jail
pkg -j webserver install nginx
For full coverage of jail networking, ZFS integration, and Bastille management, see our [FreeBSD jails guide](/blog/freebsd-jails-guide/).
---
Common Gotchas for Linux Users
These are the things that make experienced Linux admins curse in the first week. Read this section before you start.
**1. Paths are different.** Third-party binaries are in /usr/local/bin and /usr/local/sbin. Config files are in /usr/local/etc/. If a script hardcodes /etc/nginx/nginx.conf, it will not find the file. The correct path is /usr/local/etc/nginx/nginx.conf.
**2. /bin/sh is not bash.** See the shell scripting section above. Your bash scripts need either a #!/usr/local/bin/bash shebang or a rewrite to POSIX sh.
**3. GNU flags do not work.** sed -i needs an empty string argument. grep -P does not exist. date -d does not exist. Install coreutils and use g-prefixed commands if you need GNU behavior.
**4. No /proc by default.** FreeBSD has a /proc filesystem but it is not mounted by default. Some software (notably some Java and Node.js versions) expects it. Mount it with:
sh
mount -t procfs proc /proc
# Or permanently in /etc/fstab:
# proc /proc procfs rw 0 0
**5. Linux binary compatibility is optional.** FreeBSD can run Linux binaries via linuxulator, but it is not loaded by default. If you need it:
sh
sysrc linux_enable=YES
service linux start
**6. Disk device names.** There is no /dev/sda. SATA drives are ada0, NVMe drives are nda0 or nvd0, virtio drives are vtbd0. Partitions use GPT labels: ada0p1, ada0p2.
**7. No systemd.** There are no unit files, no journal, no systemctl. Services are shell scripts. Logs go to files. Configuration goes in /etc/rc.conf. This is a feature, not a gap.
**8. Default shell is sh or tcsh.** Root gets /bin/sh or /bin/csh by default. Regular users get /bin/sh. If you want bash, install it and change your shell:
sh
pkg install bash
chsh -s /usr/local/bin/bash
**9. Network interface names.** There is no eth0. Interface names are based on the driver: em0, igb0, vtnet0, bge0. Run ifconfig to see yours.
**10. Package names differ.** The package name is not always what you expect. vim is vim, but build-essential does not exist. Development headers come with the base system or specific package variants. Use pkg search liberally.
---
Linux to FreeBSD Command Cheat Sheet
This is the table you will keep open in a terminal for the first month.
| Task | Linux Command | FreeBSD Command |
|------|--------------|-----------------|
| Update system | apt update && apt upgrade | pkg update && pkg upgrade |
| Update OS | apt dist-upgrade or dnf system-upgrade | freebsd-update fetch install |
| Install package | apt install vim | pkg install vim |
| Remove package | apt remove vim | pkg delete vim |
| Search packages | apt search vim | pkg search vim |
| Find file owner | dpkg -S /usr/bin/vim | pkg which /usr/local/bin/vim |
| Start service | systemctl start nginx | service nginx start |
| Stop service | systemctl stop nginx | service nginx stop |
| Enable service | systemctl enable nginx | sysrc nginx_enable=YES |
| Service status | systemctl status nginx | service nginx status |
| View logs | journalctl -u nginx | tail /var/log/nginx/error.log |
| List interfaces | ip addr | ifconfig |
| Show routes | ip route | netstat -rn |
| Firewall rules | iptables -L | pfctl -sr |
| Add user | useradd -m john | pw useradd john -m |
| Add to group | usermod -aG wheel john | pw groupmod wheel -m john |
| Disk usage | df -h | df -h |
| List block devices | lsblk | geom disk list or camcontrol devlist |
| Kernel info | uname -r | uname -r |
| CPU info | lscpu or cat /proc/cpuinfo | sysctl hw.model and sysctl hw.ncpu |
| Memory info | free -h | sysctl hw.physmem or top |
| Process list | ps aux | ps aux |
| Kill process | kill -9 PID | kill -9 PID |
| Reboot | reboot | reboot |
| Shutdown | shutdown -h now | shutdown -p now |
| Mount USB | mount /dev/sdb1 /mnt | mount /dev/da0p1 /mnt |
| Check filesystem | fsck /dev/sda1 | fsck /dev/ada0p1 (or zpool scrub for ZFS) |
| View kernel messages | dmesg | dmesg |
| System configuration | Various files in /etc/ | /etc/rc.conf (central) |
| Cron jobs | crontab -e | crontab -e |
| Periodic maintenance | /etc/cron.daily/ | /etc/periodic/daily/ |
| Log rotation | logrotate | newsyslog |
| Trace system calls | strace -p PID | truss -p PID |
| Trace library calls | ltrace | truss -f |
| List loaded kernel modules | lsmod | kldstat |
| Load kernel module | modprobe module | kldload module |
---
FAQ
Is FreeBSD harder to learn than Linux?
No, but it is different. If you are already comfortable administering Linux from the command line, you will be productive on FreeBSD within a day or two. The learning curve is mostly about discovering where things live and which flags changed. The concepts -- processes, filesystems, networking, permissions -- are the same. Many experienced sysadmins report that FreeBSD is actually simpler because there is one way to do things instead of five.
Can I run Linux applications on FreeBSD?
Yes. FreeBSD has a Linux compatibility layer called Linuxulator that can run unmodified Linux binaries. It supports CentOS and Ubuntu userlands. Many commercial applications (including Spotify, some games via Steam, and various proprietary server software) run this way. Enable it with sysrc linux_enable=YES && service linux start. Note that this is not emulation -- Linux syscalls are translated to FreeBSD syscalls at the kernel level with minimal overhead.
Should I use UFS or ZFS?
ZFS for almost every use case. The FreeBSD installer offers ZFS as a root filesystem, and it is the recommended choice. ZFS gives you snapshots, boot environments, compression, checksums, and simple replication with no additional packages. UFS still works and is lighter on RAM, so it makes sense for very small VMs (under 512MB RAM) where ZFS's memory overhead is a concern. For a full server or VPS setup, see our [FreeBSD VPS setup](/blog/freebsd-vps-setup/) guide.
Can I use Docker on FreeBSD?
Docker itself does not run natively on FreeBSD. Docker depends on Linux-specific kernel features (cgroups v2, overlayfs, Linux namespaces) that do not exist on FreeBSD. The FreeBSD native alternative is jails, which provide equivalent or better isolation with less overhead. Tools like Bastille, pot, and AppJail provide Docker-like workflow for managing jails. If your workflow depends heavily on Docker Compose files, you will need to translate those into jail configurations. Podman has experimental FreeBSD support, but it is not production-ready as of 2026.
How do I keep FreeBSD updated?
Two separate update streams. The base system is updated with freebsd-update fetch install. Third-party packages are updated with pkg upgrade. For major version upgrades, use freebsd-update -r 14.2-RELEASE upgrade. ZFS boot environments (bectl create backup && bectl activate backup) let you snapshot before an upgrade and roll back instantly if something breaks.
What about desktop use? Can FreeBSD replace my Linux desktop?
It can, with caveats. FreeBSD runs Xorg and Wayland compositors, KDE Plasma, GNOME, XFCE, i3, Sway, and most desktop applications (Firefox, LibreOffice, VLC, etc.). Hardware support is the main limitation -- WiFi adapters, GPUs, and Bluetooth may require more manual configuration than on Linux. FreeBSD is strongest as a server OS and as a desktop for users who value simplicity and stability over plug-and-play hardware support.
How does FreeBSD handle security updates?
freebsd-update delivers binary security patches for the base system, typically within hours of an advisory. For packages, pkg audit checks installed packages against the VuXML vulnerability database. Run pkg audit -F regularly to fetch the latest advisories and check your system. FreeBSD security advisories are published at [freebsd.org/security](https://www.freebsd.org/security/) and are well-regarded for their clarity and responsiveness.
---
Next Steps
You have the map. Now walk the territory. Set up a FreeBSD VM or spin up a [FreeBSD VPS](/blog/freebsd-vps-setup/), keep this guide and the cheat sheet open in a second terminal, and start rebuilding a service you already run on Linux. The muscle memory comes faster than you expect.
For deeper dives into specific topics:
- [FreeBSD vs Linux](/blog/freebsd-vs-linux/) -- detailed comparison of both systems
- [pkg vs ports](/blog/freebsd-pkg-vs-ports/) -- when to use binary packages vs building from source
- [FreeBSD jails guide](/blog/freebsd-jails-guide/) -- complete jail setup and management
- [FreeBSD VPS setup](/blog/freebsd-vps-setup/) -- from zero to production server