Johnathan.org

Showing only: Posts

College and the Fear of Change

An Internet friend of mine, John Saddington, created a blog post about College that really got me thinking. The purpose of this post is to share some of those thoughts.

I spent 8 years, off-and-on getting my Bachelor of Science degree. I hopped around a few schools and could never really find my groove until 2013 when I landed at Western Governor’s University. Looking back on it, I wish I had done things a lot differently. Namely, just getting a basic Associates degree and transferring would have saved me a lot of time and money.

Getting my degree from an online not-for-profit, I feel like I missed out on some of the interactivity and community-building. You hear stories about how someone spent time in a fraternity/sorority, was a part of X, Y, and Z clubs, and did all these cool things with people they shared dorm buildings with. Would I have been super active in all that? Probably not, but there’s a definite networking aspect to college that one might not ever get by taking alternative paths, depending on the alternative path they take. As much as we don’t want this to be the case, some recruiters and hiring managers see degrees as an indicator that this person was able to complete a long-term project/commitment successfully.

Putting all the fluffy parts aside, there’s a part I still struggle with when thinking about the amount of time I spent on my education. I can’t help but wonder if it’ll make a difference at this point. My degree is in Information Technology. It came with a handful of industry certifications that say on pieces of paper that I know enough about a list of topics to qualify for said pieces of paper. I learned most of that information not from my college studies, but from the real world. Learning as I went. Doing. Getting things wrong. Fixing them. Getting things right. Repeat.

That’s not to say the education I received would not have been valuable to someone. I know for a fact that some find it entirely useful, though I imagine that’s more because of the material than how it was delivered. There’s nothing unique about the delivery method. Alternative forms of education exist and should be encouraged. The idea that a college is the only way to learn a certain set of skills is a tired one, even considering hands-on training.

This thought process creates a very fine line, though. No one paid close enough attention and “schools” like DeVry and ITT Tech popped up, promising quality educations. Most of the time, the only thing that happened was the student ended up being out of way too much money for an education that didn’t mean anything.

How do we find a solution to this that involves both breaking the mold and maintaining quality, trustable educational pathways?

Are coding bootcamps the answer? Probably not. There’s no good set of standards for ensuring it’s not just a $10 Udemy course wrapped in a $14,000 tuition price tag. We just trust that because they have a building and teachers and dedicated learning times that it’ll be something that just works. We’re trading one set of problems for another.

Most of this got John and I talking about the hard requirement aspect of some careers. Right now, in order to become a lawyer, you have to go to school, take a test, go to another school, and become a member of the Bar Association. Without that, no lawyering for you. Are we sure that’s still the best way to make such a career happen for someone? Obviously everything up to the Bar Association admission is useless without said admission if the goal is to be lawyering your way around a court room, so what if we could change some of that? Why is it important for someone to go to Harvard if they want to work for a quality firm? (This is part rhetorical, part genuine question).

Technology has the power to change the way we learn and establish ourselves. There’s nothing that says the way things are will stay the same forever–literally all of society is a great example of that. Innovation and disruption are a required component of moving forward as a society and sometimes (a lot of times) it also comes with some discomfort. There are always individuals who wish to keep the status quo. It’s a comfortable position to take. I’m guilty of this sometimes, too.

There isn’t one right answer, here, and whatever form this disruption takes, my generation won’t likely be around to see it. I hope my children are offered more unique and high quality opportunities than I had. In fact, if they exist, I want to encourage them. One should be able to do whatever they so desire and establish themselves along the way in the manner and format they see fit. If that means spending time in a classroom, learning from pre-defined sets of materials in a certain order or if that means a virtual environment that includes hands-on training at an affiliated location, it all sounds good to me. If 100% of it was real-world, apprenticeship-style learning right next to the CEO of a Fortune 500 company, that’s also fantastic!

I say yes to all of it! Put those who wish to excel in business next to those who have actually excelled in business, not just in a classroom. if someone wants to become an expert in animal husbandry, they should learn from the experts themselves.

Education is education and education is valuable. We should be finding as many ways to enhance that value as possible.

All the iPhone XS and XS Max Reviews in One Place

Launch day for the iPhone XS is tomorrow. While we wait, it seems only pertinent to round up all the reviews for the iPhone XS and share them in one page. 

Note: I didn’t bother splitting them out by XS and XS Max. There is no need. Both phones are the same except for their size. It doesn’t make sense to differentiate them just as little as it makes sense to review two different sizes of the same model television. 

Thoughts and Observations on Apple’s Event

Yesterday, John Gruber of Daring Fireball and The Talk Show fame posted a dissemination of the goings on from Apple’s iPhone XS/XS Max/XR and Watch Series 4 event last Tuesday. I read the whole thing and a few things absolutely jumped out at me and I wanted to cover them, here. 

The space

Last year, John talked about the new Steve Jobs theater. This year, he reminisced on the entire idea of having these kinds of events at such an exclusive location:

[W]hat the Steve Jobs Theater provides that no venue in San Francisco ever could is seclusion. Apple Park really feels like it is its own world. Putting “Park” in the complex’s name was exactly right. In terms of sight lines and feeling like you’re isolated from the rest of the world, the effect is very similar to being in one of the theme parks at Walt Disney World. As you walk the pathway uphill from the Visitor Center to the theater, ambient music plays from hidden speakers. The only thing man-made you can see from the pavilion atop the Steve Jobs Theater is Apple Park’s Ring building, seemingly on the horizon.

One hundred percent. I can imagine the level of detail Apple went into to create a space that didn’t feel like _just an ordinary event venue_. Anyone can hold a press conference at a hotel, expo/convention center, or stadium. Apple has to do it their own way. In these reveals, Apple strives for intimacy, to make you feel like it’s just you and Tim, Phil, and the gang. There’s no way they could pull off that range of emotions in a place like Moscone.

John goes on to mention that they hold but a couple events there a year. From Apple’s perspective, that’s absolutely acceptable. This space wasn’t meant to be a place where something is discussed every six weeks. I can imagine the company doesn’t even hold much in the way of internal events there. The Steve Jobs Theater is an architectural expression of Steve Jobs himself.

The Watch

Both John and I agree the Watch stole the show. Hands down the Watch quickly became the biggest deal this year. A reduction yet increase in size (thickness versus screen dimensions and pixels), ECG, improved cellular (thanks to the ceramic back), new faces that took complication display to the next level, and probably the single coolest feature of all: the I’ve-fallen-and-I-can’t-get-up mode. Fall and stay still for one minute and the Watch will summon either emergency services or an emergency contact. How freaking cool is that? It seems like a no brainer, but detecting a fall reliably is hard… calling is easy.

The Series 4 displays take up so much more of the face of the watches that the new 40mm watch’s display is larger than the display on the old 42 mm models — the new small watch has a larger display than the old large watch.

This is actually a struggle for me, now. I know for a fact that I want one of these, but because of the size changes… I don’t know which one. I’ll have to wait patiently and see how they fit in the store starting this upcoming Friday the 21st. If I could manage to work my way into a 40mm, instead, I’d be extremely happy. The 44mm is a not insignificant amount more expensive than the 42mm of the same configuration was. 

I’m a little bummed to see no Edition this year. The white ceramic Edition looked super clean. I pictured it with a white link band, too, and almost caved. I’m glad I didn’t though because resell values for Editions are trash. Still, I can admire from a distance.

The iPhones

It should be plainly clear by now that Apple has no interest in updating their budget phone line. Each of the new models all slot into the formerly-premium and really premium categories. The iPhone XR is the most interesting, though I wish they would have chosen to make it smaller, more like the iPhone 8. I’d be curious to see how many people end up with one compared to an iPhone 8 now, or one of the lesser iPhone XSes. 

Oh, that name? What the hell were they thinking?

A Roman numeral is hard enough. But to put two alphabetic characters next to each other and expect people to treat one as a Roman numeral and the other as a letter is too much. They look like ex-arr and ex-ess so people are naturally going to see them and say them as ex-arr and ex-ess.

Yes. Yes. Yes. A year later, I still have people asking me how to pronounce it. They know I’ll know because I’m the “Apple guy,” but they shouldn’t have to. No one actually knows where the X = ten naming scheme originated (OS X) so how are they supposed to draw the conclusion that Apple opted to name the iPhone similarly? 

Hell, I even have a hard time just saying the words “iPhone Ten Ess Max” out loud without having to repeat myself; more often than not I get tongue-tied or end up saying something like Ten Ex Max. I hope that marketing person was fired.

Naming aside, the internals of the XS and XS Max are pretty dang good. I love to see steady incremental improvements to hardware and Apple seems to know how to deliver on that front (at least from the perspective of mobile devices… let’s not discuss the MacBook line). This–and because I wanted the gray model this time–is why I went for it. 

Also important: AirPower

I had almost entirely forgotten about it. AirPower was supposed to drop this year and while the year isn’t over, it seems Apple has just about nothing to say at this point:

I wrote about AirPower’s absence earlier this week. What I’ve heard, third-hand but from multiple little birdies, is that AirPower really is well and truly fucked.

Not surprising. The idea that one would have several heat-generating power exchanges in such a small space really blew my mind. My single iPhone gets hot when charging on its mat. If it gets bumped out of alignment, it gets fucken hot and doesn’t even charge. Who knows what the hell is going on on the inside but it can’t be good. 

Now imagine that being a possible scenario on a single pad, one that’s also supposed to charge an Apple Watch using whatever proprietary method it charges, now.

The result? 

Something about the multi-coil design getting too hot — way too hot. There are engineers who looked at AirPower’s design and said it could never work, thermally, and now those same engineers have that “told you so” smug look on their faces.

Oh well. It was a nice idea. Maybe someday? I’d still like Qi-capable AirPods, though. I’d go for that. 

 

I glossed over a lot of Gruber’s discussion so go check out the the rest of his piece. It’s informative and definitely worth reading. 

On Deciding to Buy the Next iPhone

For those who aren’t aware, I own an iPhone X 256GB in White (it’s more like a dishwater-white, but that’s another story). When the iPhone Xs was announced, at first I reacted with “I have to have this”, followed up with “I think I’ll find it useful.” 

This is the first year in the years I’ve owned iPhones that I haven’t been able to come up with a laundry list of reasons why I’d want the next iPhone. To be clear, I’m still buying it (and in fact, I did–I bought an iPhone Xs 256GB space gray), but I had to think about it a bit more.

I’m ok with this, overall. It’s entirely healthy to question such a large purchase and outside of “having the latest and greatest just because”, not opting to dive in right away is a smart move. In the end, I could only come up with a few reasons why I wanted this year’s model, and really these were enough to get me to bite the bullet:

  • Change out the dishwater-white for space gray. I might regret this color choice if it turns out the white is now white-white.
  • Photo processing capabilities. I was entertained and convinced by the new photo capability the iPhone Xs will have, I assume thanks to software and its updated A12 Bionic chip with the faster Neural Engines.
  • Better sensor. The pixels are closer together by way of being larger (the sensor itself is the same size) and they’re “deeper,” whatever that means. I can appreciate the former, for sure. 
  • The A12 chip in general. I can always get behind the idea of a faster processor. 

After this phone has spent a year in my possession, unless Apple announces something riveting or presents unique new features, I’m not sure I’ll stick to the yearly upgrade cycle. 

This goes for the Watch, too. I plan on buying the Series 4 Cellular, but I don’t know which size, yet. Given the cases are different–I wear a 42mm now–I don’t know if the 44mm will be too big or if the 40mm will be too small. Technically, the 40mm screen size is larger than the 42mm, so that’s something to sway me in that direction–and toward a cheaper watch. I’ve longed for more at-a-glance-capable data on my watch face and that’s about it. My battery life is pretty dang good–I can go two days easily without charging, three if I use Power Reserve mode at night. Unless the Series 5 is fundamentally different as well, I can’t see myself grabbing one. Then again, if they make the steel case cheaper–I want one now, but turned off by the price–that might be enough. 

I am an Apple sheep, as some would say, and I’m okay with that. I also know that when there’s no net new value to be had in a device I’m buying, I’m likely to hold off. That’s not to say I won’t buy one ever… maybe just not on launch day.

Review of Today’s Apple iPhone and Watch Announcements

Apple’s two-hour event didn’t disappoint, though there was little surprise when it came to the design. Here’s some of the most important points to take away from today’s event.

 

Apple Watch

  • The Series 4 will come in two sizes: 40mm and 44mm. This measures the case size, which lines up with Apple’s explanation that the screen is 32% and 35% larger, respectively, while also being a bit thinner.
  • Battery life appears to be roughly the same as the previous generation.
  • Series 3 will fall into the slot of the low-end Watch offering.
  • All existing watch bands will fit the Series 4.
  • Watch faces will be more highly customizable with complications from both Apple and 3rd-party developers. Some faces will feature more extensive complication arrangements, too.
  • The Watch will be able to more closely track heart behaviors and optionally notify emergency services if a fall event occurs where medical attention is required.
  • Pricing will break down as follows (all US dollars; 40mm/44mm; sport bands):
    • Aluminum GPS: $399 / $429; GPS + Cellular: $499 / $529
    • Stainless Steel GPS + Cellular: $699 / $749 (no GPS-only option available)
  • Availability: pre-order starting September 14th, Available starting September 21st.

Apple iPhone

Three iPhones were discussed during today’s Apple event: the iPhone Xs, iPhone Xs Max, and the iPhone Xr.

 

iPhone Xs

The replacement for Apple’s prior flagship phone, the iPhone Xs will ship with the same dimensions and a whole host of improvements:

  • Face ID will be quicker to respond and unlock, though they did not explain how much faster.
  • A third color option, gold, will join the white and space grey options being carried forward.
  • 5.8″ Super Retina screen at 2436×1125 pixels and 458 pixels per inch (ppi), the highest density of any smartphone currently on the market; wide color gamut (P3).
  • Weight: 6.24 ounces (177 grams)
  • Dimensions (H x W x D): 5.65 in (143.6mm) x 2.79 in (70.9mm) x 0.30 in (7.7mm)
  • New A12 bionic chip with:
    • 6-core processor with
      • 4 high-efficiency cores that are up to 50% more energy efficient
      • 2 high-performance cores that are up to 15% faster than the A11 Bionic)
    • 4-core GPU that’s up to 50% faster than the A11 Bionic
    • 8-core 5 Trillion ops/second Neural Engine that performs up to 9x faster than the A11 Bionic
  • Updated camera with better edge detection and image capture for Smart HDR and after-the-fact adjustable depth-of-field, as well as stereo audio capture for video recordings.
  • IP68-rated splash, dust, water resistance (up to 2 meters for up to 30 minutes)
  • 12MP wide-angle f/1.8 aperture and telephoto f/2.4 aperture cameras
  • 7MP front-facing f/2.2 aperture camera
  • Support for FDD-LTE bands 1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 29, 30, 32, 66, 71, and TD-LTE bands 34, 38, 39, 40, 41, 46
  • Gigabit-class LTE with 4×4 MIMO and LAA
  • 802.11ac WiFi with 2×2 MIMO
  • Bluetooth 5.0
  • NFC with reader mode
  • Battery life extension of up to 30 minutes over the iPhone X which amounts to:
    • 20 hours talk time
    • 12 hours Internet use
    • 14 hours video (wireless)
    • 60 hours audio (wireless)
  • Dual SIM support (1 physical sim, 1 e-SIM; dual physical SIM for the Chinese market only)
  • Pricing:
    • 64GB: $999
    • 256GB: $1,149
    • 512GB: $1,349
  • Availability: pre-order starting September 14th, available starting September 21st.

 

iPhone Xs Max

A new, larger variant of the iPhone Xs, it’ll ship with everything the iPhone Xs does along with:

  • 6.5″ Super Retina Screen at 2688×1242 pixels and the same 458 pixels-per-inch (ppt) depth.
  • Weight: 7.34 ounces (208 grams)
  • Dimensions (H x W x D): 6.20 in (157.5mm) x 3.05 in (77.4mm) x 0.30 in (7.7mm)
  • Battery life extension of up to 1.5 hours compared to the iPhone X (not the iPhone 8 Plus) which amounts to:
    • 25 hours talk time
    • 13 hours Internet use
    • 15 hours video (wireless)
    • 65 hours audio (wireless)
  • Pricing:
    • 64GB: $1,099
    • 256GB: $1,249
    • 512GB: $1,449
  • Availability: same as iPhone Xs

 

iPhone Xr

The new entry in the iPhone X lineup. Some features will be the same as the iPhone Xs/Xs Max. Here’s what’s different or new:

  • 6.1″ Liquid Retina display with a wide color gamut (P3) and true-tone support, 1792×828 pixel resolution at 326 pixels-per-inch (ppi; Retina)
  • Six colors:
    • (PRODUCT)RED
    • Yellow
    • White
    • Coral
    • Black
    • Blue
  • Weight: 6.84 ounces (194 grams)
  • Dimensions (H x W x D): 5.94in (150.9mm) x 2.98 in (75.7mm) x 0.33 in (8.3mm)
  • IP67-rated splash, dust, water resistance (up to 1 meter for up to 30 minutes)
  • 12MP wide-angle f/1.8 aperture rear camera
  • 7MP front-facing f/2.2 aperture  front camera
  • Support for FDD-LTE bands 1, 2, 3, 4, 5, 7, 8, 12, 13, 14, 17, 18, 19, 20, 25, 26, 29, 30, 32, 66, 71, and TD-LTE bands 34, 38, 39, 40, 41
  • LTE Advanced support
  • Battery life extension of up to 1.5 hours more than the iPhone 8 Plus
    • 25 hours talk time
    • 15 hours Internet
    • 16 hours video (wireless)
    • 65 hours audio (wireless)
  • Wireless charging (Qi)
  • Single SIM
  • Pricing:
    • 64GB: $749
    • 128GB: $799
    • 256GB: $899
  • Availability: pre-order October 19th, available starting October 26th

Other things

  • The iPhone 6s/SE have been discontinued. The new previous-generation low-end phone is now the iPhone 7. The iPhones 7 and 8 received price reductions to starting points of $499 and $599, respectively.

A Potential Solution to Our Social Network Problem

I haven’t spent much time publicly discussing the idea of alternatives to social networks. Luckily, Manton Reece did which served as a great jumping off point for this post. I won’t re-hash too much of Manton’s discussion because it’s entirely worth reading on its own but he did mention a couple things that I feel like is worth mentioning here.

Manton broke down what it would take for us, as a collective to free ourselves from the monolithic nature of our current social network landscape. He’s been on this train for a while and with good reason. Micro.blog, the microblogging community/platform is his doing and exists because at the end of the day, we should spend more time crafting our content using less-specific and more ambitious platforms. To those who travel in the own-your-own-content circles, this is known as POSSE. 

That’s not the topic of this post, though he does touch upon that. The biggest takeaway I have from this post is that our social networks should be smaller, not larger. It’s a tough idea to wrap one’s head around when you think about why people end up on the networks the do in the first place and you have a pretty large hurdle.

Looking back on how I joined MySpace, Facebook, Twitter, Instagram, and the like, there was always some sort of motivation based on a friend or other people I knew. I frankly can’t remember how I came to learn about MySpace, but I know I joined Facebook because people I knew were joining Facebook. There wasn’t anything particularly appealing about the platform at all. What I knew was that my friends were there and that’s where I wanted to be. 

A lot of folks do not care about the nuances of social networks and said networks know this all too well. 

When we present the idea of smaller social networks (in contrast to the idea of having just a handful of very large ones), this is the challenge to beat them all. Most folks just won’t care. All they’ll find important is if the platform can get them access to their friends. 

Conversely, some will ignore this notion. My fiancée doesn’t use Twitter, Instagram, Snapchat, etc., even though I’m sure a not insignificant amount of her friends on also available there. She’s found what she needs to stay in contact with the right people on Facebook and that’s that. 

If I told her that XYZ was the coolest new social network and she should join because they care about things like privacy, ads, etc., all that would happen is the information would enter her head and disappear. She would fall into the category of desiring function over form. 

I land somewhere in the middle. I’m all for more communities of people that mean something, but it’s a very fine line to walk. Twitter and Facebook already become an echo chamber quite easily if you’re not careful. Smaller communities are even more prone to such a concept. 

Wisely, though, Manton’s overall focus is on content ownership. If Facebook died tomorrow, I’d probably lose a not insignificant amount of photos, but the ones that matter most are already in other places (iCloud backups, for example). Not everyone is so lucky. There could be years of vacation photos that by one way or another only exist on Facebook. 

In his last paragraph, Manton accurately describes a solution to social media frustration is blogging more. I entirely agree. Even if not many people read it, or you only find yourself writing once a week, take the time writing there about topics you care about, instead of retweeting everything you see (guilty!). Turn those re-tweets into posts. Expand your thoughts. If nothing else, it’ll help you form a better opinion about why you like that thing you found. 

If you’re keeping a close eye, you’ll notice that this post in itself is exactly the kind of idea Manton is describing. Taking time to write down thoughts and share them with the world on a platform you control and then share them with the world. 

Blogging will always be something I enjoy. I’ve had periods of time where I failed to discover anything meaningful I wanted to say–this happens to everyone–but even in down periods, I had topics on the brain. The easy way out is to just write a tweet. The satisfying way out is to blog. 

Medium as a Blogging Platform

All I could do was shake my head when I saw the post from John Gruber that mentioned Medium no longer allowing folks to use custom domains for their Medium-hosted publications (read: blogs). The alternative solution is to resort to a medium.com/publication URL. That sounds fantastic. /s

It seems like only yesterday that I posted about Medium supporting custom domains, though it was really over three years ago.

While old URLs will continue to work, this flies in the face of anyone expecting any kind of long-term stability and consistency from the service and company. This change reminded me of a post from a friend of mine about how self-hosting is the most safe and sustainable option. A couple years later, that’s still the case.

Gruber sums it up well:

There is tremendous strength in independence and decentralization.

and Rafat Ali takes Medium to task (and rightfully so):

Seeing Medium take this course–into blanket depersonalization of authors and content–makes me a bit sad. I have always loved their editor and I knew they were doing something right when WordPress introduced a similarly-behaving editorial experience.

Dave Winer:

The problem isn’t cost, or the tech — it’s users. Medium has momentum, still, as the place-of-record for web writing, much as YouTube is it for video. It’s a shaky foundation. No business model, huge money already invested. Not a good situation.

Without a definite revenue stream (being a Paywall as a Service doesn’t count), I wonder where Medium plans on heading next. Maybe they’ll limit word counts? Maybe most articles will cost money–a la Wall Street Journal? Or better still… good old-fashioned ads? Who am I kidding old-fashioned ads aren’t in style, anymore. these ads will have a cargo ship’s worth of tracking tech baked in.

I joke… but it’s probably coming.

Google Violations

Dave Winer reminded me why I opted to never use AdSense again:

Emails like this from Google about “violations” on my website are really disturbing, esp since I don’t run any Google ads on my site. I wish they’d STFU about violations, or say what the violations are. I always can use a good laugh. Their email is a violation of my independence. Fuck off.

Yes. 👏

Additionally, I’m told this blog is not fit for Google AdSense, which is fine. The last time I used AdSense was 2012 to 2013, I think. I was kicked out of the program without evidence I did anything wrong, but couldn’t argue against it. Without knowing what I did, I had no idea what to fix. Google always has the last say when it comes to their services and while that’s not particularly unique, they do a great job of reminding us from time to time that we’re at their mercy and we should consider ourselves grateful that they’re letting us play in their holy sandbox. 

I brought the Carbon ad network (under the ownership of BuySellAds) on board last week, an email I was genuinely excited to receive that email. They’ve been great to work with so far, have only a handful of rules, and the advertisers they allow are top-notch. As far as serving banner ads goes, Carbon is the limit. The rest of the revenue will be made up of affiliate links for stuff I actually believe in (and use) and site memberships. Dave has no ads, and that’s entirely fine–and his prerogative. I think the right network can make a world of difference.

Plus, I’m not subjecting my visitors to unknown levels of ad-tracking. BSA/Carbon does a bit of it, yes, in order to inform their advertisers how their ads performed, but that’s about it. I appreciate clean and simple advertising and wish the rest of the world would get on board. Even a single tear would not be shed if AdSense went away tomorrow. 

I can dream.

Considering a Return to WordPress

Over the last few weeks, I’ve mulled over in my mind–several times, in fact–going back to WordPress for the simple reason that a static site, while fast and relatively secure, it hard to scale. It’s also a bit more difficult than I would like to post on a regular basis. I enjoy Forestry a lot, actually, but I’d rather use tools like MarsEdit, something I can’t do right now.

Updates to posts require multiple steps and as my post count grows, it just gets more out of control.

What’s holding me back at the moment is creating a WordPress theme (again). I didn’t really enjoy doing it the first time around. 😂

Deploying A Jekyll Static Site with Circle CI

One of the primary steps in making each iteration of this site happen is deploying its generated HTML files to my Digital Ocean server. Since these are just static files and there isn’t a CMS backing them up (in a traditional sense), there needs to be an automatic process that takes care of it after I make a change. If I had to manually push or build the site every time I added something, I’d:

  1. never do it
  2. go back to a CMS

This is where Circle CI enters the picture. Used mainly for software development, Circle CI allows those who are more inclined in the software development realm to build, test, and deploy code. If it can run on a Linux command line, Circle CI can run it.

For the grand starting price of zero and the promise of keeping code open source, I’m offered up to four concurrent builds and 25 hours of build time. As the operator of a static site powered by Jekyll, this is way more than I’ll need, but I’m glad it’s there.

Goals

  • Break down how I make this site happen with Circle CI.
  • We’ll take a look at my Circle CI config file and go over my workflow a bit.

It used to be way more complicated before I wrote this post but as I was thinking about what to write, I realized I was doing way more work than I needed to in the build process.

If you’d like to follow along, this entire site is available to browse through it in GitHub repo form and the Circle CI config file is here.

Table of Contents

The Circle CI File

Starting off first, let’s take a look at the defaults I have set:

defaults: &defaults
  docker:
    - image: circleci/ruby:2.5.1-node-browsers
  working_directory: ~/repo

What you’re looking at here are values that I’ll always need, no matter how many steps, jobs, etc. I’ll end up with. Since I have only one job, this is more of my “do not touch” section in that these values will never change and only new ones will be added. (You can find a more in-depth explanation of the purpose of defaults here.)

version: 2
jobs:
  the_only_job:
    <<: *defaults

Now we’re entering job territory. This is where I specify the actual tasks I need Circle CI to run. I only have one job, now–the_only_job–but if I had more, they’d be broken down like this:

version: 2
jobs:
  the_only_job:
    <<: *defaults
  except_its_not:
    <<: *defaults
  a_third_job:
    <<: *defaults

Each job would call upon the defaults because Circle CI treats each job as a separate build and would need its own container. In multi-job scenarios, having a set of defaults to share across all jobs is truly a no-brainer.

Deployment

Inside our job, we have a set of steps:.

Note: This is a list of tasks that should be performed by the container. Everything in this section is in the context of:

jobs:
  the_only_job:
    <<: *defaults
    steps:

So never mind the lack of full indentation. It saves me from repeating lines a dozen times.

Pre-game Tasks

- add_ssh_keys:
    fingerprints:
      - "69:fe:2c:df:c8:34:c5:e6:3f:6e:18:64:43:97:58:02"

The very first thing I have the container do is add an SSH key using the add_ssh_keys step. I’ve provided Circle CI with a key to the production server as a specific deploy-only user. This adds the key to the container so it can connect to the server later without me needing to provide hardcoded credentials. Doing so would be a massive security breach as my Circle CI builds are open to the public.

- checkout

Once that’s good to go, I have Circle CI checkout the latest code from the master branch of johlym/johnathan.org. Simple enough.

- attach_workspace:
    at: ~/repo

The third step is attach_workspace. This was more relevant when I had multiple jobs but the idea here is that we’re creating a persistent and consistent location within the job container to do all our task work. In this case, I need to make it clear that we’ll be doing all our work in ~/repo from here on out.

Cache Handling, Part 1

- restore_cache:
    keys:
      - v1-bundle-{{ checksum "Gemfile.lock" }}-{{ checksum "package.json" }}

This part is important if there’s even a stretch goal of having a speedy build process. The restore_cache step looks for a cache file that we’ve already built (something we’ll do at the end) to save time with things like bundle and npm. Without this, we could spend a few minutes just installing Rubygems and Node modules. bleh.

The cache file uses MD5 hashes of the Gemfile.lock and package.json files combined. If those files never change, the MD5s won’t either, so this cache will remain valid. If I were to update a gem, for example, the cache would be invalid and Rubygems and Node modules would be installed.

One potential spot for improvement here is to break this out into two separate caches, but Circle CI doesn’t handle that well, so this’ll be fine.

Installations

- run: 
    name: Install Rubygems if necessary
    command: |
      bundle install --path vendor/bundle --jobs 4 --retry 3
- run: 
    name: Install Node modules if necessary 
    command: |
      cd ~/repo && npm install
- run: 
    name: Install Rsync
    command: |
      sudo apt install rsync

This part is pretty straight forward. I need to make sure all the required Rubygems, Node modules, and Rsync are installed. In this case, I’m making sure bundle puts everything in vendor/bundle (remember, this is relative to ~/repo since we declared that to be our workspace earlier) when it installs. The Node modules I don’t need to worry so much about. The package.json would be located in the ~/repo directory since that’s where the code was checked out to so we hop in there and get to it. It’ll plop its node_modules file at ~/repo/node_modules as a result. This is totally acceptable. Lastly, we install rsync via apt. Nothing special.

Site building

- run: 
    name: Build site
    command: |
      bundle exec jekyll build --profile --verbose --destination /home/circleci/repo/_site

For those who’ve worked with Jekyll before, this command shouldn’t come as a surprise. We’re asking Jekyll to build out the site and place it at ~/repo/_site. The --profile and --verbose flags are for CI output, only, in case there’s an error or my curiosity gets the better of me.

Site tweaking

- run:
    name: Install and run Gulp
    command: |
      cd ~/repo && npx gulp

When considering how I wanted to handle minification of HTML and JavaScript, I considered the jekyll-assets plugin, but decided against it because of the amount of overhead and work that would be required to implement it in my already moderately-sized site. This is where I decided to bring in Gulp, instead. I have a simple Gulpfile that’s set up to use a couple Gulp modules to minify all the HTML and local JavaScript. Over the 400-something pages I have, this saves me about 20% on the site size overall. Not too shabby.

You’ll notice we need to use npx here. For some reason, I was never able to get Gulp to run on its own… it would look for the gulp binary in strange places I could not control. npx allows me to run gulp wherever, so long as it can find the corresponding node_modules folder for reference. Brilliant, eh? Portable Gulp.

Server Push

- run: 
    name: Deploy to prod server if triggered via master branch change
    command: |
      if [ $CIRCLE_BRANCH = 'master' ]; then rsync -e "ssh -o StrictHostKeyChecking=no" -va --delete ~/repo/_site [email protected]:/var/www/johnathan.org/static; fi

This is pretty straight forward, as well, though it can look complicated to the untrained eye. What we’re doing is here is first checking if the branch this build is based off of is the master branch. We’ll find that value in the CIRCLE_BRANCH ENV variable. If it is not, we’ll skip this, but if it is, we’ll run rsync to push the contents of ~/repo/site over to the production Digital Ocean server. I’m using the IP here because of Cloudflare, though I have a TODO item to use a hostname instead.

Post-Deployment

For all intents and purposes, the deployment is done, but because of Cloudflare, we have one additional step to make sure everyone’s seeing the freshest code.

Cloudflare

(we’re still in the jobs context)

- run: 
    name: Bust Cloudflare cache if triggered via master branch change
    command: |
      if [ $CIRCLE_BRANCH = 'master' ]; then 
        curl -X POST "https://api.cloudflare.com/client/v4/zones/$CLOUDFLARE_ZONE_ID/purge_cache" \
        -H "X-Auth-Email: $CLOUDFLARE_API_EMAIL" \
        -H "X-Auth-Key: $CLOUDFLARE_API_KEY" \
        -H "Content-Type: application/json" \
        --data '{"purge_everything":true}'; 

Using the Cloudflare API, we’re submitting a POST request to dump the entire cache for the johnathan.org DNS zone. I’ve provided Circle CI with the necessary information as ENV variables and am calling upon them here. This keeps them safe and the job step functional.

I wouldn’t recommend this for high-volume sites, but because I have Cloudflare caching just about everything combined with the fact that I maybe do this a couple times a week, this feels like the right level of effort and precision.

Cache Handling, Part 2

- save_cache:
    key: v1-bundle-{{ checksum "Gemfile.lock" }}-{{ checksum "package.json" }}
    paths:
      - ~/repo/vendor/bundle
      - ~/repo/node_modules

Earlier, we called upon the generated cache. Here is where we create it if necessary. This’ll do the same check step before acting. If the cache file already exists with the same MD5s, we’ll skip creating it, but if it’s missing, we’ll build it out, making sure to capture everything from the ~/repo/vendor/bundle and ~/repo/node_modules folders we referenced with Rubygems and NPM.

Workflow Management

workflows:
  version: 2
  build_site:
    jobs:
      - the_only_job

I used to have multiple jobs running in a breakout-combine pattern, and this is leftover from that. Although I only have one job, now, I didn’t want to re-craft it to not use Workflows, so I just operate with a one-job Workflow instead. XD

Wrap Up

That about does it for my overview. This process is turning out to work very well for me and I’m glad I took the time to both develop it and explain it for posterity. Over time, it’ll morph, I’m sure, but right now this feels like a really good bass to work off of.

Thanks for taking the time to read this. Cheers!

Johnathan Lyman
Kenmore, WA,
United States
 
blogging, design, technology, software, development, gaming, photography