Author Archive: Jonathan Brinley

Dev with Docker

I’ve been using Docker to run my local development environments for nearly two years now. In that time, it has gone from experimental and arcane, to almost stable and user-friendly.

Docker logoI work on a MacBook Pro, in OS X. After a brief dive into the details of what Docker is and how it works, you learn that you can’t run the Docker engine in OS X. Containers require process isolation and resource management features of the Linux kernel, so you can only run the Docker engine in Linux.

There are a number of workarounds for this, all of which involve using a virtual machine. Initially, I used boot2docker, which loaded a small VM using VirtualBox. Eventually, this was subsumed into Docker Machine and the Docker Toolbox, which used the same VM in VirtualBox but will slightly improved tools. Now I’m using Docker for Mac, which still uses a boot2docker-based virtual machine, but it runs on the hypervisor framework built into OS X, obviating the requirement for a separate hypervisor like VirtualBox.

With the notable exception of filesystem read performance, Docker for Mac has removed many of the more tedious aspects of running a local Docker environment, and had made development much easier.

This is the first in an anticipated series of posts documenting how I have my local development environment configured, focusing on using Docker for Mac for WordPress development.

How to Homeschool My Children

As we prepare for Titus to enter first grade, a number of colleagues have asked for details about our homeschooling techniques, philosophy, curriculum, etc. Forthwith:


We attended the FPEA convention in May. In addition to having a chance to review materials from a smorgasbord of vendors, we also learned a lot about education philosophies from several of the presentation and workshops. There are five prevailing philosophies (or teaching styles, or learning methods, or whatever you want to call them), and I’m sure each of them has its place in different families. Our experience at the convention was one of discovery. We didn’t so much choose a philosophy; we identified the philosophy we already had. Names are powerful. By identifying the Charlotte Mason method as that which most aligned with our preferred approach, it’s much easier to find resources we think will be helpful additions to our curriculum.

So what is that approach? It’s largely structured around experiencing the world and responding to it. If you’re studying science, observe nature, do experiments. Don’t just read a book that tells you how things work; figure out why they work that way. If you’re studying the arts, seek out the masters. Live with their beauty in your house; learn why it’s beautiful. If you’re studying grammar, learn through great literature.


We started formal education at age three. At the start, the idea is to introduce concepts that we can build on in the future, and start to introduce some structure and discipline in their learning. School takes maybe 15 minutes a day at the beginning, and gradually expands to a couple of hours each day now that we’re starting first grade.

tirzah-mathWe have a designated table where we always do our lessons. Both kids will come sit down; and we’ll either alternate between them, or, wherever possible, engage them both in the same subject (this is easier for some subjects than others).

Our school year formally starts each September. We don’t take an explicit summer vacation, instead opting to take numerous breaks throughout the year (usually timed to avoid crowds that follow the public school schedule).

Beyond the formal curriculum outlined below, we’re also fortunate to live a few blocks away from O2B Kids, where the kids can do many of their “extracurriculars”. Dance, gym, art, and more; they get the opportunity to have fun with other kids and learn skills we would never be able to teach them at home.



Action BibleIt’s never too soon to start studying scripture. We started on day one at Genesis 1, and have read a chapter together every evening before bed. After a few years we reached the end, at which point we circled back to the beginning (now with two kids listening). As part of our routine, everybody gets a notebook and pencils to write down their thoughts or draw picture about the day’s chapter.

Language Arts

  • Wordy Worm – Phonograms are the smallest distinct sounds in our language. Wordy Worm teaches reading and spelling by focusing on these sounds first, and then on the letters (or combinations of letters) that can be used to create those sounds. We start by focusing on a few related phonograms each week, learning songs to help us remember them, and finding books from the library where the kids can use their new knowledge to actually start to read a few words.
  • Explode the Code – This is a more traditional approach to teaching reading and spelling through phonics.Explode the Code Each chapter covers a different sound, so one chapter will be “short a” and the next chapter is “short e”. Most chapters are about 9 pages long and reinforce the learning using several different methods. The child will copy the word, circle the picture illustrating the word, find the matching words in a list, and more. It also introduces basic literacy by having them unjumble words so they make a sentence, reading two sentences and selecting which one describes the picture, and answering yes-no questions. We have encountered a few “problems” that are inconsequential as homeschoolers. The first is that Titus’s handwriting competency was nowhere near his reading skill, making it difficult to fill out so many pages. We compromised and on one type of page he had to circle the letters, but not rewrite them. On the other type, he spelled while we wrote down the letters. The other “problem” was with the jumbled sentence. He had a great difficulty figuring out the correct order. One day, on a whim we tried putting all the words on little squares of paper and he had no trouble putting them in the correct order. So for nearly a year, he would arrange the words and glue them to the page. Now that his skills are improved, he is just writing the words as “expected”.
  • Handwriting Without Tears – This is an excellent series that teaches handwriting skills starting with pre-writing skills and advancing through cursive. In the early years, it focuses a lot on the basics of starting the letters at the top, writing on a line, and word spacing. The curriculum teaches that in the early stages, a child should copy a printed letter every time so they are always looking at a quality examples and will produce quality letters. On the other hand, if a child is required to write a row of the letter “B”, the first few “Bs” will look okay, but as they stop looking at the original “B” and start looking at their own handwriting, the letters will get worse and worse until at the end they are nearly illegible. They also slowly incorporate other aspects of grammar and composition throughout the series. We found ourselves wanting to create our own practice worksheets on occasion, so we purchased a font to match the workbooks from Educational Fontware.
  • Keyboarding Without Tears – From the makers of Handwriting without Tears, a new typing curriculum. We’ll be starting the curriculum next month, with daily 5-minute typing lessons.


  • Fred GaussLife of Fred – I can’t praise this math curriculum enough. You learn math while reading a story of the life of five-year-old Fred Gauss. The stories are silly and entertaining, and Titus will often ask to do another chapter. We started the series when he turned four. Two years in, and Titus can draw a bar graph, solve for x in 3x=12, find the union of sets, and tell you if three lines are concurrent. After we finish the intermediate series (2nd grade), Titus will likely take a break for a while and become the teacher’s assistant as we teach the books to Tirzah.
    • Year 1 (Pre-K): Apples, Butterflies, Cats
    • Year 2 (Kindergarten): Dogs, Edgewood, Farming
    • Year 3 (1st Grade): Goldfish, Honey, Ice Cream, Jelly Beans
    • Year 4 (2nd Grade): Kidneys, Liver, Mineshaft

    The curriculum goes all the way through high school and college math courses (trigonometry, calculus, statistics), so we have many years of Fred ahead of us.

  • Math-U-See – This math curriculum is structured around visual and tactile learning with colorful plastic blocks. These are great starting around age three, when you can use them to practice counting and start teaching place value. When we started the Primer at age four, I thought that Math-U-See would be our primary math curriculum, and Fred would be helpful to reinforce the concepts we were learning. I had it exactly backwards. The manipulative blocks are excellent tools for helping visualize math concepts, but the workbooks and tests mostly serve to reinforce the concepts we’re learning in Fred. The drill is still helpful, and we usually have Titus do at least a few drill pages from each chapter. But going into first grade, I’m going to focus more effort on finding pages that specifically reinforce the concepts we’re learning in Fred, instead of going through the book linearly.


Before first grade, science is mostly unstructured. Kids are naturally curious about the world, and it’s easy to guide that curiosity into experimentation and introduce the scientific method. In 2012, a couple of early tropical storms left us with an abundance of standing water, yielding a bumper crop of tree frogs. From the thousands hopping around our front yard, we adopted a handful, raising and feeding them for the next year (we learned a lot more about fruit flies than frogs). We also participated in science fairs with homeschool groups to get some formal practice with the scientific method and with public presentations. You can find books of ready-made experiments, but it’s far more interesting to come up with your own and actually learn something.

Basher BooksBeyond experimentation, good books can go a long way to open up the vast world that science covers. The Basher Science series contains a variety of books that introduce topics in bite-sized, anthropomorphized chunks perfect for preschool children. You’ll also find a number of books on any topic imaginable at your library.

With first grade, we’re starting a formal science curriculum. One of my biggest frustrations with most science curricula I’ve looked at is the lack of any science. They’ll teach you facts about the world (or some biased view of them); but that’s memorization, not science. I want to teach the method; they’ll learn plenty of facts on their own. I was delighted to discover the Real Science 4 Kids curriculum at the FPEA convention. It covers chemistry, biology, physics, astronomy, and geology, starting all of them in first grade. Every chapter is built around experimentation, so you’re not just reading and memorizing.

Computer Programming

We’re still not sure exactly how to go about teaching programming. At the moment, we’re really excited to see all the resources coming to, including their upcoming K-5 curriculum.


Castillo de San MarcosTeaching history to preschoolers is, to a large extent, an exercise in futility. They don’t really have a concept of time on any scale larger that “last week”. But this is a good age to go and explore that history in person. We’re blessed to live an hour away from the oldest city in the United States. We’ve made a number of visits to Castillo de San Marcos and toured the many museums in the area, learning about life in the area over the last half millennium.

We’re now about to start the Story of the World. It’s a four-year world history curriculum that presents the events of history intermingled with short stories to help children visualize and remember those events. It also comes with an outstanding teacher’s guide/activity book, full of related projects, recommendations for more books, and generally helpful resources.

Book of CenturiesHistory, of course, intermingles will all our other subjects. A wonderful tool we’ve learned about is the Book of Centuries. It’s a simple book that is empty other than dates in the margins, with a spread for each century. Over time, your book begins to show the relationships among the people, places, and events as you mark them in your book. We couldn’t find one we liked, so Stephanie put together her own Book of Centuries through Lulu.

Music and Art Appreciation

Stephanie is an artist. I’m a classically-trained musician. As much as we want to (and do) encourage our children to learn those same skills, it’s far more important for them to learn to appreciate and understand the beauty and history of the cultural heritage available to us.

The first step is to surround them with that beauty. There is almost always music playing in our house (usually Classical South Florida or a curated Pandora station). We have paintings on our walls. We take every opportunity we can to attend concerts. This year we’ll also start explicitly including music and art studies into our school curriculum.

Each month, we’ll pick a different composer. We’ll learn a little bit about their lives and times, but then focus on listening to their music. We’ll have a composition of the week that we will listen to every day as part of our bedtime routine, and finish up the week talking about what we heard. We get a chance to internalize each composer’s style, and find their place in the Book of Centuries to gain an understanding of the evolution of music over time.

We’ll follow a similar process with artists. Study one artist for an extended period, looking at a new piece of art each week. Then we talk about what we saw, learning to appreciate it, but also to analyze and criticize. Then we have an opportunity to create our own art in a similar style.


The government thinks it can do a better job raising my kids than I can, and likely has different goals for their education. There are plenty of undiplomatic things I could (but won’t) say here. Instead, a few anecdotes:

  • I attended public schools for nineteen years, from kindergarten through a master’s degree. I took a lot of history classes. I never finished a history book. U.S. history classes rarely made it past the Civil War (including the ones labeled “1865-Present”). When we did make it into the 20th century, it was usually part of a rushed overview of the 20th century on the last day of class.
  • When I finished kindergarten, my school tried to make me repeat it for another year. My crime: I couldn’t skip. Read that again: I couldn’t skip. You know, hopping on alternate feet. Sure, I was reading at a 2nd-grade level already (as the rest of my class was learning the names of the letters). I had outstanding marks in every subject. But I couldn’t skip. Clearly that’s the most important thing you need to succeed in public schools: physical agility.
  • Stephanie was recently speaking to another mother. The latter had a son in Kindergarten. He had one or two hours of homework every night. This is on top of the four hours he spent in the classroom every day. If you scroll up, you can re-read where I wrote, “School takes maybe 15 minutes a day at the beginning, and gradually expands to a couple of hours each day now that we’re starting first grade.” She was already homeschooling her son, but to meet somebody else’s goals, somebody else’s curriculum, somebody else’s schedule.

Sometimes the government can be forceful in asserting its supposed claim on your children. To keep matters simple, we follow a few steps:

  • Move to a location where the laws are conducive to homeschooling. Florida requires an annual standardized test or portfolio review, but otherwise is fairly unoppressive. Our county, in particular, is quite welcoming.
  • Avoid interacting with the government. Its goals are not your goals. If you go to the government for advice, it will give the wrong advice, and it will often come with legal entanglements.
  • Know the law, know your rights, and always follow the letter of the law.
  • Join the HSLDA. They do important work fighting the legal battles to keep you free.

MultiplicationObviously, homeschooling is a large investment in time (but possibly not as much as you might expect). It comes with so many benefits, though, that it’s well worth the cost. We start with giving our children the highest quality education possible. As freelance workers ourselves, homeschooling is a perfect lifestyle fit, giving our kids the same flexibility we have to work when and where we choose. Add to that the opportunity to spend quality time with them, helping them discover the world and discover themselves while we nurture our relationship with them. It keeps us busy, but who isn’t busy? We’re doing exactly what we want to be doing, and we’re loving it.

Remove DEFINER clauses from MySQL dumps

If you have triggers or views in a MySQL database, a dump of that database will have clauses like:

/*!50017 DEFINER=`root`@`localhost` */

To import this dump into a new MySQL server (e.g., going from a production environment to local development), you’ll run into problems if you don’t have the same users defined on both systems.

As far as I can tell, there’s not an easy way to exclude these clauses from the dump, but with just a bit of post-processing, your SQL file can become portable. You can replace the user in the DEFINER clause with CURRENT_USER and it will use the current user when you import the SQL.

$ mysqldump > non_portable_dump.sql
$ sed -E 's/DEFINER=`[^`]+`@`[^`]+`/DEFINER=CURRENT_USER/g' non_portable_dump.sql > portable_dump.sql

Note: Depending on your version of sed, you might need to use the flag -r (for GNU sed) instead of -E (for BSD sed).

Add File Name to WordPress Media Browser

If you have a lot of images in your WordPress media library, especially if those images are visually similar, it can be somewhat awkward finding the correct file using the new media UI. You just have images, with no text to help identify them without clicking on each one.


I wanted to add an overlay to each image so that I could see the filename, allowing easier skimming of the media library. The template for the HTML here comes from the function wp_print_media_templates(). It doesn’t really have any hooks for filtering the HTML, but we can wrap it in an output buffer and tweak it before rendering the template.

// hook in at the beginning of the footer to see if we need to add our wrapper
add_action( 'in_admin_footer', 'my_wrap_media_template_callback', 10, 0 );
// if the media templates are going to be rendered on this page, remove
// the default hook and put our wrapper in its place
function my_wrap_media_template_callback()  {
	if ( has_action( 'admin_footer', 'wp_print_media_templates' ) ) {
		remove_action( 'admin_footer', 'wp_print_media_templates' );
		add_action( 'admin_footer', 'my_wp_print_media_templates_wrapper' );
// get the default templates, but add our HTML in the correct location
function wp_print_media_templates_wrapper() {
	$output = ob_get_clean();
	// make sure to keep all of the whitespace here
	$to_find = '<div class="thumbnail">
					<div class="centered">
						<img src="{{ data.size.url }}" draggable="false" />
	// this is the HTML that will render our filename
	$to_add = '
				<div class="filename">
					<div>{{ data.filename }}</div>
	$output = str_replace( $to_find, $to_find.$to_add, $output );
	echo $output;

A fairly simple wrapper. We’re just adding a <div> in the right spot, and WordPress handles the work of formatting it and populating the correct values.


Integrate fail2ban with CloudFlare

Following my previous post about using fail2ban to stop malicious requests to xmlrpc.php, I set up a CloudFlare account. In doing so, I ran into two issues:

First, my access logs were only showing CloudFlare’s IP address, not those of the users making the requests. That’s due to how CloudFlare proxies every request. Fortunately, CloudFlare provides an Apache module to translate the IP addresses for your logs.

Second, even with the correct IP address in the logs, fail2ban was no longer effective in stopping requests (since it handled the requests before the Apache module translated the IP addresses). I needed to stop the requests at CloudFlare, before they ever made it to my server. Fortunately, it’s simple to set up a fail2ban action that utilizes the CloudFlare API to block those requests. Create an action including:

actionban = curl -s "<ip>&u=<account>&tkn=<token>"
actionunban = curl -s "<ip>&u=<account>&tkn=<token>"

And set your filter(s) to use that action.