Efficient Drupal Development with Tmux and Tmuxinator

Bob
Lead Drupal Architect
Feb
12
2015

Efficient Drupal Development with Tmux and Tmuxinator

Have you ever wished you could just type one command and load up all of the things you need to work on for a project? Wouldn’t it be nice to have your terminal set up with the correct Drush alias, tailing the watchdog, with access to your servers just a couple keystrokes away? Sounds nice, right? With a little work and a handful of open source applications this can be a reality for you.

When I need to get started on one of my projects it’s as simple as typing mux projectname and I pick up right where I left off the previous day. Here’s how I do it.

Tmux

The cornerstone application that I use every day is a terminal multiplexer called Tmux. It allows you to quickly switch between multiple terminal programs using key commands. One on my favorite features of tmux are the multi-pane windows. You can divvy up your terminal window into two, three, or more panes. Each one running it’s own terminal session. While this is useful enough, its true utility is its ability to detach from a session without interrupting or canceling it. For example, let’s say you are downloading a large file with wget on a server and want to check something else on your local machine while you wait. You can do so without opening a new terminal window by detaching from your tmux session. Your download will continue in the background. Then, when you are ready to resume work on your server simply re-attach to your tmux session.

That all sounds great, but how can this application help me with my local development work? This is where Tmuxinator comes in. Tmuxinator provides a method for creating and managing tmux sessions. I can’t imaging using tmux without it. I have a default template that I begin with on every project. It includes my terminal layouts, commands I need to run when beginning work, and windows for development, staging, and production servers, and setting up each pane with the proper Drush or bash alias.

Installation

Tmux

On a Mac you can quickly install Tmux using Homebrew.

 

brew install tmux

 

Once you have tmux installed you will want to take a look at the post on the Thoughtbot’s blog “A tmux Crash Course” and set up your own keybinding configuration. Then you will want to set up copy and paste to work as it does in Vim by following this Thoughtbot tutorial. If you are on Linux you may find that you don’t need some of these configuration changes. Specifically the copy and paste settings. I have included my .tmux.conf file below. Note, this file is located in your home directory and is a dot file so it will be hidden in most file browsers.

My .tmux.conf file

# Use vi mode

setw -g mode-keys vi

# fix pbcopy and pbpaste

set-option -g default-command "reattach-to-user-namespace -l bash"

# Setup 'v' to begin selection as in Vim

bind-key -t vi-copy v begin-selection

bind-key -t vi-copy y copy-pipe "reattach-to-user-namespace pbcopy"

# Update default binding of `Enter` to also use copy-pipe

unbind -t vi-copy Enter

bind-key -t vi-copy Enter copy-pipe "reattach-to-user-namespace pbcopy"

# force a reload of the config file

unbind r

bind r source-file ~/.tmux.conf

# mouse scrolling and selection

set -g mode-mouse on

set -g default-terminal "screen-256color"

Tmuxinator

Now you should be ready to use Tmux, but let’s also set up Tmuxinator. Tmuxinator is a Ruby gem and can be installed with the command gem install tmuxinator but do follow the instructions on the project page.

Setting up your first project

Now, let’s set up a new Tmuxinator project by typing mux new awesome_project. This will open up your project file in your default text editor.

# ~/.tmuxinator/awesome_project.yml

  name: awesome_project  
  
  root: ~/
  
  # Optional tmux socket  
  
  # socket_name: foo
  
  # Runs before everything. Use it to start daemons etc.  
  
  # pre: sudo /etc/rc.d/mysqld start
  
  # Runs in each window and pane before window/pane specific commands. Useful for setting up interpreter versions.  
  
  # pre_window: rbenv shell 2.0.0-p247
  
  # Pass command line options to tmux. Useful for specifying a different tmux.conf.  
  
  # tmux_options: -f ~/.tmux.mac.conf
  
  # Change the command to call tmux.  This can be used by derivatives/wrappers like byobu.  
  
  # tmux_command: byobu
  
  windows:  
  
    - editor:  
  
        layout: main-vertical  
  
        panes:  
  
          - vim  
  
          - guard  
  
    - server: bundle exec rails s  
  
    - logs: tail -f log/development.log  

Each tab in tmux is called a window. You can assign names to these windows which helps you remember what a window is used for. Inside each tmux window is one or more panes. The default configuration that Tmuxinator provides is very Ruby on Rails specific so let’s change that. Here is a more Drupal specific tmuxinator project setup.

# ~/.tmuxinator/awesome_project.yml

# you can make as many tabs as you wish…

project_name: awesome_project  

project_root: ~/Sites/awesome_project  

windows:  

    - drupal:  

        layout: main-vertical  

        panes:  

        - cd docroot && pstorm . && drush use @awesome.mcdev && git status  

        - cd docroot && drush use @awesome.mcdev && drush ws --tail  

        - cd mis_vagrant && vagrant up  

    - tig: cd docroot && tig  

    - dev: alias drush="/usr/local/bin/drush/drush" && drush use @drupalplatformprovider.awesome.dev  

    - staging: alias drush="/usr/local/bin/drush/drush" && drush use @drupalplatformprovider.awesome.test  

    - prod:  alias drush="/usr/local/bin/drush/drush" && drush use @drupalplatformprovider.awesome.live 

Once you have made your changes save and close the project file. Type mux awesome_project to begin you first tmux session.

You will notice that I have several windows. Specifically, I want to point out the dev/staging/prod windows. I like to use drush aliases and with Tmuxinator you can execute terminal commands when you launch the session. Let me walk through what the tmuxinator project file is actually doing.

Drupal Window

  • Pane 1: I cd to docroot and open that directory in PHPStorm. You can substitute this command for your editor of choice.
  • Pane 2: I cd to docroot and set drush to use my local alias then tail the drupal watchdog with drush use @awesome.mcdev && drush ws –tail.
  • Pane 3: launches my vagrant box for this project

Tig Window

I cd to docroot and execute the Tig application which shows me a list of commits to the repository in the command line.

Dev / Stage / Prod

On many projects our clients may be using a Drupal platform service such as Pantheon or Acquia Cloud. Some server environments may require the use of older versions of Drush than say Drush 7. I will have Tmuxinator set up each terminal window with the proper shell alias to my desired drush version and also the drush alias for that server.

Is it worth it?

While this may seem like quite a bit of work to set up the efficiency you can achieve with this workflow will quickly become apparent.

Additional Resources

How To Prettify the Output From Your Remote Drush Commands | Mediacurrent Blog Post
Learning How To Install Drush on Non-Admin Rights Server | Mediacurrent Blog Post
A Better Access Denied Page with Panels | Mediacurrent Blog Post 

comments powered by Disqus