Working with Mailgun Bounce Lists


Manipulate Mailgun Bounce Lists: Show, Add, and Delete Email Addresses. All from the terminal.

I recently came across a situation where a client reached their disk usage limit. As a result, they were unable to receive emails. This went un-noticed for a couple days (I didn’t manage the server at the time, I do now).

This client has a couple different WordPress sites with several employees receiving various notification emails. All their sites use Mailgun and the Mailgun WordPress plugin for sending emails. During the time they were unable to receive email, a few employee email addresses got placed on a Mailgun bounce list with a status of 550 Administrative prohibition.

For some background, here’s how Mailgun describes a bounce, as found in the Mailgun documentation:

Bounce list stores events of delivery failures due to permanent recipient mailbox errors such as non-existent mailbox. Soft bounces (for example, mailbox is full) and other failures (for example, ESP rejects an email because it thinks it is spam) are not added to the list.

Subsequent delivery attempts to an address found in a bounce list are prevented to protect your sending reputation.

I first noticed the bounce issue in the logs, like in the image below. After not being able to find a way to manage email addresses on the bounce list from the browser, I hit up Google and was pleased to find that you can interact with Mailgun bounce lists via their API.

Show Email Addresses in the Mailgun Bounce List

To list email addresses on the bounce list, do something like this on the terminal/command line, replacing key-xxx-xxx with your actual Mailgun API key:

json-prettifierYou can find your Mailgun API key on the Mailgun dashboard, under API Keys. The Mailgun API will return JSON, which is a bit difficult to read in the terminal. I usually copy the output and paste it into this JSON formatter, which makes the data much easier to read, as you can see in the screenshot above.

Even when the formatted JSON in it’s raw form is easier to read. See, here’s the returned JSON, in it’s original form:

Now here’s the pretty, formatted JSON as raw text:

Much easier to read, right? Those of you using REST clients like Postman will have your results automatically prettified, removing the need using a site like the JSON formatter I typically use.

Delete an Email Address from the Mailgun Bounce List

If you’ve found an email address you’d like to remove from the Mailgun bounce list, or already know the email you want to remove, do this from a terminal and replace [email protected] with the real email address to delete. And of course, replace key-xxx-xxx with your actual Mailgun API key:

Add an Email Address to the Mailgun Bounce List

Sometimes you may wish to manually add an email address to the Mailgun bounce list. This can be done very easily with the CURL command below. It will add [email protected] to the Mailgun bounce list, so make sure to change that to the email you really want to add to the list.

What Else?

Not much concerning Mailgun bounce lists specifically. It’s possible to add multiple addresses to a bounce list at once, but that gets a little more difficult from the terminal as it requires sending JSON to the Mailgun API. Using a client like Postman would be a better option if you intend on sending much data.

The Mailgun API can be used to do all sorts of stuff, like pull stats and to create new domains. It’s a powerful API and one of my favorites to work with.

How do you prefer to send emails from your websites?

View Results

Loading ... Loading ...

Use Docker for Fast WordPress Development Environments


A Dockerfile That Provides Quick WordPress Development Environments

Back in May of this year I started playing around with Docker quite a bit. Took me a bit to wrap my brain around everything Docker can do, wish I had read this article from Adam Ierymenko before starting.

Anyway, Docker describes itself as such:

Docker is an open platform for building, shipping and running distributed applications. It gives programmers, development teams and operations engineers the common toolbox they need to take advantage of the distributed and networked nature of modern applications.

I’m not using Docker to it’s fullest extent, not even close. I mostly use it for setting up quick WordPress development environments for building client sites or just to do some testing.

I came across an outdated Dockerfile that had exactly what I needed but lacked the ability to SSH to the Docker container. I forked it on GitHub and added some modifications (like SSH).

It’s on the Docker Hub Registry, making it super easy to use. There’s a few items on the to-do list, but the one I want to take care of first is adding support for Docker Compose, which will make installation even easier.

To get started with this Docker image, you just need to have Docker installed and then run the following command:

Once you’ve got the Docker image pulled, fire up a new container like with the command below. It will create a new Docker container named project-name.

Give it a bit to get everything setup then navigate to in your browser to access your new WordPress install.

For more information I suggest checking out the readme. Every time that I push commits to GitHub, a new build of the Docker image will automatically be built as I’ve got it setup as an automated build repository at the Docker Hub Registry. Pretty nifty.

So, I’m relatively new to Docker, if you’re a pro and see something I should be doing differently, please let me know. Any advice on setting up Docker Compose for this project would be great, too (if I’m not mistaken, it just involved linking multiple containers together).

Do you use Docker?

View Results

Loading ... Loading ... PGP For Beginners, With Invites


PGP for Beginners: A Simple Web Interface to PGP is quite simple, basically a web interface and command line client that makes PGP more user-friendly. At the same time, it makes it easy to get someones public key, and know it’s the correct key. allows you to encrypt, decrypt, sign, and verify messages to other users. The homepage has an excellent description on the inner workings and how to make use of the command line client.

You can find me on at

I like how the purpose of the website, as opposed to the command line client, is described: is also a Keybase client, however certain crypto actions (signing and decrypting) are limited to users who store client-encrypted copies of their private keys on the server, an optional feature we didn’t mention above.

On the website, all crypto is performed in JavaScript, in your browser. Some people have strong feelings about this, for good reason. has it’s issues, though. Liz Denys makes very good points in her Refusing To Verify Myself post.

And back in March 2014, Evan Johnson discovered very serious vulnerability in You can read more about it, along with examples and why it was so major, in his blog post.

There’s still serious debate that’s somewhat related to Evan’s discovery. An issue on GitHub is still open while the folks consider their options and best course of action.

Everything has it’s flaws, though. So for me, is an easy way for me to communicate securely with those I need to do so with. I’ll likely continue using it, but need more people I communicate with frequently to be members.


I do have invites for I’ll only send them to people I know. If you’re a regular here, a client of mine, or old online friend, you qualify. Real world friends and family obviously qualify.

Just ask in the comments below.

SSH Private Key Authentication Tip


So easy to miss, but so important for SSH Private Key Authentication

I don’t allow password logins on any of my servers. Can only login via SSH key based authentication. No root login is allowed, and I specify every user that’s allowed to login via SSH, ie: me.

If you’re a regular here, you know I love DigitalOcean. They have a very nice tutorial on setting up SSH private key login, even walking you through creating SSH keys if you don’t already have one, and even adding that key to your DigitalOcean account.

None of that will be of interest to you if you already know how to generate SSH keys.

I’ll SSH into my new Droplet, only to be rejected. I immediately know why, because it’s happened so many times. It’s due to incorrect permissions on your Droplet, VPS, server, whatever.

For SSH private key authentication to work, the ~/.ssh/authorized_keys file and the ~/.ssh folder need specific permissions:

Run that, and then try logging in via SSH to your Droplet from your local machine. Should go this time.

If you still can’t login to your remote system, something else is likely wrong. If that’s the case, you’ll want to start at the top of the DigitalOcean post about setting up SSH private key authentication and just follow the steps.

After you’ve followed those steps, change permissions on the ~/.ssh/authorized_keys file again and on the ~/.ssh folder again. Like so from your terminal:

I’m curious…

Do you allow password logins over SSH?

View Results

Loading ... Loading ...

If you do allow password logins, I’d love to hear what scenario causes you to need to allow password logins. Let me know in the comments if you don’t mind.

Quickly Deploy LAMP Stacks with ServerPilot


Easily Deploy LAMP Stacks, and it’s free

I have yet to use ServerPilot, but will be setting up a new VPS at DigitalOcean in the coming weeks for a new venture. ServerPilot makes getting a LAMP stack setup very quickly.

ServerPilot will automatically install Nginx, Apache, PHP, and MySQL on a new, freshly installed/created, 64-bit Ubuntu 12.04 or Ubuntu 14.04. So if you’re using DigitalOcean, create your Droplet, and SSH to it. You should be able to harden SSH up a little, but make sure you don’t install any new packages yet.

Getting Started

Getting started with ServerPilot is crazy easy. All you need to be able to do is SSH into your server and run a command. I highly doubt anyone reading this doesn’t know how to do this. If you don’t, Google will tell you how.

1. Sign Up

Sign up for a free account with ServerPilot.

2. Connect A Server

“Connect” a new server. Just enter your servers hostname and click the “Continue With Setup” button. Screenshot below.

3. Run The Install

Connect to your server via SSH. Remember, it must be a new server, preferably with no additional packages installed yet. To install Nginx, Apache, PHP, and MySQL, run the command below, from this gist:

The --server-id and --server-apikey values will be provided for you, they’re blacked out in the screenshot below.

Additional Information

On GitHub

ServerPilot also has a GitHub account with two repositories currently. One is ServerPilot/Vagrantfile and the other is ServerPilot/API.


This repository provides a sample Vagrant configuration for testing ServerPilot. Basically a server that you can use to test ServerPilot before using it on a new, paid VPS. The README is very detailed, definitely read it if you need help using Vagrant. There’s even an example on using composer to create a Laravel app.


From the README, The ServerPilot API is RESTful and allows you to manage ServerPilot resources using HTTP requests. All responses return JSON objects, including errors. As seems typical from ServerPilot, the documentation in the README is excellent.

The API will let you do things like list servers, connect new servers, or list all system users, among many others. An example that would list all servers can be seen in the gist below.

That request would return JSON similar to this:

Do you use Vagrant?

View Results

Loading ... Loading ...

Paid Accounts

You get a pretty cool monitoring dashboard for $10/month. I found the screenshot below in a post from Jake Peterson, it appears to be the ServerPilot monitoring dashboard.
There’s the free plan, obviously, and then two paid plans. One is $10/month and the other is $49/month. You can see what you get for your money on their pricing page.


If you’re a PHP developer and use a VPS provider like DigitalOcean or Linode, ServerPilot is probably worth checking out. Even if you don’t end up using, it’s pretty neat that something like this even exists.

I only have one feature I’d really like to see, the ability to select certain packages to be installed. If that were included in the $10/month plan, I’d definitely do it. As it stands currently, though, it’s definitely a time saver and very well executed.