Working Remotely

You may or may not know that I work remotely for Loup. Honestly, I never thought I was cut from the stock of “remote-capable” worker, but I’m finding that it’s actually not that bad. There are a couple things to keep in mind when you’re tasked with working remotely.

Communicate Effectively

This is extremely important. Note that I’m not saying communicate often; effective communication and frequent communication can be opposing forces.

Graph!

See? Okay, that’s pretty contrived but frankly pretty true. I don’t know what 6 means in “Efficacy of Communication” but I’m too lazy to re-generate this graph without the Y-axis. Find the sweet spot communicating with your peers and superiors (if you have superiors). I found that a conversation in the morning and a conversation in the evening pretty much covers it. Any other conversations should be directly and contextually relevant to getting your work done.

Separate Your Workspace

Live somewhere with a separate room that is seriously only for working. Call it an office, call it a study, call it a rumpus-workzone, whatever gets you through the day. It needs a door. It needs a desk. That desk needs a nice, big monitor, and a lamp. Speaking of light, lots of natural light would be nice, too. Ideally, a comfortable lounging chair for when you need to be reading things, or need a change of viewpoint on the world midway through the day. If you live with people (family, friends, strangers) I would recommend some kind of system where you have signs you can put on the outside of your door to indicate yes, you can bother me, or no, for God’s sake, I’m on a call. That or just make sure they know that door closed == leave me the f*ck alone.

Plan Realistically

It’s easy to fall into the ideology of: “oh, I’ll finish that after dinner” and “that’ll be a nice thing to do while I have my coffee in the morning.” Let’s be honest, though: you’re not going to do that. Think about how much you get done in a day, how much you actually get done in a day. It’s not as much as you think. Your rock-star, in-the-zone, montage-style days aren’t every day. You’ll be lucky if you get one of those a week, maybe even one a month.

And that’s okay.

Just be realistic. If you set good expectations, then you’ll have no problem looking like a B.A.M.F. when it comes to reaching your goals. Which brings me to…

Set Expectations

Working from home is not the same as working in an office. You’re not going to get as much done, because somehow flourescent lighting and all the free food and drink you can consume does increase your productivity an amount. Well, it might be that you’re locked (figuratively, usually) in a building with no expectation or responsibility other than getting your work done, and there’s not much else to do there. That’s just a fact.

Now, if you’re closed-minded, you might say to yourself, “well then, why would I want to work from home?”

Maybe because you like staying sane.

Seriously. Working from home has saved my sanity more times than I can count. Working in an office, I tend to take on the mindset of, well, there’s this little thing left, so let me stay another hour and figure it out. Then, I’m there for two hours because reality-check, of course this doesn’t take just one hour, and then I spend anotherh our commuting home. When I’m working from home, I can more easily make peace with the sentiment of time to hang it up. I’ll be able to come back fresh to this tomorrow. Then, I walk into the next room and get a beer and start cooking dinner.

In essence: understand that you’ll probably be about 80% as productive from home. If you need 115%, you can make a trip to the office and spend a week with no other concern or responsibility but work, and spend sixteen hours a day marathoning. I find that’s actually a good way to do things. I work in momentum swings. They’re not violent, but they are consistent. I’ll have a good few weeks, then a slower few weeks, then a week at HQ where I’m kicking ass, then a good few weeks, etc.

Makes sprint planning difficult but it feels more natural to me.

Go Places

You work remotely. If you need a change of scenery, go somewhere else. So long as there’s Internet, you’re capable of being productive. If you’re working on top-secret stuff, find a corner and put your back against it. If it’s double-secret-probation-secret, then maybe stay home or get some kind of encrypted VPN tunnel set up.

Have a Beer (just one!)

2PM. Brick Wall. What do you do? Walk to your fridge and get a beer! Seriously, mental blocks fear beer like the plague. It’s great.




There’s a lot more wisdom to working from home, but a big part of it is to understand that it is inherently different than working in an office with other people around. If you keep that in mind, and set appropriate expectations and boundaries, you’ll do great. I believe in you.

Setting Up a Private Docker Registry

Docker is a pretty cool technology. Abstracting much of the system configuration away from, well, system configuration, means that you can get to work writing and shipping code faster. Like most modern technologies, Docker is all-in on openness, which is great. Unless you’re trying to run a business where your technology should remain private.

The Docker Hub Registry offers a free private repository for any user, and more if they’re willing to drop a couple bucks a month. Still, though, it’s your code on someone else’s servers. I trust GitHub to an extent but I’m cautious otherwise. In this abundance of caution, I started some research into how to get a truly private Docker Registry running.

The large part of doing so is actually really easy, since you can run an instance of the Docker registry just with a convenient “docker run”, since the registry itself is an app container.

The following is an Amazon EC2 user-data script. If you start an instance with it, there will be a docker registry instance running, provided the instance’s Instance Role allows read/write access to the S3 bucket you declare.

#cloud-config
runcmd:
 - "echo 'Running Docker Setup and Registry'"
 - "yum update -y"
 - "yum install docker -y"
 - "/etc/init.d/docker start"
 - "docker run -d -e SETTINGS_FLAVOR=s3 -e AWS_BUCKET=[YOUR_S3_BUCKET] -e STORAGE_PATH=/registry -e STORAGE_REDIRECT=true -p '5000:5000' registry"
 - "echo 'Done Setting up Docker'"

So far so good. Only problem is that, once you boot an instance with this, and throw it behind a Load Balancer (for simple SSL termination… you can configure SSL termination in the Docker Registry instance itself, but I’m lazy…) and point a DNS name at it, anyone can access it and push and pull images. So much for a private repository, right?

(Note – I specifically haven’t covered the SSL terminating load balancer and DNS stuff here. If you’re not sure how to do all of that, please consult the Google)

Setting up auth for a Docker Registry is interesting, since it’s actually not a feature of the registry itself. We have to go deeper!

Nginx is a great HTTP proxy and can have an auth layer built right in. Let’s look into that. We’ll want a pretty simple setup. First, install Nginx if not installed as well as http tools:

sudo yum install nginx httpd-tools

Let’s create a password file that Nginx will refer to for people trying to access your repo:

sudo htpasswd -c /etc/nginx/docker-registry.htpasswd <USERNAME>  # Password asked by the script.

For adding more username/password entries, omit the “-c” option from the above command.

We’ll want to configure Nginx by writing our own config to include to the master Nginx config. Put this in “/etc/nginx/sites-available/docker-registry”:

# For versions of Nginx > 1.3.9 that include chunked transfer encoding support
# Replace with appropriate values where necessary

upstream docker-registry {
 server localhost:5000;
}

server {
 listen 80;
 server_name <YOUR DNS NAME>;

 proxy_set_header Host       $http_host;   # required for Docker client sake
 proxy_set_header X-Real-IP  $remote_addr; # pass on real client IP

 client_max_body_size 0; # disable any limits to avoid HTTP 413 for large image uploads

 # required to avoid HTTP 411: see Issue #1486 (https://github.com/dotcloud/docker/issues/1486)
 chunked_transfer_encoding on;

 location / {
     # let Nginx know about our auth file
     auth_basic              "Restricted";
     auth_basic_user_file    docker-registry.htpasswd;

     proxy_pass http://docker-registry;
 }
 location /_ping {
     auth_basic off;
     proxy_pass http://docker-registry;
 }
 location /v1/_ping {
     auth_basic off;
     proxy_pass http://docker-registry;
 }

}

Lastly, include it from your main Nginx config. It’s located at /etc/nginx/nginx.conf Remove any server entries from the file and add this line inside the http section:

include /etc/nginx/sites-available/*;

Mine, finished, looks like this:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log;
#error_log  /var/log/nginx/error.log  notice;
#error_log  /var/log/nginx/error.log  info;

pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    include /etc/nginx/sites-available/*;   ## ADDED THIS

}

If everything goes as planned, you should now be able to send the following:

curl localhost/_ping

It should return just {}.

Cool. Now we have successfully spun up a server and manually set up its nginx proxy to enable auth. How do we glue this all together? I’d recommend throwing the above into the user-data. It grabs the relevant config files from S3 and puts them in place where they belong. Here’s a good example:

#!/bin/bash
echo 'Running Docker Setup and Registry'
yum update -y
yum install docker httpd-tools nginx -y
/etc/init.d/docker start
docker run -d -e SETTINGS_FLAVOR=s3 -e AWS_BUCKET=[YOUR BUCKET HERE] -e STORAGE_PATH=/registry -e STORAGE_REDIRECT=true -p '5000:5000' registry
echo 'Done Setting up Docker'
aws s3 cp s3://[YOUR_BUCKET_HERE]/config/nginx.conf /etc/nginx/nginx.conf
mkdir -p /etc/nginx/sites-available
aws s3 cp s3://[YOUR_BUCKET_HERE]/config/docker-registry /etc/nginx/sites-available/docker-registry
# At your discretion: either store your htpasswd file in S3 with everything else, or set passwords on boot:
# aws s3 cp s3://[YOUR_BUCKET_HERE]/config/docker-registry.htpasswd /etc/nginx/docker-registry.htpasswd
# --- OR ---
# htpasswd -c -b /etc/nginx/docker-registry.htpasswd [USERNAME1] [PASSWORD1]   # -c flag for creating file.
# htpasswd -b /etc/nginx/docker-registry.htpasswd [USERNAME2] [PASSWORD2]
/etc/init.d/nginx start

Any problems? Feel free to ask a question in the comments – I wrote this as I was figuring it out, so it’s likely I’ve missed something here and there.

Inspired and compiled with these posts in mind:

Recent Rumblings

So, I’ve been with Loup for a while now. A couple months. It’s great – I’ve been given tons of responsibility and opportunity, and I think I’m thriving in it. Since starting, I’ve developed an app for internal use with some great usability features. I have contributed extensively to our web services, which I hadn’t anticipated I would be doing. Turns out I’m loving that, too. So I guess I’m a full-stack engineer now, which is pretty exciting!

In so doing, I’m discovering a lot of fun features of Python’s language and runtime environment. The ability to consider a type as a first-class object is great, and led to my creation of the project validict, which I recommend you check out.

That’s about it for now. There’s a lot under wraps but some exciting things upcoming. I’m hoping I can start documenting some of those things here, because I think I’m learning some really valuable lessons and am more than happy to share.

Loup

About a month and a half ago, I left Amazon.com. It was a tough decision but primarily based in opportunity and ownership for me. Things at Amazon were going well, as well as anyone can say working at Amazon goes, but I hungered for a challenge.

I didn’t start looking around very feverishly&em;I would have been perfectly happy sticking around where I was&em;but I thought it prudent to keep my eyes out. Around this time, a recruiter from Google contacted me, and I started an interview process with them. Out of respect to their wishes I won’t talk much about that. I didn’t end up at Google anyway.

Around the same time I was interviewing with Google, I stumbled across Hired. Hired is seriously cool. Basically, you log in and sign your life away to them (okay, not your life, just your social media & LinkedIn accounts for their trawling purposes), and they match you up with employers, who get to try and sell their company to you. That’s a nice changeup from the typical neurosis of trying to impress an employer throughout a five-week interview process.

With Hired I received hits from a number of small companies, but one in particular got my attention: Loup. Loup is a cool little startup. We, like a number of other companies, are trying to get our slice of the transportation pie that companies like Lyft and Uber are gobbling up, while trying to define new market possibilities.

I am the official “Senior Mobile Engineer” for the company, and that’s meant a lot of responsibility and a lot of work. I’m loving it. I’m wholly responsible for shipping apps and get complete control over the architecture and implementation. It’s a huge challenge, and one in which I’m learning every second.

One of the perks that comes with working, well, anywhere but Amazon, is I get to release and work on open source projects, and personal closed source projects! That really excites me. While I love working with other passionate people, I want to get to a point in my life where I can develop software independently for a living. It will be a long struggle, but the first step is to have an idea and to start executing.

The entity under which I’ll be developing software for independent release is called CommandShift Labs. I’ve had the name up my sleeve for some time, and I’m so excited to start working under its shadow. Check out the CommandShift Labs Blog for updates on what I’m doing over there.

Here’s to hoping I start writing more; I’m enjoying getting to let my thoughts spill out, even if not a soul reads them.

AWS WorkSpaces, and introducing: CSRevealingViewController


Good news everyone!

I've recently moved teams inside of Amazon. I've gone from Operations -- the land of broken dreams and late night service rescue -- to Development! Hooray! In particular, I am the primary developer of the Amazon WorkSpaces iPad App. WorkSpaces is a cool product which could empower organizations to deliver cost-efficient yet performant computing environments to its members. With the iPad App (and other clients), you can log into your WorkSpace, a hosted virtual desktop in the cloud, and work like you were sitting right in front of a full-scale desktop computer. I'm very excited for the opportunity to learn and grow while delivering massive improvements to usability and stability of the app.

The best part about all of this is now I'm a full-time iOS developer which is awesome. It's what I've wanted to do since I was starting out in computer work, and here I am. It's amazing to have reached a dream of mine, and I couldn't be happier.

Because I now work in iOS all day, I have a lot of great ideas. The latest great idea is a solution to a problem I don't have yet (Huh?). I've been toying with UI bits and pieces. I realized while looking around that there are a lot of swipe-to-reveal ViewController implementations out there. The catch? They all seem to only support left or right directional swiping. What if I want to swipe up to reveal? Or down? Well, never fear, I decided to solve the problem myself!

For my first go at it, I thought, "Hell, let's try Swift!" (This Gist has the code). It was ugly, but it worked. What I really wanted to do was to make all of the positioning based in AutoLayout, which I accomplished. The Swift implementation was fun to write, and it's worth noting that I was able to write this code very fast despite not having interacted with Swift very much. It's quick to pick up and rapid for prototyping, which is pretty cool.

Since Swift is still kind of buggy (the live compiler that does some nice error checking for you kept crashing on my code, for starters, forcing me to quit Xcode, edit my code in a different editor to make it correct, then open Xcode again so it wouldn't pee on itself), I decided I should port the idea to Objective-C to see if any of the stability issues were actually my fault. There were a couple, but by and large it worked pretty well. I even managed to handle orientation changes and whatnot, across iOS 7 and iOS 8.

Spoiler alert (and tangent): iOS 8 deprecates -(void)willRotateToInterfaceOrientation... and its counterparts, so be ready to handle their replacement. I think the way iOS 8 does it is pretty smart, to be fair. Instead of thinking of the orientation of the device, the new thinking around it is to just be flexible to different frame shapes and sizes, and tool your interface to layout dynamically across the multiple sizes that different orientations create.

Back to the story: I ported to Objective-C. What I realized is that I had a really poorly-designed hunk of code. (Source: Gist). It depended on a lot of switch statements and other ugly things, things that would be more easily derived with some better style, too. So, I rewrote the whole damn thing.

In deciding to rewrite it (and since I had the main machinery still in my head) I made it a very strong focus of mine to write this code in such a way that someone who is not me could use it. I think it turned out well. The real meat of it is wiring up some AutoLayout constraints in every direction from two embedded ViewControllers's centerpoints to the RevealingViewController's centerpoint (to be more precise, I mean ther views). Based on a directional value the developer sets, one of these constraints is mutable based on user input via a pan gesture. In addition, the CSRevealingViewController supports a developer-configurable "overhang" of the revealing "top" VC, touch-to-close, and programmatic manipulation.

I think it turned out pretty well, and I'm extremely proud to release it open-source.

GitHub: CSRevealingViewController
CocoaPod/Doc: CSRevealingViewController

Please feel free to submit issues or pull requests with and problems or changes you have in mind. I love collaboration!