Setting the scene…

Being a DevOps fellow at Code for Philly was enlightening on multiple levels. Full disclosure on where I started: Before my interview with my would-be mentor, I watched multiple YouTube videos I found using phrases such as “What is DevOps?”. While starting from square one was intimidating, it forced me to practice asking basic questions I’m often afraid to ask. Questions like “What’s the difference between a container and a virtual machine?”, “Wait, is there a difference between a container runtime and a container engine?”, and “What exactly is inside /bin and /lib again?” Most of these were answered by Google, but my mentor Kris never failed to be patient and helpful throughout the process—it turns out orchestration isn’t just a word for musicians!

During my fellowship, I worked with the following technologies either for the first time or deepened my previous level of understanding:

  • SSH
  • Git and Github
  • Docker
  • Kubernetes
  • Command line tools such as netstat, netcat, and curl

I also encountered a lot of new words. Example vocabulary that was either added or solidified included: * Cluster * Container * Keys * Hypervisor * Orchestration * Proxy * Virtual machine * YAML/YML (“What’s the difference?”)

The above knowledge (and more!) was acquired while helping with the deployment of Code for Philly’s new data system for Prevention Point Philadelphia. The fellowship was about a lot more than picking up new technical skills though, and I feel what Code for Philly offered beyond tech was just as important as learning to navigate a Dockerfile.

Three (not necessarily) simple technical exercises highlighting what I learned:

1. Deploying an app locally with Docker

Kris and I got started by making sure I was acquainted with generating SSH keys and cloning a git repo. While this wasn’t entirely new to me, it did serve as a good refresher on the principles behind SSH and got me actually utilizing the protocol to do something useful—in this case, cloning a repo. This was a good test of basic knowledge: What’s the difference between cloning a repo vs downloading it from GitHub?

Once I had successfully cloned the repo on my machine, it was time to run the Prevention Point app locally. This is where I encountered Docker for the first time and was reminded of another important tip to keep in mind when interacting with a codebase: Read the documentation! Kris and I talked about Docker, I installed it, and I read the Docker tutorial on building and running images. It all made sense until I tried to apply my newfound knowledge to Prevention Point. I ran into error after error trying to successfully build the database, app, and client. Having felt like I had made an honest effort, I asked Kris for help. It was during our conversation that I learned that while I had done my homework learning the basics of Docker, I had forgotten to read the Prevention Point readme. Oops. This is where I was introduced to Docker Compose and learned that nearly all of the work had already been done for me. A simple docker-compose up was all that was needed and I was up and running.

2. Deploying an app on a remote VM and configuring a reverse proxy

The next assignment Kris gave me was to repeat this process, except this time remotely on a VM hosted on Linode. He also suggested I add the feature of an NGINX reverse proxy. While the first part went smoothly, setting up the proxy did not. A small part of me was relieved when Kris wasn’t able to quickly point to an obvious-in-hindsight error I had made. It turned out I needed to place a small snippet of code (see below) in /etc/nginx/sites-available/default that allowed for successfully passing the request off to the app. A useful bonus lesson from this exercise was a review of Linux File Hierarchy Structure—it had been a long time since I had given much thought to what’s actually hanging around in /etc.

location ~ / {

As a beginner to the world of DevOps and server configuration in general, it took a while to figure out exactly what that code should look like, where it should go, and why. The most vexing problem was that the only error I had to work with was “connection reset”. I learned quickly that this could be caused by a host of issues including browser compatibility, firewall settings, server configuration, authentication, or some combination of the above. The vagueness of the error left me scratching my head, and taking in multiple how-tos, StackOverflow threads, and YouTube videos that never seemed to quite match what I thought the problem might be. This is where Kris was a tremendous help. I may have been stuck for days longer had I not requested a Hangouts session after a couple frustrating afternoons.

3. Deploying an app on a cloud platform using Kubernetes

The next and final step to take was to deploy the current version of the Prevention Point app to a cloud platform while taking advantage of Kubernetes. We decided it would be instructive for me to go through Kubernetes’ own tutorial, and then see if I could use what I learned to get the app running on my machine using Minikube. In what I believe is a familiar pattern for many, the Kubernetes tutorial seemed straightforward enough, installing VirtualBox, Minikube, and Kompose was doable (there were a few hiccups, but I got there), but when confronted with actually using Kompose to move an app from Docker to Kubernetes, there was trouble. Many error messages, written tutorials, and YouTube videos later, I again turned to Kris for help. “Being tech savvy is just knowing how to Google” is something of a meme, but watching Kris troubleshoot what was going on showed me how it comes into play at all levels of expertise. After he looked up docs, tutorials, and logs, and applied that knowledge to the task at hand, he was able to diagnose that there was an issue with the container rather than a step missing in how we were using Kompose. Getting to this stage turned out to be challenging for both of us, and Kris wasn’t able to conclude there was a container issue until he had experimented with trying to deploy the app on Minikube as well as a Linode cluster. Unfortunately at the time of this writing, we still haven’t ironed out exactly what is being lost in translation between Docker and Kubernetes. However, getting to watch, ask questions, and have a conversation with Kris while he dealt with an issue that is currently over my head gave me a glimpse into what a future in DevOps may look like.

Three things that made the fellowship about more than tech:

1. Exposure to teamwork

One of the most interesting aspects of this opportunity was getting to be part of a motivated team. While all of our meetings were virtual due to the pandemic, they were still meetings of tech professionals where I got to be part of a knowledgeable group of people communicating with one another to solve problems. This was only my second opportunity being part of a team in the world of tech, and it was a refreshing change after working almost entirely alone during my graduate studies in computer science. I felt welcomed by all, and was routinely impressed by the team’s efficiency. I found the setup of two weekly meetings (one with the team, one with my mentor) to be ideal, and they were just the right mix of exchanging pleasantries and getting down to business.

2. Mentor support

As described above, sometimes finding a solution to a challenge I was facing proved difficult. When this happened, the challenge was solved much faster and my learning was accelerated thanks to access to a mentor. I tend to like to figure everything out for myself, and while that saved Kris from having to give me the textbook definition of a hypervisor, it can also leave me stuck for unreasonable periods of time. Having someone I could reach out to and troubleshoot with in real time was my favorite feature of the fellowship. I felt more comfortable than I thought I would asking questions, and will conclude my fellowship feeling like I’ve made a genuine connection with a competent, helpful individual in the tech industry.

3. Reflecting on your work

On a somewhat meta note, I also learned a bit about writing a blog post. Code for Philly was kind enough to connect us with Vicki Boykis via Zoom, and she provided us with tons of useful advice on tech blogging. One such piece of advice I should have followed was to take notes as I made my way through the fellowship—doubly so since I knew I was going to have to write a blog post near the end! While I kept a messy list of questions I asked myself along the way, I wish I had kept specific notes on what I was doing while troubleshooting. My Slack messages with Kris provided a trail of breadcrumbs to reference for this post, but next time I’ll definitely be doing more thorough documentation!

Wrapping up, looking ahead…

As my time being a fellow comes to a close, I can definitively say it has been a positive experience. I’m hoping to figure out exactly what that Docker container issue was all about, and am looking forward to presenting what I’ve learned to the rest of the Code for Philly community. I’m thankful the organization allowed me the opportunity to recharge my resume after a sizable gap, and to broaden my tech skill set to include basic DevOps competencies. I’m just as thankful for the exposure I got to a group of friendly, skilled people in the Philadelphia area. Going forward, I’m hoping to put my skills to work in a professional capacity, and will be keeping my eyes open for ways I can help others the way Code for Philly has helped me.