If you’re using a static site generator like Jekyll or Grow (recommended), you know that commands like jekyll serve or grow run will spin up local web servers that allow you to live develop and preview your static site. Unfortunately, these generators don’t create a secure context behind an HTTPS domain, something I need often to test PWA features or certain AMP tags.

Fortunately, I did some digging and found a pretty good workaround for Mac OS X (probably works similarily on Linux). As a bonus, we’re adding a custom local domain (vhost). Here’s how it works:

1. Setup SSL on your local Apache

Follow this excellent tutorial by Jonathan Neal to setup SSL in your local Apache (make sure you’ve already generally enabled it).

2. Add mycustomdomain.dev (whatever you want to call it) to your hosts file

Right now, your OS thinks that mycustomdomain.dev is just an ordinary website, and tries to resolve it via DNS. We want to override that behavior so it always redirects to the local Apache. For that, open the hosts file at /etc/hosts, then add this line to it and save:

127.0.0.1       mycustomdomain.dev

3. Reserve proxy to your static site server

At this point, you should be able to navigate to https://mycustomdomain.dev (or whatever you called it) and it should show you the contents of the DocumentRoot that you’ve specified following the tutorial in Step 1. That’s because the VirtualHost we’ve setup uses a wildcard and will happily answer with your localhost.

This is however not what we want – we want it to behave as if it opened http://localhost:8080 instead (or whatever port your site generator serves your pages from). In order to do this, we’ll have to reverse proxy.

3.1 Load additional Apache plugins

Open /etc/apache2/http.conf and uncomment the following modules (they’re probably not all required, but I forgot which are):

LoadModule proxy_module libexec/apache2/mod_proxy.so
LoadModule proxy_connect_module libexec/apache2/mod_proxy_connect.so
LoadModule proxy_ftp_module libexec/apache2/mod_proxy_ftp.so
LoadModule proxy_http_module libexec/apache2/mod_proxy_http.so
LoadModule proxy_fcgi_module libexec/apache2/mod_proxy_fcgi.so
LoadModule proxy_scgi_module libexec/apache2/mod_proxy_scgi.so
LoadModule proxy_wstunnel_module libexec/apache2/mod_proxy_wstunnel.so
LoadModule proxy_ajp_module libexec/apache2/mod_proxy_ajp.so
LoadModule proxy_balancer_module libexec/apache2/mod_proxy_balancer.so
LoadModule proxy_express_module libexec/apache2/mod_proxy_express.so

3.2 Redo SSL certificate generation from above, with new domain name

We need a new cert file for the custom domain. When you again create the localhost.conf file (name it mycustomdomain this time), you might want to change:

[alt_names]
DNS.1 = localhost
DNS.2 = *.localhost

to:

[alt_names]
DNS.1 =mycustomdomain.dev
DNS.2 = *.mycustomdomain.dev

and in the next step, you want to change

sudo openssl req -new -key /etc/apache2/ssl/localhost.key.rsa -subj "/C=US/ST=California/L=Orange/O=IndieWebCamp/CN=localhost/" -out /etc/apache2/ssl/localhost.csr -config /etc/apache2/ssl/localhost.conf

to

sudo openssl req -new -key /etc/apache2/ssl/localhost.key.rsa -subj "/C=US/ST=California/L=Orange/O=IndieWebCamp/CN=mycustomdomain.dev/" -out /etc/apache2/ssl/mycustomdomain.csr -config /etc/apache2/ssl/mycustomdomain.conf

Where mycustomdomain is really anything you want. Note that I didn’t recreate localhost.key.rsa, this one can stay the same.

3.3 Add a new VHost configuration for your custom domain

Open /etc/apache2/extra/http-vhosts.conf, the add the following configuration:

<VirtualHost *:443>
    DocumentRoot "/Users/yourusername/Sites"
    ServerName mycustomdomain.dev
    SSLEngine on
    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
    SSLCertificateFile /etc/apache2/ssl/mycustomdomain.dev.crt
    SSLCertificateKeyFile /etc/apache2/ssl/localhost.key

    ProxyRequests Off
    SSLProxyEngine On

    <Proxy *>
      Order deny,allow
      Allow from all
    </Proxy>

    ProxyPass / http://localhost:8080/
    ProxyPassReverse / http://localhost:8080/
    <Location />
      ProxyPassReverse /
      Order deny,allow
      Allow from all
    </Location>
    Header edit Location ^http://localhost:8080/ https://localhost:8080/

</VirtualHost>

4. That’s all!

When you run something like jekyll serve, you should now be able to navigate to https://mycustomdomain.dev and it should open the proxied site, with a green lock.