Add a path to the global $PATH with Ansible

When building certain roles or playbooks, I often need to add a new directory to the global system-wide $PATH so automation tools, users, or scripts will be able to find other scripts or binaries they need to run. Just today I did this yet again for my geerlingguy.ruby Ansible role, and I thought I should document how I do it here—mostly so I have an easy searchable reference for it the next time I have to do this and want a copy-paste example!

    - name: Add another bin dir to system-wide $PATH.
        dest: /etc/profile.d/
        content: 'PATH=$PATH:{{ my_custom_path_var }}'

In this case, my_custom_path_var would refer to the path you want added to the system-wide $PATH. Now, on next login, you should see your custom path when you echo $PATH!

Ansible playbook to upgrade all Ubuntu 12.04 LTS hosts to 14.04 (or 16.04)

Generally speaking, I'm against performing major OS upgrades on my Linux servers; there are often little things that get broken, or configurations gone awry, when you attempt an upgrade... and part of the point of automation (or striving towards a 12-factor app) is that you don't 'upgrade'—you destroy and rebuild with a newer version.

But, there are still cases where you have legacy servers running one little task that you haven't yet automated entirely, or that have data on them that is not yet stored in a way where you can tear down the server and build a new replacement. In these cases, assuming you've already done a canary upgrade on a similar but disposable server (to make sure there are no major gotchas), it may be the lesser of two evils to use something like Ubuntu's do-release-upgrade.

Using Ubuntu Bash in Windows Creators' Update with Vagrant

When Microsoft announced the Windows Subsystem for Linux, now seemingly rebranded as Bash on ubuntu on Windows, I was excited at the possibility of having Drupal VM (and other similarly command-line-friendly open source projects) work better in a Windows environment. But unfortunately, the Anniversary update's version of WSL/Ubuntu Bash was half-baked, and there were a lot of little issues trying to get anything cohesive done between the Windows and Ubuntu Bash environments (even with cbwin).

Then, a year or so later, Microsoft finally announced that tons of improvements (including upgrading Ubuntu in the WSL from 14.04 to 16.04!) would be included in the 'Creators Update' to Windows 10, dropping tomorrow, April 11.

Using Ansible through Windows 10's Subsystem for Linux

Ever since I heard about the new 'Beta' Windows Subsystem for Linux, which basically installs an Ubuntu LTS release inside of Windows 10 (currently 14.04), I've been meaning to give it a spin, and see if it can be a worthy replacement for Cygwin, Git shell, Cmder, etc. And what I was most interested in was whether I could finally point people to a more stable and friendly way of using Ansible on a Windows workstation.

In the past, there was the option of running Ansible inside Cygwin (and this is still the best way to try getting Ansible working in an older Windows environment), but this always felt kludgy to me, and I hated having to recommend either that or forcing Windows users to do a full Linux VM installation just to run Ansible commands. I finally updated my PC laptop to the latest Windows 10 Anniversary Update, and installed the Windows Subsystem for Linux, and lo and behold, Ansible works!

Orange Pi Plus Setup, Benchmarks, and Initial Impressions

tl;dr: The Orange Pi Plus offers much better specs, and much better performance, than a similarly-priced Raspberry Pi. Unfortunately—and this is the case with most RPi competitors at this time—setup, hardware support, and the smaller repository of documentation and community knowledge narrow this board's appeal to enthusiasts willing to debug annoying setup and configuration issues on their own.

Orange Pi Plus - Front

Orange Pi Plus - Back

A few months ago, I bought an Orange Pi Plus from AliExpress. It's a single-board Linux computer very similar to the Raspberry Pi, with a few key differences:

Format the built-in eMMC storage on an Orange Pi Plus

To use the built-in 8GB of eMMC storage on the Orange Pi Plus as a writable volume in Linux, you need to delete the existing partitions (I think mine were formatted as FAT/WIN32), create a new partition, format the partition, then mount it:

  1. Delete the existing partitions:
    1. sudo fdisk /dev/mmcblk1
    2. p to list all partitions, then d and a number to delete all existing partitions, then w to write the changes.
  2. Create a new partition:
    1. sudo fdisk /dev/mmcblk1
    2. n to create a new partition, then use all the defaults, then w to write the changes.
  3. Format the partition: sudo mkfs.ext4 -L "emmc" /dev/mmcblk1p1
  4. Create a mount point: sudo mkdir /emmc
  5. Mount the disk: mount /dev/mmcblk1p1 /emmc

Viewing email in Linux using postfix's mailq and postcat

When I'm developing using the Drupal Development VM, or checking into email processing on any of my servers, I usually use postfix to handle mail sending. Postfix is simple, preinstalled on most Linux distributions (and easy to set up if not), and is easy enough to use.

Here are the most common commands I use when either developing or troubleshooting email in production:

  • mailq - print a list of all queued mail
  • postcat -vq [message-id] - print a particular message, by ID (you can see the ID along in mailq's output)
  • postqueue -f - process the queued mail immediately
  • postsuper -d ALL - delete ALL queued mail (use with caution—but handy if you have a mail send going awry!)

There are many other helpful commands and scripts to help deal with mail (e.g. deleting all messages to a certain domain, or deleting specific message IDs easily), but these are the main ones I use during day-to-day development and troubleshooting.

Route local emails to another email address using Postfix on Linux

When I set up new servers, I like to make sure any system messages like cron failures, server issues, or emails that are routed to (where '' is the hostname of the server—meaning emails to that domain will get routed through the server itself and not hit an external MX server unless postfix/sendmail is configured correctly) are sent to my own email address.

It's relatively straightforward to route emails to internal users (like webmaster, root, etc.) to an external email address; you simply need to edit the /etc/aliases file, adding a rule like the one below, then run the command sudo newaliases:

webmaster: root

# Person who should get root's mail

By default, most internal users are routed to root as well (including webmaster), so setting an external email address (or a list of addresses, separated by comma) for the root account will allow you to more easily see what's happening on your server. Don't forget to run sudo newaliases to pick up the changes!

Diagnosing Disk I/O issues: swapping, high IO wait, congestion

One one small LEMP VPS I manage, I noticed munin graphs that showed anywhere between 5-50 MB/second of disk IO. Since the VM has an SSD instead of traditional spinning hard drive, performance wasn't too bad, but all that disk I/O definitely slowed things down.

I wanted to figure out what was the source of all the disk I/O, so I used the following techniques to narrow down the culprit (spoilers: it was MySQL, which was using some swap space because it was tuned to use a little too much memory).


First up was iotop, a handy top-like utility for monitoring disk IO in real-time. Install it via yum or apt, then run it with the command sudo iotop -ao to see an aggregated summary of disk IO over the course of the utility's run. I let it sit for a few minutes, then checked back in to find:

A brief history of SSH and remote access

This post is an excerpt from Chapter 11: Server Security and Ansible, in Ansible for DevOps.

In the beginning, computers were the size of large conference rooms. A punch card reader would merrily accept pieces of paper that instructed the computer to do something, and then a printer would etch the results into another piece of paper. Thousands of mechanical parts worked harmoniously (when they did work) to compute relatively simple commands.

As time progressed, computers became somewhat smaller, and interactive terminals became more user-friendly, but they were still wired directly into the computer being used. Mainframes came to the fore in the 1960s, originally used via typewriter and teletype interfaces, then via keyboards and small text displays. As networked computing became more mainstream in the 1970s and 1980s, remote terminal access was used to interact with the large central computers.


Subscribe to RSS - linux