Tool Boxes

Dec 10

S w 37942 unsplash

unsplash-logos w

I like to tell people to develop skills like they would add tools to a tool box. I think I first came across this metaphor as a musician and it made perfect sense: learn scales, rhythmic exercises, excerpts from different composers – combine in different ways later on when you encounter something new. Rinse and repeat.

And it applies to what I do now with software too. Except… I’m just not applying it. I’m not thinking about it in the same way that I would with music, which I approach very theoretically and like a puzzle. You would think that kind of thinking would be obvious with programming for machines, but I’ve been a bit stressed out. And when I’m stressed out, I stop trying to add new tools – I instead rely on the ones I have, and even then only the very familiar ones.

I thought of this again today with cooking. I was using my rice cooker and only now decided to measure out the amount of rice I was going to use. I used to do this when I would measure out rice when living with my family! But I lost my dad and with that stress I forgot how to cook. And it’s only until today I realized I could gain that tool back, measuring rice.

Going back to music, I want to reflect on how I succeeded reasonably well without practicing. And it’s because I created a bunch of tools and I became intimate with how they worked. Then when I was stressed out playing (which was, admittedly, most of the time) I’d still know how to use those tools.

It’s also worth noting that because I had those tools, I was also less stressed out about what I was playing. The same goes for cooking. The same goes for coding. And the same goes for whatever it is you’re trying to do. If you can develop an intimacy and familiarity with the tools of your craft, you’ll be able to wield them that much better when you’re under a lot of pressure and stress.

Moving Offices

Nov 28

After our company closed our office to save some coin, I’ve been working from home now for about a month and have a better handle of what that change has meant for me and my well-being. Everyone on our team is adjusting slightly differently, but hopefully by shedding some light on my experience I can shed some light on what to prepare for if the same thing happens to you.

First, What We Accounted For

I think we did a lot of things right when preparing to work from home. The big thing was to do trial runs, communicate about our experiences, and share any insights we might have. We tackled it as a team and that was really useful.

As for specific advice, we immediately figured out the following:

Working From Home a.k.a. Changing Your Commute

I think the best way to treat a transition to working from home is to think about it as a change in your commute. At this same company, we had moved our office downtown and it changed everyone’s commute. We should have treated this the same way. I think if we did that, we would’ve considered the following:

I didn’t really think about the impact of walking less every day – the little amount I did when going to and from train stations and going out to lunch was instrumental in keeping my mood up and keeping my weight down! And that weight crept up on me – I didn’t notice it until I weighed myself at the doctor’s.

The separation between work and home is also important. I play games and program for fun in the same space I now work. Having the monitors in the same place isn’t a huge problem, but I need to make sure I get out of my desk and do something else for a bit before returning to it. Otherwise it all kinds of melts together.

Last, having a zero minute commute means more time in the day, right? Except for me, that commute time was necessary to stay sane. I used it to read books and get into a better reading habit! So now I need to make sure I bake that in to my schedule again.

Offices Are Social Spaces

And we are social creatures. We knew this would be affected, but it’s hard to gauge that in testing when you still have an office to return to. Not only does it feel more draining working from home without anyone to talk to, it completely affects the problem-solving methods that our team was accustomed to. We have to be much more deliberate.

And yes, Iggy is great, but she’s not a person! No matter how hard she tries. :)

Corporate Passed On Costs To Us

This one is simple – company not only saves money on not having an office via rent, but also via utilities, amenities like snacks and coffee, and providing a gym. And not only do we have to pay for these now in a budget sense, we also have to build their responsibility into our habits. I can’t just bring a duffel bag to work and swing by the gym during lunch – I need to take a twenty minute bus ride to the gym, workout, and come back. I also need to pay for it. And before you ask, no, none of us received raises to cover these costs.

Ultimately, Structure Is Good

I talked to my therapist about this today. Even though I’m not Type A and I don’t impose a lot of structure on myself, I like to dance around existing structure. Without it, I can’t dance! So it’s a big change for me to not have my routine of waking up, showering, getting on a train, sitting down at a desk and saying good morning to everyone.

So we need new structures: for our habits, for our social well-being, to make sure we budget appropriately and to help us do our jobs effectively. And if you know me, you already know I don’t have a lot of faith in those in positions of leadership and power to lead on this appropriately. So we need to roll up our sleeves and get ready to get our hands dirty.

Bringing this back

Nov 23

This blog has been neglected for a bit, and I think I should bring it back in some form. In general, I’ve kinda laid low since the beginning of July, when we went through some huge restructuring changes at work and I haven’t had the energy to process them in written form. Instead I’ve been just trying to process them as they came, by myself and with my team. It’s been a lot, but I feel like I can at least post some updates now.

I now work from home. Which is to say, I see a lot more of my dog Iggy now. She’s nuzzled up against me right now, alternating between snoring loudly and trying to get some pets in. The biggest changes to my lifestyle center around broadcasting my work actions more (lunch, logging on and off, reaching out for help) and making sure I don’t go stir crazy being inside all the time. Iggy helps with this too.

I want to do more technical writing in the near future. Advent of Code is around the corner and I need to prep some CI/CD examples for different languages for the group I mentor. I also want to do more work on ceruleanlabs.com and that includes setting up Concourse so team members can manage their own deploys without me. Honestly, I guess I’m doing a lot of DevOps these days.

This blog is interesting in that it contains samples of my writing for over a decade of my life – without that context, it’s really scary to release out into the wild. But if I do it right, then I shouldn’t be too worried – it shows an individual growing over time and continuous learning. After all, that’s all I can really hope for myself. Right now, this blog only shows entries since May 12th. But the archives are there (I should add them to source control) and I still plan to republish them at some point. It is just not a top priority given all the other things I want to accomplish, and I don’t want to cut any corners to complete the archives import because it needs to be done correctly.

Anyhoo, that’s it for now. Expect more posts in the near future. ^_^

Separating Ideas From Actionables

Aug 1

I use Todoist for all of my task management, and for that it works wonderfully. However when it comes to tracking ideas – or even things I just think I should do – Todoist is lost. It’s the same problem with email – items collect dust because I don’t want to act on them but I also don’t want to write them off or forget about them.

For example, I made an item for a new tattoo. But there are no actionables for it right now. Actionables might include eventually saving money? Coming up with ideas for a design? It’s like I need a placeholder for it because I want to break it down further and categorize it, but right now I can’t.

Part of me wants to build some custom view to handle all of these use cases. The other part of me just realizes I just started to figure out how Filters work and finally made one to separate work tasks from other things I might want to do. So I’m probably getting ahead of myself with wanting to use the Todoist API. This is the same brain that sometimes wants to build custom budgeting software instead of just using Excel!

Filters have a lot of strength because the tasks can be prioritized differently based on what I need to do. So something like a “Chores” list would just list all my chores and then I’d do them when I have time and energy. Something like a software project might just have a priority order and then I’d pick which one to do next.

We’ll see what I can do to better leverage the software I have. I still want to develop better ways to develop ideas, build out habits, and plan out larger projects that have several components that need to be done over larger swaths of time.

Rails + Puma + Capistrano + Nginx

Jul 21

About a month ago I decided I wanted to get a website going for Cerulean Labs, my catch-all organization that has supported game dev, mentoring meetups, and other random group projects. It would be good to have a website that allowed users in the organization to coordinate meeting up, sharing projects, and reviewing important info like community guidelines.

I specifically chose Rails because I haven’t developed on it since Rails 3 and I miss developing in Ruby. Puma is the default app server out of the box, and Capistrano takes care of deploys. Last, Nginx is used as a proxy.

Installation

Below are the components I had to install on the host machine. The order is all out of whack – I bounced around as I figured out what still needed to be setup. If you’re looking for specific guides, check out the bottom of this post.

SSL Certificate

I used Let’s Encrypt to get my certificate. First, I setup my dependencies:

$ sudo add-apt-repository ppa:certbot/certbot
$ sudo apt-get update
$ sudo apt-get install python-certbot-nginx

Installing the cert:

$ sudo certbot --nginx -d www.ceruleanlabs.com

Testing renewal:

$ sudo certbot renew --dry-run

It’ll prompt you along the way but the questions are straight-forward.

Nginx Gotos

I used the following when I wanted to check the syntax of my config files, check to see if nginx was running, and then to restart it whenever I made a change.

$ sudo nginx -t
$ sudo service nginx status
$ sudo service nginx restart

Nginx Config

When you first look at /etc/nginx/sites-available/default it looks something like this:

server {
    root /var/www/html;

    index index.html index.htm index.nginx-debian.html;
    server_name www.ceruleanlabs.com; # managed by Certbot


    location / {
            try_files $uri $uri/ =404;
    }

    listen [::]:443 ssl ipv6only=on; # managed by Certbot
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/www.ceruleanlabs.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/www.ceruleanlabs.com/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}

server {
    if ($host = www.ceruleanlabs.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80 ;
    listen [::]:80 ;
    server_name www.ceruleanlabs.com;
    return 404; # managed by Certbot
}

The first server block shows a default Nginx page. The second block makes sure that your site is always served over HTTPS.

We want to first add an upstream block that points to where our Puma socket will be located. I put this at the very top of the file:

upstream puma {
    server unix:///var/www/ceruleanlabs/shared/tmp/sockets/puma.sock fail_timeout=0;
}

Next we want to rewrite the guts of that server block that is currently serving the default Nginx page. Mine looks something like this, given we’re serving a Rails app via Puma:

server {
    root /var/www/ceruleanlabs/current/public;
    access_log /var/www/ceruleanlabs/current/log/nginx.access.log;
    error_log /var/www/ceruleanlabs/current/log/nginx.error.log info;
    server_name www.ceruleanlabs.com;

    location ^~ /assets/ {
        gzip_static on;
        expires max;
        add_header Cache-Control public;
    }

    try_files $uri/index.html $uri @puma;
    location @puma {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;

        proxy_pass http://puma;
    }

    listen [::]:443 ssl; # managed by Certbot
        listen 443 ssl; # managed by Certbot
        ssl_certificate /etc/letsencrypt/live/www.ceruleanlabs.com/fullchain.pem; # managed by Certbot
        ssl_certificate_key /etc/letsencrypt/live/www.ceruleanlabs.com/privkey.pem; # managed by Certbot
        include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
        ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

    error_page 500 502 503 504 /500.html;
    client_max_body_size 10M;
    keepalive_timeout 10;
}

Firewall Config

This part was also straightforward, and again I followed the guide at the bottom of this post. I pretty much just ran the following commands:

$ sudo ufw allow "Nginx Full"
$ sudo ufw allow "OpenSSH"
$ sudo ufw delete allow "Nginx HTTP"

$ sudo ufw status

Ruby Setup

$ curl -fsSL https://github.com/rbenv/rbenv-installer/raw/master/bin/rbenv-installer | bash

I then followed the rbenv guide for installing it to my shell so it would be available when I’m running commands remotely via Capistrano. You can set that shell for that user with chsh -s /bin/bash – using Bash, for example, with a ~/.bash_profile that looks like this:

export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

JavaScript Runtime

We need a runtime for compilation of the Javascript components. I ended up just installing Node on the host machine, but you can also add something like mini_racer to your Gemfile to add support as well.

Deploys

$ cap production deploy

Additional Setup

This is all open-source, so you can of-course check out the rest of the app configuration on GitHub: https://github.com/ceruleanlabs/ceruleanlabs.com The rest of the changes I had to make mostly centered around configuring the Rails app with the correct database credentials, libraries, etc. I should’ve written my steps down better haha, but you’ll find the rest of what’s configured in the repo.


Useful Docs and Guides

Step 2: CircleCI and S3 Buckets

Jul 1

The second part took longer than usual. Part of this was because I was wrestling with DNS – I don’t think DNS changes ever go quickly – but the other part was because I was hit with another bout of depression. #yaydepression

For the second part I configured CircleCI to build and deploy this blog to an S3 bucket, which I reconfigured with the slidingdown.com URL by using Route 53 as my new DNS provider.

CircleCI

This part was pretty fun. I first setup Docker to make sure it could containerize correctly. This helped me debug a JS dependency for Middleman – something I quickly fixed with mini_racer. Next I figured out how to get it to build on CircleCI. CircleCI lets you build one project for free, which is why I’m having it run my blog, which is a private repo.

One useful piece of information was understanding how to persist data in workflows. The diagram in the article really helped and I was able to cobble the rest together using documentation.

AWS Configuration

The S3 configuration was really straightforward once I got the hang of the naming conventions and what how permission should be setup. I followed Amazon’s guide for setting up a custom domain static site. And if you’re wary about copypasta'ing the policy into your bucket’s config, you can get the same results from using the AWS Policy Generator.

Getting CircleCI authenticated was also really easy – I created an IAM user specifically for CircleCI and gave it S3 permissions.

The most annoying part was figuring out I needed to switch from my own DNS provider to Route 53. I was trying to setup my own CNAME record and it didn’t take – S3 balked at my configuration. So I made the switch and everything worked magically.

Putting it all together

And now CI/CD for my blog works! The only nice-to-have I really want to have is SSL support. It’s not necessary because I host a static site, but it’s where the web is heading and Firefox gets angry. There might be an option using CloudFront that I can explore.

Two Related Emotions

Jul 1

I had a breakdown yesterday – it was the last hours of a long day, that long day being the last day of a long month. So as I descended into a ball of snot and tears, two primary emotions came to the forefront.

I am dumb

I can’t measure up to the company I keep. The gap between them and me is too great – there’s no way I can catch up. They’re all doing amazing things and I struggle with the most basic. That includes this mental illness. Why can’t I be smart enough to beat this? Why is it so irrational, but I still can’t outthink it?

I am a burden

I should remove myself from the company I keep. I’m only holding them back – they give me their precious time out of charity or pity, and I don’t know which is worse. Imagine the mental gymnastics they must do to call me their friend! I’ll be doing the world a service if I just go away.

Neither of those are true

I talked to my mom for an hour and a half last night. She really likes to talk – a trait I didn’t always appreciate growing up, but now it is exactly what I need for times like this. We talked about growing up as an immigrant, how my sister and I are similar and different, about what Mom went through when Dad passed away, cartoons. My mom likes her goofy metaphors, something I now understand I got from her – she likened my current situation to being flattened by an anvil. And even though I’m flattened, I’m just popping my feet back out and waddling around. My goal is to become 3D again.

Rasberry Pi -- I remember you!

Jun 30

Before we begin, fun fact: Middleman doesn’t like generating articles with exclamation points in the title. I’m guessing it has a problem stripping them out when generating the filename. Maybe this is a good opportunity for a pull request!


I’m following Gordon Turner’s Raspberry Pi guide to start step one of putting an information radiator in my home.

Hardware

I’m using an old monitor and an old Raspberry Pi 1. 8 GB memory card from who knows when. Nothing fancy here; why invest in hardware when I haven’t written any software yet?

Turning It On

I guess there’s one piece of hardware I invested in that was a nice-to-have – a Wemo Mini Smart Plug. Right now I have it hooked up to an IFTTT recipe that lets me press a button on my iPad to toggle the Pi on and off. Eventually I’ll have it hooked up to Alexa or put on a schedule so I can see it in the morning and otherwise have the whole thing turned off.

Setting Up the Pi

I followed the Raspberry Pi setup steps to get Raspbian Stretch flashed onto the memory card. (Etcher Pro looks so cool btw) Next was to follow the directions as they were written out! I especially liked the instructions to SSH into the Pi, since that lets me copypasta the scripts easily from my MacBook Pro. After following those instructions, everything worked out!

Next Steps

Next I’ll want to design a website – it’ll have to be pretty lightweight so the Pi can easily render it. I think that’ll be a fun challenge! I also want to get my domains in order: I’ve been having trouble with GitHub Pages and custom domains, so I’ll probably bite the bullet and host on AWS or something. We’ll see what kind of architecture I need.

That’s it for now! This is the first day of a week long “sabbatical” for me. I’m using the time to get caught up on grad work, relax from burnout, and innovate. So far so good!

I Made It

Jun 23

HI DOG UR A DOG HELLO DOG HI HI HI https://t.co/HIsAzYoSJk

— jomny sun (@jonnysun) June 23, 2018

Seriously, this made my week – and I had a pretty rough week.

Cleaning Up Dropbox

Jun 19

One of the unexpected side-effects of owning a dog is how many pictures I now take on a daily basis. I use Dropbox’s Camera Upload feature, so – as you might expect – I quickly ran out of space. Right now there’s a queue of a few hundred photos on my phone waiting to be uploaded to the cloud.

Rather than pony up some money to buy space and prolong the problem, I decided to dive in and start categorizing photos. I basically treat my Camera Upload folder like an inbox and move photos from there into other folders to be processed at a later point (assuming I can’t decide to delete a photo right then and there).

Another one of my holdups for processing all of this data was that I wanted to write an app to make it easier to sort photos. But ultimately I just need to go through the data – the tools I have are sufficient to make good progress. I need to work on not getting hung up on doing something optimally if I want to make immediate progress. Discerning between immediate gains and long-term gains is a useful skill worth honing – I use it every day in software development and it’s applicable in many other areas too.

Be Still

Jun 11

I wrote a Firefox extension called Be Still that blocks traffic from social media websites I need to get myself off of. Right now it’s not published (you can still check it out on GitHub) and it only shows an image, but I’d like to make it more mental health focused going forward. I’d also like to support Chrome, Safari and Edge too.

But right now it’s something. Ironically enough, it was difficult to develop extension because my mind was on fire the whole time. I still don’t have a great system for planning out work – sometimes I cope fine and my brain can keep everything organized, other times it can barely focus on one thing. I’m hoping this extension is a step in a direction that supports people like me, and maybe it can give me ideas for building other tools I might need.

I haven’t written in this blog recently – was a bit held up trying to get my Ghost blog ported. Instead I think I should just keep writing these posts and not worry about importing the past. If there’s ever a time for me to need writing, it’s now.

A New Start

May 12

It’s time I start this blog again, and make a committed effort to it. I think it’ll be useful to have a platform to write down my thoughts both professionally and personally.

Scott Hutchison – frontman of Frightened Rabbit – took his own life this past week, and it’s been on my mind. As I near my birthday and older by another year, I can’t help but think about my own mental illnesses and how my life changes as those illnesses change.

I don’t know what my future holds for me. Yes, it’s kinda scary. I didn’t really want to say anything in particular, just to acknowledge the fear that’s real and present.

Be so good to everyone you love. It’s not a given. I’m so annoyed that it’s not. I didn’t live by that standard and it kills me. Please, hug your loved ones.

— Scott Hutchison (@owljohn) May 8, 2018

I’m away now. Thanks.

— Scott Hutchison (@owljohn) May 8, 2018