This structure was also partially inspired by Jennifer Dewalt and her amazing 6-month journey to becoming a developer, where she created a new site every day for 180 days. Our goal is more incremental, and will initially only span the month of December.
It should probably go without saying that this course structure is not only beneficial to my brother but also to me as well. It is my opinion that you never truly know a subject until you can teach it to others. Teaching him code is going to help solidify in my mind what I really know and what I myself could still use work on.
But wait, there’s more!
Even better, since I want my brother practicing code and not worrying about anything else, I’m going to be designing a new site every day for him to code. This is really exciting since it’s the perfect combination of pressure and motivation that I need get off my ass and hone my design skills.
I’m a big proponent of having a multifaceted skillset. In the context of being a developer, this usually means also becoming skilled (or at least proficient) in design and marketing as well as programming. So this is clearly a win-win for both of us.
A work in progress
This whole course structure is of course subject to change. Over the course of the month I’ll undoubtedly have to tweak and revise my methods as the strengths and weaknesses of this approach come to light. That being said, I’m really looking forward to the process and I’m excited to see the results of our work.
I’ll be posting updates over the next few days as we dive into it.
I just returned to the US after a few months in Asia, and my goal for the month of December is to teach my brother how to code. One month, that’s how much time I have to get him up to speed. Sound crazy? It might be, but that depends on the concrete goal. “Learn to code” is far too abstract.
In one month’s time I intend to get my brother up to speed with front-end development. But “up to speed” does not mean he will be writing the next front-end framework in just one month. My goal is more along the lines of quickly smashing through the usual barriers people face when they want to learn code. These usually include things like:
All sorts of mental barriers (“It’s too hard.”, “I’m starting too late?”, “Where do I start?”)
Time constraints. (If you have a full-time job it might be hard to find the time to code.)
When I learned to code those first two points were the biggest barriers to progress. Not knowing where to start is a big hurdle to overcome if you are brand new to coding and don’t know anyone in the field. Luckily I do this for a living so I can help my bro get passed that pretty quickly.
Over the next month, I see frustration as the largest obstacle to progress, especially since we’re focusing on the front-end.
Moreover, I hope to give him enough knowledge that he can continue comfortably on his own. That is the ultimate goal.
Since we’re focusing on the front-end, I’ll be teaching the classic front-end technologies:
Each have their own challenges.
HTML is busywork. It’s not particularly difficult to understand or implement, the number of tags and attributes are all quite limited and there’s no logic to consider. That being said, it’s just not interesting. In fact, writing HTML is intensely boring, especially once you know what you’re doing. (That’s why I moved to Jade 😄.)
CSS is a terrible language. It was designed for a very different web than we design for today. Styling text is usually simple enough, but when you want to get into any sort of layout styling things can get very frustrating very fast. Want to put something on the right? Just use float: right; and everything will be fine… until your containing div collapses and you have to figure out what “clearfix” means and how to implement it. Or you could just use overflow: hidden;, but that is unintuitive at best and at worst can cause issues with absolutely positioned elements and shadows.
There are a million other ways CSS can frustrate people, since so many of its properties simply don’t work the way you expect, or you need to ensure certain display properties to make them work as advertised.
The other issue with CSS in my mind is that like HTML, it’s boring. There’s more opportunity in CSS to write good code, but it still lacks logic and lacks features that seem wildly obvious (Variables anyone?).
For a partial solution, learn CSS well then never touch it again and only use Stylus.
Finally, the actual programming language of the front-end. I haven’t yet started teaching this to my brother, but I’m looking forward to it. Real programming is a thrill once you gain even a tiny amount of knowledge. Being able to create things from scratch that are actually useful is liberating; at least it was for me. By the end of this makeshift bootcamp I hope my brother feels the same way.
This is a quick overview of how to get a Meteor app set up on Dokku. It’s actually not difficult, but it doesn’t seem to have been well documented anywhere yet. Let’s get started.
What you need
Obviously, you will need a server running Dokku. I used the Digital Ocean Dokku droplet, which uses the following versions:
If you have a different setup your results may vary, but I’m guessing this guide will generally work for you as long as you have Dokku v0.2.3 setup.
You also need a meteor app. If you are reading this just out of curiosity and don’t have an app feel free to use one of the example apps. You can generate them easily through the CLI. Example:
$ meteor create --example todos
First of all, the default buildpack that Dokku will use if it detects a Meteor app is the Heroku Buildpack, which is not yet compatible with Meteor 1.0 and still uses Meteorite. That’s no good, so you will need to specify a custom buildpack for Dokku. The buildpack I’ve used successfully with Meteor 1.0 is Meteor Buildpack Horse. As of this writing (11/22/14) the documentation still doesn’t reflect that it’s compatible with 1.0, but it’s worked so far so don’t worry about that.
To specify a custom buildpack, just create a file in your project root named .env and within that file export the buildpack URL like so:
This may take a few minutes since it will need to install mongodb-server on the remote machine, unless you’ve already installed Mongo in which case it should be quick. Once it’s done, start Mongo and link it to your app:
Note: In the following snippet replace <app> with the name of your application, assuming you’ve already pushed it to Dokku. If not, push your app up first and then run these commands. Your app name is what you specify in the git remote URL that points to Dokku. It looks like [email protected]:<app>.
$ mongodb:create <app>
If you haven’t yet, deploy your app to Dokku. It will most likely crash (i.e. You get an Nginx error when you hit your URL), but that’s fine as it is still missing one last piece.
The final step is to set the ROOT_URL environment variable in your app container. You need to have pushed your app at least once for the app container to exist. Replace <url> with the URL you intend to use for your app. If you haven’t yet purchased a domain name, you can set this variable to your IP address and it should still run just fine. Don’t forget the leading http:// (ex: http://example.com or http://0.0.0.0):
$ dokku config:set <app> ROOT_URL=<url>
Setting the environment variable will trigger Dokku to restart your app. Once it does you should be able to view the app at the URL you provided in<url>.
That’s it. Hopefully this helps as you deploy your meteor apps quickly using Dokku. If you want to create another meteor app you will just need to run through the above steps again, with the exception of adding the MongoDB plugin.
If you had trouble with anything above there are a couple ways you can troubleshoot Dokku and it’s containers:
Inspect the apps logs. This is likely the most useful troubleshooting technique, and will likely reveal the problem. Run dokku logs <app>.
If the logs don’t reveal the issue, put Dokku into debug mode and re-deploy. To do this you need to create a new Dokku config file at /home/dokku/dokkurc. Add a single line to the file: export DOKKU_TRACE=1. Now when you deploy, Dokku will send back a lot more information.
A couple weeks ago I made the decision to reinstall OSX and start anew, washing away over a years worth of accumulated files. It took about two hours to get most things reinstalled and running again, and after the fact I was very happy with the results. My computer is now fresh again, the downloads folder doesn’t have 1000 items in it and I have over 100GB of free space (up from ~5GB before)! All in all a very quick and painless experience… until this week.
Know what to migrate
It’s tough to keep track of everything on your system that’s vital to your day-to-day workflow. The toughest are the things that aren’t needed day-to-day, but which become vital the second you try do something that depends on them. In my case this was building an android app for distribution.
To distribute an app on the Google Play Store you need to create a Java Keystore to sign your app with. This file is monumentally important if you’re an app developer, because without it you cannot update your app. This week I had to update an app on Google Play and figured out how important that file was.
Time Machine to the rescue
Luckily, I did make sure to back up my entire system before reinstalling OSX, so I knew I must have my Java Keystore saved somewhere. I just had to find it. This was actually surprisingly fast as I had initially stored it under a folder named keystore. Simple enough. I hit restore in Time Machine and done, it was on my system.
Excellent, now I just need to sign my Android APK and I would be good to go. This particular project is built with Cordova, so the easiest way I’ve found to do this is to specify an ant.properties file under platforms/android. There’s a great, concise article on this with full instructions.
Great, now to just run the command…
$ cordova build android --release
[input] Please enter keystore password
… shit. Did not remember my keystore required a password.
At point I ended up trying a few common passwords all of which failed, but I did ultimately figure it out. I wrote a quick Ruby script to run through a list of about 20 potential passwords and one of them did turn out to be the right one. So in the end not a terrible experience, just a strong reminder that backing up everything is always a good idea, and backing up the keys to your apps is paramount.
I was reminded today of just how much opportunity there is in the world. I met with a new friend and potential client to discuss two websites he wants to build. Our talk focused mostly on his business, but we made a number of digressions into general business in Asia, incorporation, visa issues and a number of other topics of concern to expats.
A quick digression
…don’t work for free.
After a nice hour long chat we finally came to the point of the matter: Project details and compensation. The offer he gave was an all-to-common one: Build this “small” thing for free and their will be tons of paying work down the road. I can’t speak to the experience of other developers, but this is something I hear all too often. Potential clients like to lure people of various background to do some up front work for free with a promise to deliver paying work down the road. Projects like these can be tempting for new developers, but they rarely pan out. Doing free work, regardless of the promised riches down the road, is generally a mistake and at best it means taking on unnecessary risk as a developer. If the project works out, you might get paid later or you might not, but even if you do there’s really no reason to wait unless you truly believe in the project (i.e. you think it’s the next Facebook). Business if full of risk, but working as a developer/freelancer/consultant should not be risky work.
New business opportunities
So, for the time being that particular project isn’t going to be on my todo list but it was an insightful conversation nonetheless and we ended up talking for two hours. What really stood out to me was another proposal that my friend made, which was to go into apparel sales here in Taiwan.
The idea of selling apparel in Taiwan would have seemed like a novel idea a day ago, but after listening to my friend talk about the opportunities in the market and the success he’s already had I must say I’m intrigued. I don’t plan to start selling apparel tomorrow, but I was reminded of something that I truly hope I will never forget: Opportunity is everywhere. As a developer it’s so easy to get sucked in to the world of code. After all, if you can code you can literally build anything you want. But from a business perspective it is really only one small slice of the much larger economy, and there are all sorts of opportunities elsewhere as well.
Good conversation should be thought provoking, and todays meeting certainly hit the mark.
I’m now well into week two of my diet and I realized something unexpected: I have largely given up coffee. I the past I would regularly drink 3-4 cups a day, but lately that amount has decreased to 1 cup at most. I would have never expected to accidentally give up coffee, I always thought it would be a sever exercise in willpower if I were to ever decide I needed to give it up. Turns out all I needed was to stop drinking coffee I liked…
Turns out I really don’t like dark roasts. I know many people like the bitter, charred flavor that you get with a darker roast but it is not for me. Despite drinking dark roast coffee black on a regular basis since starting my diet, it was only a couple days ago that I discovered what it means to enjoy a cup of black coffee. I was out at a café and ordered their daily special. I had no idea what it was, but daily specials usually interest me and it also happened to be much cheaper than all the frappuccino-latte-type choices that most everyone else was drinking.
I sipped it, expecting the all too familiar bitterness that I dislike in black coffee but it was not to be found. I was nearly stunned at how delicious and fragrant the coffee was. I drank more. I was hooked. It was a bit of a strange experience to find out that the reason I disliked black coffee all along was not because it wasn’t sweet, but because it simply didn’t suite my taste.
The whole experience was strongly akin to when I first discovered good beer. As a college student I most often drank the cheapest of the cheap beer and happily accepted the fact that it was crap. That’s just the way beer was… Until I tried a Belgian beer. It was a sweet, light tripel and it shattered my preconceptions of what beer should taste like. It opened my eyes and opened the door to enjoying many more beers of all flavors down the road. I hope that this experience with a light roast will do the same for coffee.
My diet choices have been generally unhealthy for the past year, but lately I’ve decided I want abs. As such I asked my buddy Ravi for nutrition advice, and came up with the following daily macros:
This is a very minimal diet as it comes out to ~1800 calories. The point being, I would put my body at a caloric deficit every day and lose weight. Simple 😎
So much protein
Since my normal diet of the past year wouldn’t get me anywhere near 180g of protein in a day I needed to make a change. The simplest way in my mind was to just eat more chicken. Easy enough, I love chicken and know how to cook it. As far as sources of protein go, chicken is amazing. It’s low fat, has zero carbs and of course packs tons of protein. I live near a large chain store called RT-mart (大潤發) here in Taipei. At RT-mart raw chicken breast is packaged such that 1kg of chicken meat costs about $6.60. Not bad a bad price, so I this became my main source of chicken.
I used all that chicken, along with some veggies and kimchi to make dishes like the this:
It was going quite well. Meals like that are very low in carbs and fats and super heavy in protein. I continued to make many similar dishes.
Then I made another…
Sometimes I changed the salad up a bit.
The idea behind these meals was great: Eat mostly protein. The problem was, I never took the time to look up the nutrition facts for what I was eating. I knew on a very general level that chicken had a lot of protein, but I didn’t know exactly how much. Remember how I was buying chicken in 1kg packages? I would make a point of eating that entire pack of chicken over the course of a day, so 1000g. In 100g of raw chicken there are about 23g of protein, so I was actually getting about 230g of protein a day from chicken alone. Then on top of that I was drinking a daily protein shake and eating six eggs for breakfast. Check out this omelet:
So with everything tallied up I was getting about 300g of protein every single day, well ahead of my goal of 180g. At least I was getting it though.
So my takeaway from all this is that you should always be sure to know what your eating before you put it in your mouth. All that extra protein meant that I wasn’t hitting my caloric goals and probably had a caloric surplus most days during the past week. Oh well, lesson learned. From now on I’m going to cut back on the chicken and bring my macros more inline with where they need to be in order to get abs. 🍗 + 🍃 = 💪
UPDATE 2016-11-12: This post is no longer relevant now that Docker for Mac.
One thing to remember
When your running boot2docker on a Mac (and probably Windows as well) it’s important to remember that ports exposed by your containers will not be directly accessible via localhost as you might expect. Since docker is running within boot2docker containers will be exposed via ports on the boot2docker IP.
For example, if running docker ps tells you your app is exposing port 80 on some high-numbered port on the local host, it is actually exposed via boot2dockers IP:
$ docker ps
CONTAINER ID IMAGE NAMES PORTS
6751b94bb5c0 ubuntu:latest 0.0.0.0:49154->80/tcp
Going to 0.0.0.0:49154 in your browser won’t work. You need to replace 0.0.0.0 with boot2docker’s IP address. To find it, run:
$ boot2docker ip
The VM's Host only interface IP address is: 192.168.55.555
Putting that into the browser will along with the correct port will give you 192.168.55.555:49154 and you will be able to access your web app as expected.
This may all be very simple for anyone familiar with networking, but it took me a good amount of time to figure this out with no error message. I guess you should just run Docker on Linux 😉
Although not entirely related, I wrote a gist to automatically export boot2docker’s IP address into an environment variable whenever it is set:
I just want my stuff to work and not break. Programming is not my passion. Making stuff is my passion. – Levels.io
That’s not my quote, but it certainly resonated with me. For the better part of two years I’ve been working as a freelance developer, coding projects for clients to generate some income and occasionally working on projects of my own in my spare time. This has worked out great for me so far: I live where I want (currently Taipei), work when I want and generally have quite a bit of freedom in what I do on a given day.
This line of work has also led me to discover how much I love the web and creating for it. At the same time I’ve also (re)discovered the joy of programming. I regularly tell friends, acquaintances and people I just met that they should learn to code. Not because I believe I know what’s best for them, but because I truly enjoy what I do and I think others might as well.
But why do I enjoy it? This question has come up more than once in my mind. Do I actually enjoy programming for programmings sake? Is it my passion? I think not. I think it’s just as Levels.io said: Making stuff is my passion. Yet, I often spend time doing things that are directly related to programming, but perhaps won’t directly lead to any new creation. Here are a few examples:
I’ve been spending a lot of time recently learning Docker so I can better deploy my apps.
For much the same reason I taught myself Bash and switched all my sites over to Digital Ocean (referral link) so that I could enjoy the obscurity of the command line with all my projects.
When I first started coding I learned Git before I could even build a stable app.
And of course the most egregious example of all: I learned Vim. I certainly don’t regret that, but learning Vim means learning an entirely new programming language call vimscript, all so that you can basically code your own text editor.
The best part is I enjoyed all of it. So maybe I am more of a ‘Programmer’ than I thought. Still, I’d like to always be aware of why I’m doing what I’m doing, and that’s because there are so many cool things to be built that simply don’t exist yet.
TL;DR: If you run into trouble using Mongo with Dokku for a Node.js app, re-image your server and start from scratch.
Today was my first adventure into setting up a full-fledged, database-driven application with Dokku. I built the app with Node.js so I chose Mongo as the database. Local setup was easy, I already had Mongo installed. Setting up the production server also seemed easy at first until it just didn’t work. Here’s I troubleshot it:
The first problem I ran into was an Nginx error page. I forgot the status code, but it essentially meant there was no app running. Strange, since the app was running fine on my local system. Since my application was set to log to stdout I wasn’t able to see any information about what was causing the app to error out, so I decided to do a quick deploy to Heroku and see what was amiss.
Sidenote: I really like Heroku. If it wasn’t so much more expensive than a Digital Ocean droplet I would probably use them for every project.
Troubleshooting on Heroku
Heroku has a great heroku logs command that shows everything an application logged while it was running. As soon as I saw the output I had a face-palm moment: I hadn’t saved all my dependencies to package.js, so I was getting simple “module not found” errors. That was embarrassing, but at least it’s a quick fix.
After cleaning up my package.json file I deployed again and got a database error. Nothing unusual there, I hadn’t added a Mongo database to Heroku. This was to be expected, so I decided to deploy straight back to my own droplet.
Was Dokku Broken?
After redeploying I was still getting the same Nginx error telling me that there was no app running. When I ran docker ps I saw that was true: Only the MongoDB container was running. Lame.
At this point I didn’t know what to try. I’m still not super familiar with Docker/Dokku for deployment, so I used the good old fashioned method of just resetting everything.
I had saved a droplet image on DO right after installing Node but before setting up Dokku with my SSH key, so I just restored to that image. Then I:
Setup my SSH key as usual, not using virtual host naming b/c I still haven’t transfered the clients main site.
Installed the Dokku Mongo plugin and the domains plugin
Created a Mongo container using the plugin: dokku mongodb:create <app>
Created the actual Dokku app from my local server: git remote add dokku dokku@<ip>:<app>
Deployed: git push dokku master
Then everything worked fine. Running docker ps now shows two running containers: one for the app and one for Mongo.
So.. in conclusion
I don’t know what went wrong initially, but resetting everything worked like a charm. So when in doubt, just restore to a stable image and start from scratch. And make sure to make snapshots of your droplet whenever you feel it is in a reusable state. Boosh!