Introduction

Meet tj, a tool that helps you create new local WordPress development sites, manage existing sites, and deploy them, all from the command line.

tj handles all of the hard stuff: creation of a local development environment, managing local and remote WordPress sites, and the most annoying part of all, actually deploying those sites. Say goodbye to MAMP!

tj is built on top of tried and true open source libraries such as Capistrano for deployment, Vagrant for local development, and even a little bit of WP-CLI for database migration.

Requirements

tj requires Vagrant and VirtualBox to be able to create virtual machines for local development. Please download and install both of these before getting started. If you plan on using tj for deployments, you should also ensure that your remote servers have WP-CLI installed in order for tj to be able to handle database migration.

I recommend one of the latest versions of Ruby MRI (2.2, 2.1, 2.0). tj requires at least MRI 1.9.3. For the full report, check out the Travis CI build status, where I test against an array of Ruby interpreters.

I also recommend you set up SSH-keys for GitHub. Internally, tj uses git clone with SSH URLs, so things might break if you don't have your keys set up properly.

Installation

gem install theme-juice

NAME

tj-deploy - Deploy a project

SYNOPSIS

tj deploy stage [command] [--flag=arg] [--flag]

DESCRIPTION

Deploys a project to the passed stage. All commands are transformed and then piped directly to capistrano(1) to handle deployment.

REQUIREMENTS

The remote that is being deployed to needs to have wp-cli(1) installed in order for tj(1) to be able to handle database migration.

SETUP

Follow these steps to quickly get up and running:

  1. Create a deploy user on the stage server
  2. Set up SSH keys for the new deploy user for password-less SSH access
  3. Confirm the deploy user owns the deploy path
  4. Run tj deploy <stage> setup to setup the required directories
  5. Deploy!

GLOBAL OPTIONS

-b, --branch=branch

Use an alternate git(1) branch for current deployment

--archive, --tar, --gzip, --zip

Archive directories with tar(1) when performing file transfers

PRIMARY COMMANDS

If no command is passed, the default task to be executed is deploy

deploy

Deploy a project

rollback

Rollback a previous deployment

setup, check

Run a preliminary deployment check, making sure that all necessary folders are created and accessible on the passed stage

SECONDARY COMMANDS

db:backup

Back up the database on the passed stage and store it locally in the deployment.stages.vagrant.backup directory

db:pull

Pull the database from the passed stage and import it into the development environment

db:push

Push the database from the development environment and import it into the passed stage

env:pull

Pull the current .env.<stage> file from the passed stage to the development environment

env:push

Push the current .env.<stage> file from the development environment to the passed stage

uploads:pull

Pull the current stage's uploads folder from the passed stage to the development environment

uploads:push

Push the uploads folder from the development environment to the passed stage's uploads folder

file:pull=path

Pull a relative file from the passed stage to the development environment.

file:push=path

Push a relative file from the development environment to the passed stage.

dir:pull=path

Recursively pull a relative directory from the passed stage to the development environment.

dir:push=path

Recursively push a relative directory from the development environment to the passed stage.

CONFIG FILE

The YAML Juicefile(5) configuration may be used to store deployment-related settings. Below you will find the various options you can use to define your project's deployment setup.

deployment

Deployment configuration

deployment.application

Application settings passed directly to capistrano(1)

deployment.settings

Deployment settings passed directly to capistrano(1)

deployment.repository

Repository settings passed directly to capistrano(1)

deployment.rsync

Optional settings passed to capistrano-rsync(1); mapped as rsync_<setting> during the deployment initialization

deployment.slack

Optional settings passed to capistrano-slackify(1); mapped as slack_<setting> during the deployment initialization

deployment.stages

Deployment stages

deployment.stages.<stage>.server

Domain or IP address of the server; can include an optional port number in the form of <ip_or_domain>:<port>

deployment.stages.<stage>.path

Root path to the deployment directory

deployment.stages.<stage>.user

User account to deploy as (it is recommended not to use root)

deployment.stages.<stage>.url

URL of the stage

deployment.stages.<stage>.uploads

Relative path from deploy path to the uploads folder

deployment.stages.<stage>.tmp

Relative path from deploy path to the tmp folder

deployment.stages.<stage>.shared

Sequence of relative files from application root to place inside of the shared folder. Files that end with a trailing forward slash are assumed to be a directory.

deployment.stages.<stage>.roles

Sequence of deployment roles for the stage

deployment.stages.vagrant

Required development environment settings; these are used for database and file migration

deployment.stages.vagrant.server

Domain or IP address of the development environment

deployment.stages.vagrant.path

Root path to the application directory within the VM

deployment.stages.vagrant.user

User account to deploy as (usually vagrant)

deployment.stages.vagrant.pass

Password for the user (usually vagrant)

deployment.stages.vagrant.url

URL of the project

deployment.stages.vagrant.uploads

Relative path from application root to the uploads folder

deployment.stages.vagrant.backup

Relative path from application root to the backup folder

deployment.stages.vagrant.tmp

Relative path from application root to the tmp folder

deployment.stages.vagrant.roles

Sequence of roles for the development environment

Below is an example deployment configuration:

  # Project configuration
  project:
    name: example

  # Deployment configuration
  deployment:

    # Repository settings
    repository:
      repo_url: git@github.com:example/example-app.git
      branch: :master
      scm: :rsync

    # Other settings that will be passed directly to Capistrano
    # @see http://capistranorb.com/
    settings:
      keep_releases: 5
      format: :pretty
      log_level: :verbose
      use_sudo: false
      ssh_options:
        keys: ~/.ssh/id_rsa
        forward_agent: true
        paranoid: true
      # Add additional directories to $PATH. This is useful if you're
      #  on a shared hosting environment (i.e. GoDaddy) and you need
      #  to use an executable such as wp-cli for database migration.
      default_env:
        path: /opt/wp-cli/bin:$PATH

    # Capistrano rsync options and install procedure
    # @see https://github.com/Bladrak/capistrano-rsync
    rsync:
      stage: tmp/deploy
      cache: shared/deploy
      scm: :git
      depth: 1
      # Options to pass to the rsync command
      # @see http://linux.die.net/man/1/rsync
      options:
        - --recursive
        - --delete
        - --delete-excluded
        - --include="vendor/**/*" # Overrides any excluded patterns
        - --exclude="node_modules/"
        - --exclude=".env.sample"
        - --exclude=".git*"
        - --exclude="Juicefile*"
        - --exclude="composer.*"
        - --exclude="package.json"
        - --exclude="README.*"
      # Run application install scripts
      install:
        - composer install --no-dev
        - bundle install
        - npm install
        - bower install
        - grunt build
      # Run scripts before the deployment starts
      pre_scripts:
        - touch .maintenance
      # Run scripts before the deployment finishes
      post_scripts:
        - rm .maintenance
        - sudo service apache2 restart

    # Slack integration
    # @see https://github.com/onthebeach/capistrano-slackify
    slack:
      url: https://hooks.slack.com/services/your-token
      username: Deploybot
      channel: "#devops"
      emoji: ":rocket:"

    # Deployment stages
    stages:

      production:
        server: 192.168.13.37:1234
        path: /var/www/production
        user: deploy
        url: example.com
        uploads: app/uploads
        tmp: tmp
        shared:
          - .env.production
        ignore:
          - robots.txt
        roles:
          - :web
          - :app
          - :db

      staging:
        server: 192.168.13.37
        path: /var/www/staging
        user: deploy
        url: staging.example.com
        uploads: app/uploads
        tmp: tmp
        shared:
          - .env.staging
        roles:
          - :web
          - :app
          - :db

      # This is your development environment used to push/pull database files,
      #  uploads, the .env file, etc.
      vagrant:
        server: example.dev
        path: /srv/www/tj-example
        user: vagrant
        pass: vagrant
        url: example.dev
        uploads: app/uploads
        backup: backup
        tmp: tmp
        roles:
          - :dev