Local development with Sitevision on macOS

I need to set up a local development environment often enough so that I forget until the next time. This article is mostly for me, but might help others as well.

In this article, I will describe how to:

  • Set up a top-level domain for local development.
  • Install Java 8.
  • Download and install Sitevision.
  • Set up a self-signed certificate for Sitevision.

The packages will be installed using Homebrew, which is a package manager for macOS. I strongly recommend it for its simplicity.

Homebrew

Using Dnsmasq for the top-level domain .test

Managing local domains in your /etc/hosts file works but can quickly get out of hand. Avoid this problem by using Dnsmasq and set up a dedicated top-level domain for all local development projects.

I have chosen the top-level domain .test, which is reserved for testing purposes. It is therefore unlikely to be bought and repurposed, as .dev was by Google. Fingers crossed!

Use the shell commands below to:

  • Install Dnsmasq.
  • Modify the default configuration file to include all configuration files in the directory /opt/homebrew/etc/dnsmasq.d.
  • Create a configuration file in there called test.conf to handle our top-level domain.
  • Create a resolver configuration so Dnsmasq is used before any other DNS server.
  • Start the Dnsmasq service.
# Install dnsmasq
brew install dnsmasq

# Make sure etc folder exist in brew dir
mkdir -pv $(brew --prefix)/etc

# Append custom configuration to end of 
# default config file (dnsmasq.conf)
echo "\n\n# Custom configurations\ndomain-needed\nbogus-priv\nconf-dir=$(brew --prefix)/etc/dnsmasq.d/,*.conf" >> $(brew --prefix)/etc/dnsmasq.conf

# Create a separate dnsmasq config file for 
# our TLD .test (dnsmasq.d/test.conf)
echo "address=/test/127.0.0.1" > $(brew --prefix)/etc/dnsmasq.d/test.conf

# Create a resolver config for our TLD .test
sudo mkdir -v /etc/resolver
sudo bash -c 'echo "nameserver 127.0.0.1" > /etc/resolver/test'

# dnsmasq seems to need sudo? Probably due to 
# running on port 53 (privileged port).
# You might want to try without sudo first.
sudo brew services start dnsmasq

You should now have all domains under the top-level domain .test redirected back to your local machine.

Java Development Kit via Homebrew

To run Sitevision locally, you need to have Java 8 installed. Of all the available distributions, I chose Eclise Temurin from Adoptium. It is easy to install and works out of the box on my M2 MacBook Air.

As a side note, Sitevision themselves seem to use Corretto from Amazon, making it a valid choice. I did try it but got stuck on an issue that halted the startup process of Sitevision on macOS.

So take the simple route. Use these two shell commands to install Eclipse Temurin via Homebrew:

# Add cask versions repository 
# so we can install older jdk version
brew tap homebrew/cask-versions

# Install Eclipse Temurin (v8) which is 
# the name of Adoptium's OpenJDK distribution
brew install --cask temurin8 # or corretto8

Local installation of Sitevision

To download Sitevision, you will first need to have an account. Find further instructions here:

How to create an account

When you have an account download Sitevision from here:

Download Sitevision (Swedish, requires login)Download Sitevision (English, requires login)

Follow the steps at the download page, and download the distribution files for macOS. Extract the contents of the tar archive to /opt/sitevision.

Now, to start Sitevision in the foreground, use:
sudo /opt/sitevision/bin/sitevision console

This will trigger FileVault on some files which need to be accepted for Sitevision to run.

When all is up and running, visit localhost/edit and set up your first website.

Since Sitevision was started in the foreground, you can stop it simply by sending a SIGINT with CTRL + C.

Self-signed certificate, Tomcat KeyStore, and Java TrustStore

Using HTTPS for local development might not be needed, but in some cases, it makes sense. For instance:

  • To prevent issues with mixed content.
  • When using HTTP/2.
  • When required by third-party libraries.
  • When working with secure cookies.
  • To have better parity between the development and the production environment.

Sitevision is built with Java and uses a KeyStore and a TrustStore.

The server application, Tomcat, uses the KeyStore to support secure connections between the client and the server. And Java uses the TrustStore to determine if a requested server has a valid certificate.

By default, temurin8's TrustStore contains around 140 trusted certificates. And of course, our yet-to-be-created self-signed certificate is not among them.

So let's say you only create and set up a self-signed certificate in the server KeyStore. With that, you would get HTTPS support for the clients connecting to your site. But if you would try to fetch a resource from your site with Java, you would get an exception similar to this:

SSLHandshakeException for URL https://sitevision.test/rest-api/1/1/Sitevision/nodes, cause: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

And this is why you would also need to import the certificate into the TrustStore. Use the shell commands below to:

  • Create a new KeyStore with a certificate for the domain sitevision.test.
  • Export the certificate from the KeyStore.
  • Import the certificate into the TrustStore, and your login keychain in macOS.
# Create the folder which we will place 
# our keystore and cert in
mkdir ~/.sitevision

# Generate KeyStore including a certificate for 
# the domain "sitevision.test"
keytool -genkey -keyalg RSA -keysize 2048 -noprompt -alias tomcat -dname "CN=sitevision.test, OU=NA, O=NA, L=NA, S=NA, C=NA" -ext "ExtendedKeyUsage=serverAuth,clientAuth" -ext "SAN=DNS:sitevision.test,DNS:localhost,IP:127.0.0.1" -keystore ~/.sitevision/sitevision-keystore.p12 -storetype pkcs12 -validity 9999 -storepass changeit -keypass changeit

# Export certificate from KeyStore 
# and into same folder
keytool -exportcert -rfc -keystore ~/.sitevision/sitevision-keystore.p12 -storetype pkcs12 -storepass changeit -alias tomcat -file ~/.sitevision/sitevision.test.pem

# Import certificate into Java TrustStore 
# so Java (and Sitevision) accepts our self-signed 
# certificate. This will allow https requests 
# from within Sitevision to our test domain.
sudo keytool -import -noprompt -trustcacerts -alias tomcat -file ~/.sitevision/sitevision.test.pem -keystore $(/usr/libexec/java_home)/jre/lib/security/cacerts -storepass changeit

# Add certificate to login keychain
sudo security add-trusted-cert -d -r trustRoot -k $(security login-keychain | xargs) ~/.sitevision/sitevision.test.pem

The next step is to update Sitevision's Tomcat configuration. You can usually find it here: /opt/sitevision/tomcat/conf/server.xml.

Find <Certificate /> with a link to the default KeyStore. It should look something like this:

<Certificate
   certificateKeystoreFile="webapps/ROOT/WEB-INF/keystore/sitevision_default.keystore"
   certificateKeyAlias="tomcat" certificateKeystorePassword="changeit" />

Comment out or remove the existing tag and insert a new one with your own KeyStore. And make sure you use the absolute path to your custom KeyStore. It should look something like this:

<Certificate
   certificateKeystoreFile="/Users/hampus/.sitevision/sitevision-keystore.p12"
   certificateKeyAlias="tomcat" certificateKeystoreType="PKCS12" certificateKeystorePassword="changeit" />
<!--<Certificate
   certificateKeystoreFile="webapps/ROOT/WEB-INF/keystore/sitevision_default.keystore"
   certificateKeyAlias="tomcat" certificateKeystorePassword="changeit" />-->

And that is it!

Restart Sitevision if it is already running, and you should be good to go.