Getting Started with Writing a Technical ebook

The early release of my ebook Juggling JSON with jq comes out tomorrow! However this post is more about the process of writing the book itself.

Getting started on an technical ebook, (such as Juggling JSON with jq), requires a bit of upfront setup. On the ebook side, I decided to go the route of writing the book in Markdown, and generating the various formats using Sphinx. While I feel most comfortable using Markdown, and yet Sphinx uses reStructedText by default. So I had to coax Sphinx to accept Markdown by using a project called m2r. Generating the PDF version of the ebook took a bit to get working. Sphinx uses LaTeX to generate PDFs, and LaTeX while powerful can be clunky to work with. I wrapped everything up with an invoke script, and now I can quickly generating new versions of ebook in the various formats I want to support.

Something unique to writing technical books, is the need to have actual working examples. You can learn by reading, but working through exercises and examples re-enforces that learning. In the case of Unjumbling JSON with jq, I needed an example REST API that readers play with. I searched for some nice open APIs, but nothing seemed very compelling. Many of the open APIs require some form of user registration and non-trivial authentication method that would complicate the examples in the book. So I setup a simple demo API for the book. Thankfully with Docker and Flask, that isn’t a particularly daunting task. (Dockerizing most of my webapps definitely made my live easier overall.)

Finally using Gumroad made marketing and selling the book a lot more approachable. Getting everything setup for e-commerce is a daunting job, if you plan on doing it yourself. Thankfully for ebooks, and similar digital products, Gumroad solves most of the problems one can encounter. I definitely recommend using them if you are planning to do something similar.

Book Announcement: Unjumbling JSON with jq

jq is an amazing tool for querying and manipulating JSON in command-line, that I learned about from one of my good colleagues, Eric Olsen. And I feel that jq deserves a good book describing how to use this tool. Hence I am writing a book called Unjumbling JSON with jq on the topic.

As mentioned in a previous post, I originally planned on writing a single book on both jq and httpie. I divided the original book in two, because there is only a small overlap between the two. I wanted to show examples of grabbing a REST API response via httpie, and parsing the JSON output with jq. However basic querying a REST API is something that could be covered in a short section. By writing the books separately, I will be able to release them faster, and the books will be much more focused.

I plan on selling early drafts of the ebook on August 10th. Buyers of the ebook will get regular versions of the evolving drafts of the ebook, and a free upgrade to the final version of the book. I want to release the early drafts to get early reader feedback. In addition readers of the book will have access to the REST API that accompanies the book.

You can order the early version of Unjumbling JSON with jq from here].

WordPress Password Resets via MySQL

I have not completed the switch away from WordPress completely, (as this site and the justCheckers site show). I might switch to using something like Django CMS or Wagtail. Unfortunately I have not had as much time as I’d like to, to work on Rookeries, my own Flask based CMS

Still in the meantime, I managed to accidentally lock myself out of my own WordPress sites. Thankfully there are a few ways to reset passwords in WordPress. The most surefire way I found was to reset the password using MySQL. (Using the wp-cli tools looks interesting, but I didn’t feel like setting up get another PHP tool.) Most of the time you don’t need to do this. However if you’ve managed to forget your only admin password… well this will get you out of that problem. So what does resetting a WordPress password via MySQL, you ask?

  1. Log into your server via SSH (or to MySQL via a SSH tunnel if you have that enabled)
  2. Login into MySQL: mysql -u $MY_DB_USER -p
  3. Get the username if you have not already. You can look those up in the ${MY_WP_SUFFIX}_wp_users table.
  4. Finally reset the password, using the MD5() function and an update SQL statement: UPDATE "wp_users" SET "user_pass" = MD5('new_password') WHERE "wp_users"."user_login"= "username";
  5. Log in with the user using the regular WordPress login (e.g. https://my-wordpress.example.com/wp-login.php). Remember to change the password, as that will use a stronger hash than MD5 internally and is more secure.

And there you go!

Approaching Inbox Zero in Gmail

Earlier this year (yes I meant to send this out much earlier) I went to a meetup hosted by my local PyLadies group. There Tracy Osborn of Wedding Lovely and Hello Web App fame gave an amazing talk about marketing for developers. I was truly inspired by the talk, and I feel it was very relevant for me, especially as I try to launch my first product and startup Amber Penguin Software. I could write a series of blog posts just on the content from this one meetup alone, and I probably will over time. But today I’ll focus on one thing in particular that I’ve learned from Tracy.

Getting to Inbox Zero

Nowadays I try to not organize my day to day tasks, by either my inbox or even one of my many, many Trello boards. Rather I try to bite off a few urgent and important tasks each day. Still I end up spending time on tasks initiated from emails in my email inbox. Unfortunately my inboxes seems to fill up faster than I can manage them at times. I would love to have a clean inbox as in Inbox Zero technique but more importantly I want to be much more responsive to the emails I get. Also opening up my email can be overwhelming when I see the number of emails in my inbox.

Using Multiple Inboxes in Gmail

One of the things I learned after the meetup, while browsing Tracy’s site was a technique to get my inbox under control at least in Gmail. In essence, you need to enable the “Multiple Inboxes” lab experiment in the Gmail Labs settings. Then you need to write a few filters such as is:drafts || label:follow-up (which happens to be my filter for follow-up emails) for each particular inbox. Et voilà! You have a much more manageable inbox that is subdivided into categories, and the actions you need to take.

Where it works and where it doesn’t work

Unfortunate this technique only works in Gmail at the moment. Some other webmail providers maybe have a similar multiple inbox solution, but unfortunately ProtonMail does not but it is a suggested feature. So my ProtonMail will probably lag behind in terms of how quickly I respond, unless I or someone else implements the multiple inbox feature in ProtonMail.

However where I can use multiple inboxes like in my Amber Penguin Software email (managed by Gmail) it has drastically improved my email experience and my own responsiveness. My Gmail still needs some love to get everything under control, but once I do I will be much better at replying to emails. Ultimately this technique helps you become more confident in categorizing your email, and then acting up on it when the time comes.

Encrypt All the Things!

This week has been a rough one for me, so I’ll keep this blog entry short.

However I am pleased to announce that after a bit of struggle, I have setup HTTPS on all my sites, including this one. Thanks to Let’s Encrypt and specifically the acme-nginx project to making that possible. Getting everything setup, and automated using Ansible took a bit of work, but in the end it was worth it.

In the future I am looking forward to using the new more secure TLS 1.3 standard once it is supported more widely by NGINX and various browsers.

Avoiding Blank PHP Responses after upgrading to Ubuntu 16.04, and php7.0-fpm

Earlier this week I finally made the plunge to upgrade my VPS to Ubuntu 16.04. With a minor hiccup surrounding supervisord (which I probably can avoid if I go the systemd route) not being enabled at boot, the upgrade was simple for both my WSGI and Node webapps.

I can not say the same thing about my WordPress/PHP installations. (Installations that I hope to transition off to Rookeries once that software becomes more stable.) It took me a few hours to track down and resolve the problems. Hence I am posting this article, to hopefully save someone else’s time when they do the same upgrade.

Upgrading to PHP 7.0

Ubuntu 16.04 makes the switch away from PHP 5 to PHP 7. So I had to switch to php7.0, php7.0-fpm, and php7.0-mysql from their PHP 5 equivalents. The location of the running UNIX socket has changed from /var/run/php5-fpm.sock to /var/run/php/php7.0-fpm.sock, as did the PID files.

Updating the PHP-FPM configuration

Running WordPress using FPM (Fast Process Manager) and NGINX, requires turning off the path translation in php.ini file. This can be done by uncommenting the line cgi.fix_pathinfo=0 found in the configuration file /etc/php/7.0/fpm/php.ini. Again these files have moved from the old location. After you’ve done this remember to restart the FPM service using the new systemd utilities: sudo systemctl restart php7.0-fpm.

Updating the NGINX configuration and Solving the Blank Response

This is the tricky part. After updating my NGINX configurations to the new UNIX socket path, and restarting NGINX, I found that I got blank PHP responses. Everything else worked, expect that any PHP page would not render. And not render by not rendering any content in the body of the responses. That led me down a few rabbit holes, and researching how to re-architecture my setup using Docker. Eventually I stumbled across a blog entry with the solution to the blank PHP response issue.

In a nutshell, with the NGINX upgrade one of the parameters needed for FastCGI went missing namely the fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; bit. Oddly this parameter appears in /etc/nginx/fastcgi.conf and not the /etc/nginx/fastcgi_params file that I normally include in my NGINX configs. Anyways after adding this line and restarting NGINX using sudo systemctl restart nginx everything worked correctly. Below I’ve included a sample NGINX configuration that should work.

Sample NGINX Configuration /etc/nginx/site-enabled/example-site.conf

“`
server {
server_name .example-site.com;
index index.php;
root /srv/www/location_of_wordpress_install;
listen 80;

access_log      /var/logs/nginx/site-access.log;
error_log       /var/logs/nginx/site-error.log info;

location / {
    try_files       $uri $uri/ /index.php$args;
}

location ~ \.php$ {                        
    fastcgi_split_path_info     ^(.+\.php)(/.+)$;
    fastcgi_pass    unix:/var/run/php/php7.0-fpm.sock;
    fastcgi_index   index.php;
    fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
    include         fastcgi_params;
}

location ~* \.(js|css|png|jpg|jpeg|gof|ico)$ {
    expires         max;
    log_not_found   off;
}

}
“`

Selling Off Some Domains

I was going to write about why needing an app isn’t a good way to try get into business. (Hint: It is very expensive, if you can’t code it yourself.) However something else popped up, namely I am trying to sell off two domains: justcheckers.org and justcheckers.net that I own. These were for the justCheckers project, that I’m essentially shutting down. Anyways if you are interested in buying them off me, feel free to contact me.

I will say that the experience so far has been interesting. Thankfully there are some good resources for selling a domain or site. I’ve looked at two companies that handle the auction and transfer of these things Flippa and Sedo. Both are quite legitimate, but there were some bad reviews and some people claiming to have been scammed. I’m trying out Flippa first since it was founded by the fine folks at SitePoint, who I quite like for other reasons. Anyways, I’m hoping that I can find a good home for the domains.

PyCon US 2016 Talk – Pythons in a Container

At the end of May, I presented a talk at PyCon 2016, on using Docker with Python microservices. You can imagine the rush I felt getting to present on such a popular topic at such a large and important conference as PyCon! While it took me a while to recuperate after PyCon and Portland both of which were amazing. I would definitely do another talk at PyCon given the opportunity. Anyways I hope you enjoy watching the video of the talk! Below the video I also wrote about preparing for the talk, its reception, and a bit of the controversy that it stirred up below the fold. 🙂 (And I apologize for the lateness of this post, its been sitting in my backlog waiting to get finished for a few weeks now. 🙁 )

Video

Links

Abstract

Microservices and Docker are all the rage for developing scalable systems. But what challenges will you face when developing and deploying Python apps using Docker to production? This talk goes into the real-life lessons learned from creating, deploying and scaling Dockerized Python applications.

About the talk

Preparation for the Talk

PyCon talks definitely take quite a bit of time and effort to prepare. In my case, the talk took 3 major revisions before becoming the talk that I actually presented at PyCon. What started off as a intro to some of the concepts of Docker with some minor Python points, became more of a lessons learned targetted at intermediate to advanced developers. One of the things I wished I had (and I planned to but didn’t pull of) was to mention and thank my team for helping me preparing my talk. So thank you Kevin Qiu, Biniam Bekele, Yele Bonilla, and Gavin D’Mello for all your support, sitting me through three versions of my talk, and all the amazing feedback! I’ll make sure to include a slide with thanks next time.

Also I am very thankful for Jared Kerim from Mozilla, who presented at the local Python Toronto meetup about his team’s Docker setup. He was kind enough to let me use his example docker-django-template project. His example was also inspirational for my own docker-compose example using my CMS Rookeries. An example that I crafted and tested on the plane trip over to Portland. (After talking with other speakers, finishing up your presentation, notes and examples on the plane trip over is a proud traditional of PyCon and other conferences. :D)

Reception

Overall the reception of the talk was amazing! The talk turned out quite a crowd, in fact filling up most of the room. (I’m not sure of the capacity of the room but I estimate over 300 people attended). I was pretty nervous, but with the exception of a few stumbles, I think I pulled off the talk quite well. I really enjoyed some of the questions that were fielded during the Q&A session, and also privately afterwards. I wish could of answered some of the Docker Machine and Amazon ECS questions better, but I simply have not worked with both technologies long enough to give proper advice.

Controversy

The most surprising aspect of the talk was the controversy it stirred up. At the end of the Q&A you can hear some comments from a young lady about where I supposedly went horrbily wrong, and how there were tweets flying back and forth about it. I had turned off the notifications on my phone when I got up on stage, to avoid getting distracted. She persisted with telling (or trying to explain) what was wrong in the private gathering afterwards. Unfortunately she did not do a wonderful job of communicating, and I felt it took away time from others to ask their questions. It didn’t help her case that she admitted to being a novice at Docker. Please don’t that as an attendee, there are better ways to disagree and communicate that.

I later approached by a gentleman (thank you whoever you are), who mentioned I should go talk to the OpenShift guys since they had some concerns about my talk. News of the Twitter controversy worried me, because I hated the notion that I had gotten on stage and toled people to go and do the wrong thing. Especially when apparently I’m telling the opposite of what Glyph from Twisted said to do. After a brief chat (and a nice demo about their cool Kubernetes suite) from the OpenShift guys, I found out that Graham Dumpleton, the creator of mod_wsgi and who works on OpenShift had done a live tweeting commentary during my talk, where he disagreed with a few of my points. Long story short, eventually I was able to chat with Graham. He was a great sport and explained his points. Interestingly enough I had also talked with the folks at Docker. And they agreed with the points in my talk, and the logic behind my points. Essentially most of my points were based off the best practises they proposed.

Anyways I listed a few of Graham’s points with links to his blog posts (thanks again Graham!), and some of my quick thoughts on each one. A quick disclaimer about some of my points: the advice I gave worked for us in our datacentre, and that it might not work for others in other environments. It should work well, it might not be perfect, but it worked for us, and some of the folks at Mozilla. I gave a disclaimer at my other talk on a Ansible setup for WSGI apps at PyCon Canada, and I thought it was superfluous. But it turns out it is a useful thing to mention, and be explicit.

Errata

So the slide that caused a good portion of the controversy was the base image one. There I had provided an example Dockerfile on half the slide and discussed about base images and good Dockerfile practises, with points on the lower half. Now the example was meant as a toy and not necessarily complete. It is difficult, even impossible to present a well formated, perfect Dockerfile in that context. There is only so much room on a slide to fit both an illustrative example and some explanatory points. That is why I included links to some samples, that hopefuly did a better job of it.

Virtualenvs

Ah yes, the “enfant terrible” of my talk. 🙂 If you want to be controversial in your talk, mentioning something like this will get people’s attention. (Ironically, it was not my desire to stir up a controversy). Graham post a while back why you might want to use virtualenvs in your Dockerized app. It is a longish post, so I’ll give a shortened version. Basically when you base your image off some distro (say Ubuntu, Fedora or what not), there is a good chance of bringing in more Python packages in your system site packages than you expected. e.g. You’re building a Flask app, and the package maintainer included a version of Werkzeug in the base Python install, so now when you pip install Flask as part of your requirements you get the wrong version of Werkzeug.

And that is a valid point (with my example)… except if you use something like the official Python 2.7 base image… which installs just Python. I would argue that you would catch and resolve this issue, if you are auditing your Docker images. (And you should be always doing your due diligence and checking your base and resulting images. ) So yes… you don’t really need virtualenvs, but you can also use them if you are concerned that you might be getting conflicting packages.

Volume maps

Graham was right about the adding volume mapping in the Dockerfile being problematic. You should not define volume mounts in your Dockerfile, since they create extra files with sudo-like permissions on the host (see /var). In your own datacentre that isn’t a problem. A multi-tenant cloud provider like OpenShift, would disallow you to create those files. The documentation argument I provided is not all that useful, since you can document the mountpoints in the README that you would provide with the Docker image.

Base Images

Base images are hard to get right. And there is a lot of debate whether or not to use tooling instead of base images. Graham says his warpdrive tool will do that sort of a thing. At work we build out our own tooling for building “standard” service Dockerfiles, and that just add another level of abstraction. I prefer base images since it while not ideal, provides less levels of abstractions that can get in the way when you’re debugging your Dockerfile setup. But your mileage may vary here.

So yes, good base images are hard. Try not to build your own unless you find it really useful and you have a great base to work from.

Installing GCC/Build Tools

In an ideal world one ought not have to include GCC, Python dev headers and so on. Yes, one can pip install using wheels, but that doesn’t always work out.

Dockerfiles

Formatting of the RUN command. This is not one of Graham’s points, but it did come up. Yes, you should format the RUN commands, with a line for each command and using a \ line continuation for readability. My slide didn’t have enough physical space to do so. My Rookeries example does a better job of this.

Running as Root

Graham is right, you should not run containerized apps as root. That is a bad security practise that can lead to an attacker compromising your Docker host via a privileged account on your Docker container. Again a bad example on my part, I should of added a USER command and dropped the VOLUME line, or maybe rethought the use of an example.

UWSGI and the HTTP flag

No, you don’t need it and you should use the UWSGI protocol if you put an NGINX container before your WSGI container. I left the flag in to make sure the example Dockerfile was runnable. My bad on trying to get a good illustrative example, but it wouldn’t be a good idea in production unless you feel comfortable exposing UWSGI to the direct HTTP traffic.

Personally I’m not a fan of mod_wsgi + Apache, but Graham did point out he created mod_wsgi-express to simplify your life. If we continue to use Apache + mod_wsgi at work, then I’ll try to get us to use mod_wsgi-express too.

Final Thoughts

Anyways, I hope got everything right. Thank you for reading all the way to the end! 🙂

See You at PyCon US 2016!

If you’re wondering why I’ve been so quiet these past few weeks, it is because I’ve been busy preparing to go to PyCon US in Portland this year!

I am very excited not only to be attending, but I will be giving a talk at PyCon US this year! I will be talking about Dockerizing Python microservices, and some of the lessons we’ve learned along the way at work. My talk will be on the first day (Monday May 30th) at 3:15-3:45 PM (PST). Videos of the all PyCon talks should be available a few days after the talk.

Huge thanks to everyone at my workplace, Points, for making this possible for me!

Finally I will be around in Portland for a few days after the sprints as well. I have never been to Portland, so I want to check out some of the sights around there. Let me know via Twitter or email if you want to meetup with me while I’m there. 🙂