How to Ryan

Hi, welcome to the team. I’m so glad you are here at $COMPANY.

It’s going to take a solid 90 days to figure this place out. I understand the importance of first impressions, and I know you want to get a check in the win column, but this is a complex place full of equally complex humans. Take your time, meet everyone, write things down, and ask all the questions – especially about all those baffling acronyms … healthcare is full of them

One of the working relationships we need to define is ours. The following is a user guide for me and how I work. It captures what you can expect out of the average week, how I like to work, my north star principles, and some of my, uh, idiosyncrasies. My intent is to accelerate our working relationship with this document.

Our Average Week

During your first 90 days we’ll have a 1:1 every week for about 30 minutes. I try to never cancel this meeting so it might get moved around a bit. I would like to apologize for this in advance.

After 90 days I let you decide how frequently or infrequently we meet. Some people meet with me every week even after the 90 days. Some meet once a month. However, once a month is the longest I feel conformable between 1:1s.

If you are curious about the 1:1s I have with my manager I’m more than happy to tell you about their frequency and duration. I meet with my boss at least once a week for anywhere from 30 – 90 minutes. It just depends on the week.

The purpose of our meeting is to discusses topics of substance, not updates (there are other platforms for that). Sometimes they can morph into update type meetings. I’ll do my best to keep that from happening, and I ask that you do the same. I have a running list of items that I will want to discuss with you and I encourage you do have the same.

We have scrum every day unless it’s retrospective day. I act as the scrum master to help move the meeting along, but during the meeting I’m the scrum master, not the manger (I even wear a silly hat). The purpose of the scrum is to tell the team three things:

  1. What I did yesterday
  2. What I’m doing today
  3. What, if any, roadblocks I have

The scrum master will make note of the roadblocks and work to remove them as quickly as possible. Sometimes this is fast, sometimes it’s not.

Every 2 weeks we have a Sprint Retrospective and Planning session. This lasts about 90 minutes. The purpose of this meeting is to review the previous Sprint and to plan out the issues that will be worked on in the next one.

When reviewing the previous sprint we ask ourselves four questions:

  1. What did we do well?
  2. What could we have done better?
  3. What did we learn?
  4. What still puzzles us?

This is a time to be honest and constructive. If the scrum master didn’t manage the scrum well, say so. If Bob didn’t get back to you say so. If you learned an amazing new way to query the database that is more performant give a shout out.

If I am traveling or will be out of the office on PTO (yes, I take PTO and you should too once you can), I will give you notice of said travel in advance. Depending on the type of travel I may need to cancel our meeting. If it’s a weekly meeting I won’t reschedule. If it’s not weekly then I’ll reschedule for as close to the day when I’ve returned as I can.

Sometimes I work on the weekends. Sometime I work late. Unless we have a big project that you are working on and it needs to get done I don’t ask anyone else to work late or on the weekends. I want you to have a life outside of work.

North Star Principles

Humans first. I believe that happy, informed, and productive humans build fantastic products. I try to optimize for the humans. Other leaders will maximize the business, the technology, or any other number of important facets. Ideological diversity is key to an effective team. All perspectives are relevant, and we need all these leaders, but my bias is towards building productive humans.

Leadership comes from everywhere. My wife likes to remind me that I hated meetings for the first ten years of my professional career. She’s right. I’ve wasted a lot of time in poorly run meetings by bad managers. I remain skeptical of managers even as a manager. While I believe managers are an essential part of a scaling organization, I don’t believe they have a monopoly on leadership, and I work hard to build other constructs and opportunities in our teams for non-managers to lead.

It is important to me that humans are treated fairly. I believe that most humans are trying to to do the right thing, but unconscious bias leads them astray. I work hard to understand and address my biases because I understand their ability to create inequity. I am not perfect, but I try to be better today than I was yesterday. Sometimes I succeed. Sometimes I don’t.

I heavily bias towards action. Long meetings where we are endlessly debating potential directions are often valuable, but I believe starting is the best way to begin learning and make progress. This is not always the correct strategy. This strategy annoys those who like to debate.

I believe in the compounding awesomeness of continually fixing small things. I believe quality assurance is everyone’s responsibility and there are bugs to be fixed everywhere… all the time.

I start with an assumption of positive intent for all involved. This has worked out well for me over my career.

Feedback Protocol

I firmly believe that feedback is at the core of building trust and respect in a team.

At $COMPANY, there is a formal feedback cycle which occurs once a year per employee.

During that formal feedback cycle (also called the Annual Review) we will discuss the previous year. There’s a form ($COMPANY loves forms). I’ll fill it out and we’ll discuss it.

This means that at anyone time I could be finishing up 5 reviews or 1.

Notice I say finishing up. I try to make the reviews I write as living documents so I can capture everything from the year, and not just everything from the last month.

If during the Annual Review you are surprised (positively or negatively) by anything, I have not done my job. Please let me know. Feedback is the only way we know we are doing something well, or not well.

I won’t assume you know what I’m thinking, and I ask that you don’t assume I know what you’re thinking.

Disagreement is feedback and the sooner we learn how to efficiently disagree with each other, the sooner we’ll trust and respect each other more. Ideas don’t get better with agreement.

Meeting Protocol

I go to a lot of meetings. In the morning scrum many times I will indicate that today I have several meetings. I don’t enumerate all of them because I don’t think everyone wants to know specifically which meetings I’m going to. If I think it’s important for the team to know, I will say, I have meeting X today. If I don’t indicate what meeting I have and you want to know, ask. If it’s not private / confidential I will tell you.

My definition of a meeting includes an agenda and/or intended purpose, the appropriate amount of productive attendees, and a responsible party running the meeting to a schedule. If I am attending a meeting, I’d prefer starting on time. If I am running a meeting, I will start that meeting on time.

If a meeting completes its intended purpose before it’s scheduled to end, let’s give the time back to everyone. If it’s clear the intended goal won’t be achieved in the allotted time, let’s stop the meeting before time is up and determine how to finish the meeting later.

Nuance and Errata

I am an introvert and that means that prolonged exposure to humans is exhausting for me. Weird, huh? I tend to be most active when I’m not running the meeting and there are fewer people. If I’m not running the meeting and there are many people I am strangely quiet. Do not confuse my quiet with lack of engagement.

When I ask you to do something that feels poorly defined you should ask me for both clarification and a call on importance. I might still be brainstorming. These questions can save everyone a lot of time.

I tend to be very reserved but this is not a sign that I am uninterested, it is just who I am. Every once in a while that reserved facade is cracked and I display emotions. That’s when you can tell I’m really excited about a thing (either good or bad).

During meetings in my office I will put my phone on DND and log out of my computer if we won’t be using it. If we will be using my computer I close Outlook and only have the applications open that need to be open. During meetings I will take notes on my phone. I have a series of actions programmed on my iPhone to help keep me on top of things that I need to do. Rest assured, I’m not texting anyone, or checking the next available movie time. When I am done typing a note, I will put the phone down.

Humans stating opinions as facts are a trigger for me.

Humans who gossip are a trigger for me.

I am not writing about you. I’ve been writing a blog (off an on) for a long time and continue to write. While the topics might spring from recent events, the humans involved in the writing are always made up. I am not writing about you. I try to write all the time.

This document is a living breathing thing and likely incomplete. I will update it frequently and would appreciate your feedback.

Basketball Conference Finals OR How the actions of one person can fire up the other team and lead them to win

Last weekend I watched both games 7 of the NBA conference finals. I have no particular affinity for the NBA (I prefer the Madness in March associated with the NCAA) but I figured with 2 game 7s it might be interesting to watch. I was not wrong.

On Sunday night Cleveland was hosted by Boston in a rematch of a game 7 from 2010. One of only 2 game 7s that LeBron James had lost.

This game had all the makings of what you would want a game 7 to be. A young upstart rookie (Tatum) with something to prove. A veteran (James), also with something to prove.

What really stuck our for me, for this game, was what happened at the 6:45 mark in the fourth quarter. Tatum dunked on LeBron (posterized is the term ESPN used) to put the score at 71-69 Cleveland. What happened next though, I think, is why the Cavs won the game.

Tatum proceeded to bump his chest up against the back of LeBron’s shoulder, like a small child might run up to a big kid when he did something amazing to be like, “Look at me … I’m a big kid too!”

LeBron just stood there and looked at Tatum with incredulity. The announcers seemed to enjoy the specticle more than they should have. But LeBron just stood there, the Boston crowd cheering wildly at what their young rookie had just done. To dunk over LeBron, arguably one of the greatest, in a game 7? This is the thing that legends are made of.

But while the crowd and the announcers saw James look like he was a mere mortal … what I saw was the game turning around. The look on James’ face wasn’t one of ‘damn … that kid just dunked on me. It was, “Damn … now I’m going to get mine and I have a punk to show how this game is really played.”

From that point on the Cavs outscored the Celtics 16-10 … not a huge margin, but a margin enough to win. What the score doesn’t show is the look of determination on LeBron’s face as he carried his team to the NBA Finals. Not because he scored all 16 points (he only scored 7) but because he checked his ego at the door and worked to make his team better than the other team. In short, he was the better team mate than Tatum in those last minutes and that’s why the Cavs are in the Finals and the Celtics aren’t.

Tatum’s reaction to dunking on LeBron is understandable. Hell, if I had done something like that when I was his age, I would have pumped my chest up too.

But it the patience and reservedness (that perhaps come with age) that make you a great player or team member. You don’t really want to rile up a great player because that’s the only reason they need to whoop your butt.

Perhaps Tatum will learn this lesson. Perhaps he won’t.

Because you see, acting like a a little kid isn’t just the right of a rookie.

James Harden pulled some immature shenanigans too in his team’s loss to the Warriors. At one point, with the Rockets up 59-53 with 6:13 in the 3rd, Harden when for a layup and was knocked down … accidentally in my opinion.

When a player from the Warriors tried to help him up he just sat there and then flailed his arms until one of his teammates can to help him up. Big man there Harden.

By the end of the 3rd quarter the Rockets were down 76-69. By the end of the game they’ve lost 101-92.

You see, when it comes down to it a great teammate will do what’s best for the team, and not do what’s best for their ego. It doesn’t seem to matter, old or young, rookie or veteran, not having the ability to control your emotions at key points in a game (or in life) can be more costly than you realize.

Sometimes it’s game 7 of the NBA Conference finals, sometimes it’s just a pick up game with some friends at the park, but in either case, being a good teammate requires checking your ego at the door and working to be the best team mate you can be, not being the best player on the court.

To put it another way, being the smartest person in the room doesn’t make you the most influential person in the room, and when it comes down to moving ahead, being influential trumps being smart.

Using Drafts 5 at Work

I have many meetings that I go to in any given day. One of the things that I’d been struggling with was being able to keep track of what I needed to do after a meeting and/or documenting certain types of meetings more effectively.

I have been using a Workflow I created a couple of years ago to get the pertinent details of a meeting into Drafts. I spoke about updating that workflow to incorporate drafts 5 here.

Once I was able to get the information into Drafts 5 a new opportunity arose. I was able to run a Workflow in Drafts!

I decided that getting the information into Drafts was great, but I needed a good way to get it out.

There were two sections in the Draft that I decided I could leverage to help:

  1. Actions
  2. Notes

Broadly speaking there are 3 types of meetings I go to:

  1. Daily Standup aka Scrum
  2. One-on-One with direct reports or my manager
  3. General Meetings

Categorizing the meetings helped me to create Draft Actions that run Workflows for each meeting type.

Scrum

This workflow runs through the Actions of the Draft and adds each one to OmniFocus in a Project called Scrum with a Tag of Work. The due date set for these tasks is noon of the same day. My goal is to have the items that come from Scrum totally processed by noon of that day and for 80% of them I can. Some actions are more involved, but having them in OmniFocus helps me to make sure that they get taken care of.

It also creates a calendar meeting for the next business day with my Scrum template and lets me know which team member will start that next day.

One-on-One

This workflow runs similarly to the Scrum workflow. It adds the Action items to OmniFocus with a due date of noon the same day, tagged with Work and in the One-on-One Project.

Instead of creating a calendar meeting for the next business day at 8:30 it appends items from the Notes section to a Dropbox file. The Dropbox path is predefined, but the name of the file matches the name of the person I met with (luckily I don’t have 2 Tom’s reporting to me).

General Meetings

This is the simplest workflow. It adds all of the items under actions to OmniFocus with a due date of noon, project of Meeting Follow Up and Tag of Work.

After the Actions are run from Drafts the notes are archived in Drafts.

I’m toying with the idea of archiving the notes from these meetings into Dropbox, but I’m not sure that it gets me anything … so I haven’t really looked at it too deeply.

Workflow links

The links for each of the workflows can be found here:

Parse Scrum Notes

Parse One-on-One Notes

Parse Meeting Notes

Setting up Jupyter Notebook on my Linode

A Jupyter Notebook is an open-source web application that allows you to create and share documents that contain live code, equations, visualizations and narrative text.

Uses include:

  1. data cleaning and transformation
  2. numerical simulation
  3. statistical modeling
  4. data visualization
  5. machine learning
  6. and other stuff

I’ve been interested in how to set up a Jupyter Notebook on my Linode server for a while, but kept running into a roadblock (either mental or technical I’m not really sure).

Then I came across this ‘sweet’ solution to get them set up athttp://blog.lerner.co.il/five-minute-guide-setting-jupyter-notebook-server/

My main issue was what I needed to to do keep the Jupyter Notebook running once I disconnected from command line. The solution above gave me what I needed to solve that problem

nohup jupyter notebook

nohup allows you to disconnect from the terminal but keeps the command running in the background (which is exactly what I wanted).

The next thing I wanted to do was to have the jupyter notebook server run from a directory that wasn’t my home directory.

To do this was way easier than I thought. You just run nohup jupyter notebook from the directory you want to run it from.

The last thing to do was to make sure that the notebook would start up with a server reboot. For that I wrote a shell script

# change to correct directory
cd /home/ryan/jupyter

nohup jupyter notebook &> /home/ryan/output.log

The last command is a slight modification of the line from above. I really wanted the output to get directed to a file that wasn’t in the directory that the Jupyter notebook would be running from. Not any reason (that I know of anyway) … I just didn’t like the nohup.out file in the working directory.

Anyway, I now have a running Jupyter Notebook at http://python.ryancheley.com:88881

  1. I’d like to update this to be running from a port other than 8888 AND I’d like to have it on SSL, but one thing at a time!

A Summary of Dale Carnegie’s “How to Win Friends and Influence People”

This is mostly for me to write down my notes and thoughts about the book “How to Win Friends and Influence People.”

I’ve noted below the summary from the end of each section below (so I don’t forget what they were).

The first three sections seemed to speak to my modern sensibilities the most (keep in mind this book was published in 1936 … the version I read was revised in 1981).

I have the summaries below, for reference, but I wanted to have my own take on each.

Fundamental Techniques in Handling People

This seems to be a long way of saying the “Use the Golden Rule” over and over again. The three points are:

  1. Don’t criticize, condemn or complain
  2. Give honest and sincere appreciation
  3. Arouse in the other person an eager want

Six ways to make people like you

The ‘rules’ presented here are also useful for making small talk at parties (or other gatherings). I find that talking about myself with a total stranger is about the hardest thing I can do. I try to engage with people at parties and have what I hope are interesting questions to ask should I need to. Stuff I tend to avoid:

  • What do you do for a living?
  • Where do you work?
  • Sports
  • Politics

Stuff I try to focus on:

  • How do you know the host / acquaintance we may have in common
  • What’s the most interesting problem you’ve solved or are working to solve in the last week
  • Have you been on a vacation recently? What was your favorite part about it? (With this one I don’t let people off the hook with, ‘being away from work’ … I try to find something that they really found enjoyable and interesting

These talking points are usually a pretty good starting point. Sometimes when I’m introduced to a person and the person introduces them as their job, i.e. This is Sally Jones, she’s a Doctor at the local Hospital, I’ll use that to parlay away from something work focused (what kind of doctor are you) to something more person focused, why did you want to become a doctor? Where did you go to Medical School? Did you know you always wanted to be a doctor? I try to focus on getting to know them better and have them talk about themselves.

The tips from the book support my intuition when meeting new people. They are:

  1. Become genuinely interested in other people
  2. Smile
  3. Remember that a person’s name is to that person the sweetest and most important sound in any language
  4. Be a good listener. Encourage to talk about themselves
  5. Talk in terms of the other person’s interest
  6. Make the other person feel important – and do it sincerely

How to Win People to your way of thinking

This section provided the most useful and helpful information (for me anyway!). It really leads to how to have better influence (than winning friends).

One of the problems I’ve suffered from throughout my life is the need to be right about a thing. This section has concrete tips and examples of how to not be the smartest person in the room, but working on being the most influential person in the room.

My favorite is the first one, which I’ll paraphrase to be “The only way to win an argument is to avoid it!” I’d never thought about trying to avoid arguments, only how to win them once I was in them. The idea reminds me a bit of War Games. At the end, Joshua, the super computer that is trying to figure out how to win a Nuclear War with the USSR, concedes that the only way to win is to not play at all. Just like an argument.

The other piece that really struck me was get the other person to say ‘Yes’. This is kind of sales-y and could be smarmy if used with a subtext of insincerity, but I think that the examples given in the book, and using it in the context of trying to win friends AND influence people it can go a long way.

The tips from this section of the book are:

  1. The only way to get the best of an argument is to avoid it
  2. Show respect for the other person’s opinions. Never say “You’re wrong”
  3. If you are wrong, admit it quickly and emphatically
  4. Begin in a friendly way
  5. Get the other person saying “yes, yes” immediately
  6. Let the other person do a great deal of the talking
  7. Let the other person feel that the idea is his or hers
  8. Try honestly to see things from the other persons perspective
  9. BE sympathetic with the other persons ideas and desires
  10. Appeal to the nobler motives
  11. Dramatize your ideas
  12. throw down a challenge

Be a Leader: How to change people without giving offense or arousing resentment

This section has the best points, but the stories were very contrived. Again, this goes to how to win influence more than winning friends. Some of the items are a bit too 1930s for my taste (numbers 2, 3, and 6 in particular seem overly outdated). But overall, they are good ideas to work towards.

The tips are:

  1. Begin with praise and honest appreciation
  2. Call attention to the person’s mistake indirectly
  3. Talk about your own mistakes before criticizing the other person
  4. Ask questions instead of giving direct orders
  5. Let the other person save face
  6. Praise the slightest improvement and praise every improvement. Be “hearty in your approbation and lavish in your praise”
  7. Give the other person a fine reputation to live up to
  8. Use encouragement. make the fault seem easy to correct
  9. Make the other person gabby about doing the thing you suggest

Overall I’m really glad that I read this book and glad that my CHIME mentor Tim Gibbs recommended it to me.

I’ve been actively working to include these ideas into my work and home life and have found some surprising benefits. It’s also helping to make me a little less stressed out.

If you’re looking for a bit of help in trying to be a better influencer in your organization, or your personal life, this book is well worth the read.

Updating my meeting Workflow for Drafts 5

Drafts is a productivity app created by Greg Pierce (@AgileTortoise).

I’ve loved and used Drafts 4 every day for the last several years. I loved it so much I even contributed to the Tip Jar Greg had in the app. Seriously, it’s an amazing app. If you haven’t downloaded it already you totally should.

Recently, Greg released Drafts 5. With this new version comes a new Business Model as well. Instead of a single pay (and hope people ‘tip’ you) he’s converted to a subscription model.

I signed up for the free week and didn’t have a real opportunity to use it before my free week was converted into a pay week but I’ve no regrets. I like what Greg does and want him to keep updating his app so that I can get the benefits of it once I have a real chance to dive in.

Part of the reason I wasn’t able to really use the new version is the way that I primarily use Drafts. I have a WorkFlow that takes a meeting on my work calendar and allows me to take notes about that meetings.

It’s one of the most useful productivity tools I have during my morning standup meetings with my team, and it’s useful for the other (sometimes endless) meetings that I go to.

With the release of Drafts 5 I was not longer able to use both Drafts 5 AND my workflow, so I needed to update my workflow.

With Drafts 4 it was just one of the built in Apps. Because Drafts 5 limits some of the functionality unless you have the PRO version I don’t think that Workflow will be updated to include Drafts 5 like it did Drafts 4.

Once I realized that AND since I’m paying for the app I figured I’d need to update my Workflow instead of waiting and hoping that Workflow would be updated to include Drafts 5.

In order to make the update I had to look for URL Scheme for Drafts 5 … but I couldn’t really find one. I assumed that Drafts 5 URL Scheme would be the same as Drafts 4 (I was right) and made various attempts at getting a copy of the Workflow to work with Drafts 5.

This is the section of the workflow that needs to be updated:

Since Drafts 5 isn’t included in the Built in Apps I was going to need to pass a URL and open the app.

This would require 3 separate steps in Workflow

  1. Convert Text into URL Encoded string
  2. Prepend the URL Scheme for creating a new draft to the URL Encoded String
  3. Open the URL

This basically means that 1 step is now replaced with 3 … but hey, that’s the price of progress must be paid!

Both the Drafts 4 and Drafts 5 versions of these workflows are available.

If you enjoy them, hit me up in the comments or let me know on Twitter @ryancheley!

OmniFocus 3!

The OmniGroup posted on their blog the other day that they have a ship date for OmniFocus 3 … May 30.

To say that I’m excited is a bit of an understatement. I’ve been a loyal OmniFocus user for about 5 years now, and though I have declared OmniFocus bankruptcy once, I still believe it’s a super useful App and I could not imagine life without it.

OmniFocus3 will bring with it tags which is something I’ve really wanted and struggled without in using OmniFocus2. Sometimes things don’t just fall into pure GTD contexts and tags appear to be a recognition of that.

The initial release on May 30 is iOS only. The Mac Version is set to be released in 2018 but no firm date has been announced.

Only 25 days until upgrade day 😊

Making it easy to ssh into a remote server

Logging into a remote server is a drag. Needing to remember the password (or get it from 1Password); needing to remember the IP address of the remote server. Ugh.

It’d be so much easier if I could just

ssh username@servername

and get into the server.

And it turns out, you can. You just need to do two simple things.

Simple thing the first: Update the hosts file on your local computer to map the IP address to a memorable name.

The hosts file is located at /etc/hosts (at least on *nix based systems).

Go to the hosts file in your favorite editor … my current favorite editor for simple stuff like this is vim.

Once there, add the IP address you don’t want to have to remember, and then a name that you will remember. For example:

67.176.220.115    easytoremembername

One thing to keep in mind, you’ll already have some entries in this file. Don’t mess with them. Leave them there. Seriously … it’ll be better for everyone if you do.

Simple thing the second: Generate a public-private key and share the public key with the remote server

From the terminal run the command ssh-keyken -t rsa. This will generate a public and private key. You will be asked for a location to save the keys to. The default (on MacOS) is /Users/username/.ssh/id_rsa. I tend to accept the default (no reason not to) and leave the passphrase blank (this means you won’t have to enter a password which is what we’re looking for in the first place!)

Next, we copy the public key to the host(s) you want to access using the command

ssh-copy-id <username>@<hostname>

for example:

ssh-copy-id pi@rpicamera

The first time you do this you will get a message asking you if you’re sure you want to do this. Type in yes and you’re good to go.

One thing to note, doing this updates the file known_hosts. If, for some reason, the server you are ssh-ing to needs to be rebuilt (i.e. you have to keep destroying your Digital Ocean Ubuntu server because you can’t get the static files to be served properly for your Django project) then you need to go to the known_hosts file and remove the entry for that known host.

When you do that you’ll be asked about the identity of the server (again). Just say yes and you’re good to go.

If you forget that step then when you try to ssh into the server you get a nasty looking error message saying that the server identities don’t match and you can’t proceed.

Automating the Hummingbird Video Upload to YouTube or How I finally got Cron to do what I needed it to do but in the ugliest way possible

Several weeks ago in Cronjob Redux I wrote that I had finally gotten Cron to automate the entire process of compiling the h264 files into an mp4 and uploading it to YouTube.

I hadn’t. And it took the better part of the last 2 weeks to figure out what the heck was going on.

Part of what I wrote before was correct. I wasn’t able to read the client_secrets.json file and that was leading to an error.

I was not correct on the creation of the create_mp4.sh though.

The reason I got it to run automatically that night was because I had, in my testing, created the create_mp4.sh and when cron ran my run_script.sh it was able to use what was already there.

The next night when it ran, the create_mp4.sh was already there, but the h264 files that were referenced in it weren’t. This lead to no video being uploaded and me being confused.

The issue was that cron was unable to run the part of the script that generates the script to create the mp4 file.

I’m close to having a fix for that, but for now I did the most inelegant thing possible. I broke up the script in cron so it looks like this:

00 06 * * * /home/pi/Documents/python_projects/cleanup.sh
10 19 * * * /home/pi/Documents/python_projects/create_script_01.sh
11 19 * * * /home/pi/Documents/python_projects/create_script_02.sh >> $HOME/Documents/python_projects/create_mp4.sh 2>&1
12 19 * * * /home/pi/Documents/python_projects/create_script_03.sh
13 19 * * * /home/pi/Documents/python_projects/run_script.sh

At 6am every morning the cleanup.sh runs and removes the h264 files, the mp4 file and the create_mp4.sh script

At 7:10pm the ‘header’ for the create_mp4.sh runs. At 7:11pm the ‘body’ for create_mp4.sh runs. At 7:12pm the ‘footer’ for create_mp4.sh runs.

Finally at 7:13pm the run_script.sh compiles the h264 files into an mp4 and uploads it to YouTube.

Last night while I was at a School Board meeting the whole process ran on it’s own. I was super pumped when I checked my YouTube channel and saw that the May 1 hummingbird video was there and I didn’t have to do anything.

Whoops! Or how I broke my website by installing Nginx with Apache

I’ve been working on a project to create a Django based website. Over the weekend (Saturday I think) I tried to get it up and running on my Linode server. However, after a couple of failed attempts I decided to use the free hosting coupon1 I had for DigitalOcean to see if that allowed me to reply more easily deploy … the short answer … meh.

What I didn’t realize over the weekend is that while I had been trying to deploy my Django site, I had installed Nginx on my Linode server that was also running apache2. This lead to them both trying to listen on port 80 but because Nginx was the last thing I had kicked off, it was winning.

While I was working on my Django site I should have realized that something was up when I tried to connect to the blog for the site (still a WordPress site on my Linode server) and it returned a ‘Can not connect to the server message’. I didn’t pay much attention because I figured (incorrectly) that I had done something specific to that subdomain, and not that I had made all of the sites on my Linode server inaccessible.

Last night at about 9 I thought, “Well, it should’t take long for me to figure out the issue with the new blog. ”

By 10:15 I tried everything the internet had told me to try and I was still unable to get apache2 to reload.

I googled a bunch of stuff, but nothing was helping.

When I tried to get the status on apache2 I would get this:

● apache2.service - LSB: Apache2 web server
   Loaded: loaded (/etc/init.d/apache2; bad; vendor preset: enabled)
  Drop-In: /lib/systemd/system/apache2.service.d
           └─apache2-systemd.conf
   Active: inactive (dead) since Tue 2018-05-01 05:01:03 PDT; 5s ago
     Docs: man:systemd-sysv-generator(8)
  Process: 7718 ExecStop=/etc/init.d/apache2 stop (code=exited, status=0/SUCCESS)
  Process: 7703 ExecStart=/etc/init.d/apache2 start (code=exited, status=0/SUCCESS)

May 01 05:01:03 milo apache2[7703]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
May 01 05:01:03 milo apache2[7703]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
May 01 05:01:03 milo apache2[7703]: no listening sockets available, shutting down
May 01 05:01:03 milo apache2[7703]: AH00015: Unable to open logs
May 01 05:01:03 milo apache2[7703]: Action 'start' failed.
May 01 05:01:03 milo apache2[7703]: The Apache error log may have more information.
May 01 05:01:03 milo apache2[7703]:  *
May 01 05:01:03 milo apache2[7718]:  * Stopping Apache httpd web server apache2
May 01 05:01:03 milo apache2[7718]:  *
May 01 05:01:03 milo systemd[1]: Started LSB: Apache2 web server.

This morning I started to google each line of the status message and finally got to this:

no listening sockets available, shutting down

Googling for that lead me to trying this:

sudo netstat -ltnp | grep ':80'

Which output this:

tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      3324/nginx -g daemo
tcp6       0      0 :::80                   :::*                    LISTEN      3324/nginx -g daemo

And finally, I saw the issue. Over the weekend while I was futzing around I had apparently installed Nginx and let it listen on port 80 AND kept it running.

Once I killed the Nginx process with this:

sudo kill -9 3324

I was able to restart apache2 with no problems.

Thank goodness.

I find that when I mess something up like this it’s important to ask myself what I learned from the experience.

In that vein …

What did I learn from this experience?

  1. Can’t run apache2 and Nginx on the same server and have them listen on the same port. Seems obvious, but you know having to actually deal with it really seals the deal
  2. The output messages are super helpful … google each part of them and don’t give up
  3. A good night’s sleep can make all the difference
  4. Rolling your own web server is less expensive than having it be Turnkey (a la SquareSpace, or some other hosted solution) but you end up being your own Sys Admin and that’s actually pretty easy when things are going well, and a freaking nightmare when they’re not
  1. Thanks to the Talk Python to Me Course for Entrepreneurs