Quick tangent this week, then back to the puppet show!

We launched a website this past week.  I’d love to say we were able to use all the cool new deployment tools, but for various reasons (stack choice, database connectors, developing and deploying on Windows, major version and architecture updates), it just wasn’t possible.  So, we had to shut down the old server, remotely log in, make some upgrades and update some versions, cross our fingers, and re-start.

Always a risky procedure.  Particularly with a two person team.  Really a one and a half person team.  I do a bit of dev ops, but am mostly a Javascript guy.  Apache config files aren’t really my sweet spot.

My partner on this was updating Django versions, then trying to install the right db connector to work with SqlServer.  It was tricky, but eventually he got there.  I updated Node, built our Angular application, and deployed the front end server.  For the most part, it worked, but there were a few ‘gotchas’.

One involved enabling https.  This was something we didn’t test in development- we have one SSL certificate and it was in use for the production site.  Enabling it on the Express server was simple enough, but I didn’t realize that there were 3 important parts.  The key, the certificate (got both those), and the chain.  Most modern browsers only need the first two, but some require the chain (I’m looking at you, Firefox on Mac).  The chain needs to be split on newlines in Node to work.  But we got past that hurdle after a bit of frantic Googling.

The other interesting one involved server side rendering our Angular application.  Like most modern JS apps, ours uses some 3rd party libraries.  We could never get Angular’s built in SSR to work (though we are still trying), so we’re using a 3rd party service to do the render.  Our server contacts that 3rd party’s servers, gets the rendered version of a page, and returns it (and then the SPA loads and takes over).  Google’s spiders are happy.  But our users aren’t- they just had to wait over 2 seconds to get a page.  However, we can store those renders in a local cache, so on any subsequent visit, it’s blazing fast again (I’m documenting the crawl and storing of those in the Puppeteer series- see entry one from last week- it’s super fun!).

Back to the related launch issue: we were getting cross origin request errors.  But only if the url included ‘www’.  For example: if I went to domain.tld, our site loaded, it made a delayed https call to our internal news article api, loaded those, and everything was great.  But if I went to http://www.domain.tld, boom- CORS error.  The error referenced a disallowed header.

The lesson this reinforced was to use your dev tools.  I hit F12 and checked the network tab.  Clicked the red response and inspected the request and response headers.  Then I made a successful (no ‘www’) request and compared those.  The ‘www’ request was getting an extra header related to the prerendering service (still not sure why it wasn’t present on all requests).  So, on our Apache server (running the news API- which just returns JSON), we just had to add that header to the allowed list.  I definitely don’t have that command memorized, but once I knew exactly what I was Googling for, it took about 2 minutes to find and implement.

Use your dev tools.  Words to live by in this business.  When something doesn’t work, there’s always an answer- particularly in this world where everything is online.  Dev tools help narrow down that search.  I went from a panic search of “site works without ‘www’ but not with ‘www'” to “apache configuration allow headers”.  The first got me nothing useful.  The second solve my problem almost immediately.