Setup Web Server (apache) and DNS (bind) on a MacMini using Homebrew


  1. Online references
  2. Common pitfalls, problems, useful commands
  3. XCODE and BBEdit - command line tools
  4. BREW
  6. HTTPD config edits including HTTP2 and vhosts
  7. HTML default header
  8. Let's Encrypt - certbot
  9. Named and bind
  10. Network Performance tools
  11. SSH on a different port number
  12. PHP
  13. MacMini Setup (for SC/webcam/demo)
  14. TimeMachine Problem Solving
  15. How this page is made

Online references

In this table are the commands for apache, bind and certbot via brew as in

The previous Apple server software needs to be completely uninstalled!
In this guide the commands are in green. Text to be changed or entered are in light blue.

Common pitfalls, problems, useful commands

  • After a brew upgrade some services may not work. One difficult to diagnose problem may be the firewall settings in MacOSX. It blocks by default incoming connections on unsigned bin's and executables need to be added in the list in the System Preferences Firewall settings. Also note that just putting there the /usr/local/bin/executable will not work since brew puts aliasses (links) there. Follow the link to the real bin. Same for /usr/local/sbin .
  • After a "brew upgrade" the output may display an error that an old directory could not be removed and a sudo command is displayed. In reality the "brew upgrade" did not complete, so execute that sudo command and repeat "brew upgrade" and displayed error - sudo commands until nothing is being done anymore by that command.
  • Somehow launchd has a different or incomplete PATH environment. Caused certbot renew to initially fail.
  • if you need to log out another user:
    • ps awwwwux | grep loginwindow
    • kill the pid of that user with:
    • sudo kill -9 [pid]
  • Support files can be found HERE.

XCODE and BBEdit - command line tools

Apple's command line tools need to be installed, XCode is not needed.
  • xcode-select --install

If needed to re-install command tools do this command first:

  • sudo rm -rf /Library/Developer/CommandLineTools

Install BBEdit from

Start BBEdit and set up its command line tools under the BBEdit menu.



  • ruby -e "$(curl -fsSL"
  • brew install openldap libiconv
For more information see:


To upgrade all installed programs to newest version:
  • brew update
  • brew upgrade
  • brew cleanup
  • brew services list
  • sudo brew services restart --all


Check version and installation:
  • brew doctor
  • brew --version
If needed to correct permissions:
  • sudo chown -R "$USER":admin /usr/local
  • sudo chown -R "$USER":admin /Library/Caches/Homebrew



  • brew install httpd
  • sudo brew services start httpd


To restart httpd:

  • sudo brew services restart httpd
  • sudo apachectl stop
  • sudo apachectl -k restart


In a separate windo show dynamically the tail of the error and access logfile:
  • tail -n 200 -f /usr/local/var/log/httpd/error_log
  • tail -n 200 -f /usr/local/var/log/httpd/access_log
If install has problems because of previous versions:
  • sudo apachectl stop
  • sudo launchctl unload -w /System/Library/LaunchDaemons/org.apache.httpd.plist

Check if deamon is running:

  • ps -aef | grep httpd
To get setup paths:
  • sudo apachectl -S
Test conf files, must be with sudo to test certificates:
  • sudo apachectl configtest

HTTPD config edits including HTTP2 and vhosts

HTTPD config basic edits:
  • bbedit /usr/local/etc/httpd/httpd.conf
  1. Listen 8080 => Listen 80
  2. enable ==> LoadModule deflate_module lib/httpd/modules/
  3. enable ==> LoadModule rewrite_module lib/httpd/modules/
  4. ServerAdmin
  5. #ServerName ==> ServerName localhost:80
  6. enable ==> Include /usr/local/etc/httpd/extra/httpd-autoindex.conf
HTTPD config edits to enable http2
  • bbedit /usr/local/etc/httpd/httpd.conf
  1. disable ===> #LoadModule mpm_prefork_module lib/httpd/modules/
  2. enable ===> LoadModule mpm_event_module lib/httpd/modules/
  3. enable ===> LoadModule http2_module lib/httpd/modules/
  4. add ===> Protocols h2 h2c http/1.1
Small edit to enable full filename display in case of directory index:
  • bbedit /usr/local/etc/httpd/extra/httpd-autoindex.conf

add NameWidth=* to the line IndexOptions FancyIndexing HTMLTable VersionSort

  1. ===> IndexOptions FancyIndexing HTMLTable VersionSort NameWidth=*
HTTPD config edits enable vhosts:
  • bbedit /usr/local/etc/httpd/httpd.conf
  1. enable ==> LoadModule vhost_alias_module lib/httpd/modules/
  2. enable ==> Include /usr/local/etc/httpd/extra/httpd-vhosts.conf
and for vhosts including a catch directory. The catch directory is the default webroot where all requests go to if there is not a specific webroot for that (sub)domain defined. Therefore, it must be the first in the list. Here an example for edit:
  • bbedit /usr/local/etc/httpd/extra/httpd-vhosts.conf
<VirtualHost *:80>
    DocumentRoot "/usr/local/var/www"
<Directory "/usr/local/var/www">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted

<VirtualHost *:80>
    DocumentRoot "/Users/example/Sites"
<Directory "/Users/example/Sites">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted

HTML default header

Web pages header:

<!DOCTYPE html>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=0.25, maximum-scale=4.0, user-scalable=yes">
    <meta name="description" content="title">
    <meta name="author" content="Cees de Laat">
  <body style="font-family: Helvetica,Arial,sans-serif;" text="#ffffff" bgcolor="#000000" link="#ffcc66" alink="#ff9900" vlink="#ffff66">

Let's Encrypt - certbot

  • sudo install -d -o $(whoami) -g admin /usr/local/Frameworks
  • brew install certbot
HTTPD edits:
  • bbedit /usr/local/etc/httpd/httpd.conf


LoadModule ssl_module modules/
LoadModule socache_shmcb_module modules/

add at the end:

<IfModule mod_ssl.c>
   Listen 443
Include /usr/local/etc/httpd/extra/httpd-vhosts-le-ssl.conf

The idea is that all requests that get through on port 80 or with incorrect url's/domain names end up in:
  • "/usr/local/var/www"
and all requests that come in via https and correct domain names go to the correct webroots of those domains.

For that purpose different rewrite rules take care of redirection. Those are in httpd-vhosts.conf
I use the following domain construction for
  • catch
    • catches all (sub)domains for which no other webroot is defined is
    • this goes to the normal webroot of the domain
    • also to the typical webroot of
    • a subdomain of with its own webroot
in httpd-vhosts.conf:
  • bbedit /usr/local/etc/httpd/extra/httpd-vhosts.conf
<VirtualHost *:80>
    DocumentRoot "/usr/local/var/www"
<Directory "/usr/local/var/www">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted

<VirtualHost *:80>
    DocumentRoot "/usr/local/var/www"
RewriteEngine on
RewriteCond %{SERVER_NAME} [OR]
RewriteCond %{SERVER_NAME}
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
<Directory "/Users/example/Sites">
    Options Indexes FollowSymLinks
    AllowOverride All
    Require all granted

and create/edit httpd-vhosts-le-ssl.conf:
  • bbedit /usr/local/etc/httpd/extra/httpd-vhosts-le-ssl.conf
<VirtualHost *:443>
    DocumentRoot "/usr/local/var/www"
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/
SSLCertificateKeyFile /etc/letsencrypt/live/

<VirtualHost *:443>
    DocumentRoot "/Users/example/Sites"
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/
SSLCertificateKeyFile /etc/letsencrypt/live/
To request the certificates:
  • sudo certbot --apache
or if one first wants to do a number of test runs for debugging:
  • sudo certbot --apache --staging
for after successful testing forcing a full new certificate:
  • sudo certbot --apache --force-renewal
for production:
  • sudo certbot renew

if test runs are needed:

  • sudo certbot renew --dry-run
To list the certificates:
  • sudo certbot certificates
However, the plist in the above solution does not work because somehow the PATH variable of the running deamon is not correct. Therefore we make our own script that sets the path and then  invokes certbot renew, and then we use a LaunchDeamon to periodically invoke the script. For renewal we have to make a shell script and a launchd plist.

create file /usr/local/etc/ :
  • bbedit /usr/local/etc/
and put in:

sudo certbot renew
Make it executable:
  • chmod +x /usr/local/etc/

create plist:

  • bbedit /Library/LaunchDaemons/com.letsencrypt.renew.plist
  • sudo vi /Library/LaunchDaemons/com.letsencrypt.renew.plist
put in that file the xml below here:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "">
<plist version="1.0">

  • sudo chmod 644 /Library/LaunchDaemons/com.letsencrypt.renew.plist
  • sudo chown root:admin /Library/LaunchDaemons/com.letsencrypt.renew.plist
  • sudo launchctl load /Library/LaunchDaemons/com.letsencrypt.renew.plist
  • sudo launchctl list | grep -i letsencrypt
  • tail -f -n 40 /tmp/com.letsencrypt.renew.stderr
  • tail -f -n 40 /tmp/com.letsencrypt.renew.stdout
  • sudo tail -f -n 400 /var/log/letsencrypt/letsencrypt.log

Some more info:

The configuration file is at: /etc/letsencrypt/renewal/

Named and bind


  • brew install bind

Edit the conf file:

  • bbedit /usr/local/etc/named.conf

And create the zone files in:

  • /usr/local/var/named/
Start bind:
  • sudo brew services start bind


  • sudo brew services restart bind
  • sudo brew services stop bind


First set up a separate window with tail of logging:

  • tail -f -n 40 /usr/local/var/log/named/named.log

Some checks:

  • rndc -k /usr/local/etc/rndc.key -p 54 status
  • named-checkconf -z /usr/local/etc/named.conf
  • host -t ns
Zone file specials:  10800 IN SOA (
                      10800 IN NS
                      10800 IN NS
                      10800 IN NS
                      10800 IN A
                      10800 IN MX     10
                      10800 IN TXT    "v=spf1 +mx -all"
                      10800 IN CAA    128 issue ""

Network Performance tools

brew install iperf iperf3 nuttcp bwctl owamp
  • iperf -s -i 4 -w 5m
  • iperf -i 4 -t 1000 -N -w 5M -l 1M -c [servername]
  • iperf3 -s -i 5
  • iperf3 -i 4 -t 1000 -N -w 5M -l 1M -c [servername]
On the server:
  • nuttcp -S
  • nuttcp [servername]
This runs a 10 second test, only on ipv4

SSH on a different port number

This procedure and port numbers come from:
  • sudo vi /etc/services
    • Change the port number in:
    • ssh 22/udp # SSH Remote Login Protocol
    • ssh 22/tcp # SSH Remote Login Protocol
  • sudo vi /etc/ssh/ssh_config
    • uncomment the following: Port 22
      and change that port number in the desired one.
  • Restart the ssh daemon.
  • sudo launchctl unload /System/Library/LaunchDaemons/ssh.plist
  • sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

SSH tunnel for e.g. VNC. Here we assume ssh over port 12345. After this tunnel setup one can ust vnc to to reach the other machine:

  • ssh -p 12345 -v -L 5901: destination


Note: DOES NOT WORK BECAUSE OF incompatible caching regimes!
  • brew install php
To enable PHP in Apache add the following to httpd.conf and restart Apache:

    LoadModule php7_module /usr/local/opt/php/lib/httpd/modules/

    <FilesMatch \.php$>
        SetHandler application/x-httpd-php

Finally, check DirectoryIndex includes index.php
  • bbedit DirectoryIndex index.php index.html
The php.ini and php-fpm.ini file can be found in:

To have launchd start php now and restart at login:
  • brew services start php
Or, if you don't want/need a background service you can just run:
  • php-fpm

MacMini Setup (for SC/webcam/demo)

  • Users & Groups
    • SNE-Admin
      • sne-admin
    • SNE-demo
      • sne-demo
    • Login Options
      • auto login sne-demo
  • Power settings
    • never sleep computer
    • restart after power fail
    • prevent display sleep
    • awake with net access
    • start up 8h00 in the morning
  • Desktop & Screen Saver
    • no screen saver
  • Sharing
    • Screen Sharing
    • File Sharing
    • Remote login
  • Security
    • turn off screen lock
    • enable location services
    • no filevault
  • Date & Time
    • automatic time adjustment
  • Display and WebCamMonitor App
  • MenuMeters
  • BBEdit
  • Deskpicture SNE logo
  • Team Viewer Setup
  • EvoCam Setup
    • Evocam5 download
      • serial ES56-MUDX-9LD6-BRAG
      • Note:
        • EvoCam 4 crashes now and then but does recording fine!
        • EvoCam 5 is more stable but gives unusable recordings!
        • note that sometimes the high res recording looks like taken at low res!
          Make sure to open first the small and then the big window.
    • Settings
      • Preferences
        • web server port nr 10456
        • Log Web Server access
        • auto-open docs from previous session at startup
        • make sure the low res is in the back.
        • Finder Cam1.settings on desktop put in dock and set Open at login
        • 320 * 180
        • 384 * 216
        • 480 * 270
        • font size 12
        • framerate 15
        • quality normal normal
        • fontsize 9
      • Cam2.evocamsettings
        • 1280 * 720
        • framerate 15
        • quality normal normal
      • Other resolutions 16*9
      • 256 * 144 -> YouTube 144p
      • 426 * 240
      • 640 * 360 -> nHD
      • 768 * 432
      • 800 * 450
      • 848 * 480
      • 896 * 504
      • 960 * 540 -> qHD
      • 1024 * 576
      • 1152 * 648
      • 1280 * 720 -> HD
      • 1366 * 768 -> WXGA
      • 1600 * 900 -> HD+
      • 1920 * 1080 -> Full HD
      • 2000 * 1125
      • 2048 * 1152
      • 2304 * 1296
      • 2560 * 1440 -> QHD
      • 2880 * 1620
      • 3200 * 1800 -> QHD+
      • 3520 * 1980
      • 3840 * 2160 -> 4K UHD
      • 4096 * 2304 -> Full 4K UHD
      • 4480 * 2520
      • 5120 * 2880 -> 5K UHD
      • 5760 * 3240
      • 6400 * 3600
      • 7040 * 3960
      • 7680 * 4320 -> 8K UHD
      • 15360 * 8640 -> 16K
      • NOTE: the low resolution serve must start first, then the high resolution, otherwise video is low quality.

TimeMachine Problem Solving

The procedures come from:,08,27,169,fix-time-machine-sparsebundle-nas-based-backup-errors.html

This procedure is to correct errors like: “Time Machine completed a verification of your backups. To improve reliability, Time Machine must create a new backup for you.”. It may or may not work.

The steps:
  • sudo chflags -R nouchg /Volumes/<PathTo+Name>.sparsebundle
  • sudo hdiutil attach -nomount -noverify -noautofsck /Volumes/<PathTo+Name>.sparsebundle
  • sudo tail -f /var/log/fsck_hfs.log
  • sudo fsck_hfs -drfy -c 4294967296 /dev/diskXs2

or take for cacjhe 3221225472 or 2147483648 or 1073741824

If you get a message in the fsck_hfs.log along the lines of " RebuildBTree – record x in node y is not r" then try:
  • fsck_hfs -p /dev/diskXs2
  • fsck_hfs -drfy -c 4294967296  /dev/diskXs2

To scan for bad blocks:

  • /sbin/fsck_hfs -S /dev/diskXs2
When succeeded:
  • hdiutil detach /dev/diskXs2
When complete, you need to edit an plist file within the sparsebundle that records the state of the backup. On the top level of the sparsebundle find a file called "". Edit it and remove these two nodes:



Finally you want to change:


Now Time Machine can give it another go. After the (long) verification step, backups should proceed once again.

To find log file entries:
  • log show --predicate 'subsystem == ""' --info | grep 'upd: (' | cut -c 1-19,140-999

How to solve calendar problems

How to solve the error: "Apple Calendar Can’t Save Event to Exchange":


  • Quit Calendar application (Command + Q)
  • Quit Apple Mail
  • Open Activity Monitor (through Spotlight or Launchpad)
  • Search for “Calendar” and quit all the relevant processes
  • Open Finder and navigate to ~/Library/Calendars
  • Double-check Activity Monitor to make sure no Calendar-related processes are running
  • Delete cache files
  • Relaunch Calendar

How this page is made