Skip to content

Instantly share code, notes, and snippets.

@oojikoo-gist
Created September 11, 2015 07:21
Show Gist options
  • Save oojikoo-gist/d213b3425544af7f662d to your computer and use it in GitHub Desktop.
Save oojikoo-gist/d213b3425544af7f662d to your computer and use it in GitHub Desktop.
rails: mina

(these are merely ideas, not a concrete plan on where Mina is headed from now!)

State of affairs

There are many tools available for app deployment, but they can all use some form of improvement.

  • Capistrano is flexible, but slow, and takes too much effort to customize.
  • Cap and Mina can work with any language, but the Capfiles and deploy.rb's are all written in Ruby, making anyone writing in Node/Python/Scala feel a little left out.
  • Cap and Mina both let you declare your deploy manifests imperatively, not declaratively.
  • Mina doesn't have native support for handling multiple servers and environments (although it can easily do this).
  • Mina is fast, but can be made even faster.

Mina2

Here's my vision to what Mina's successor should be like:

  • Write your deploy files in a declarative manner in a YAML file
  • Plain ol' YAML files - no need to learn Ruby. Also, you can take advantage of YAML constructs, like inheritance.
  • Deployment manifests are shorter and more manageable than Cap/Mina.
  • Semi-inspired by Ansible.

Example

Write your config/deploy.yml. Here's a full example:

---
# (Optional) declare what libraries you want. You can also add relative paths
# to your own extensions.
use:
  - mina/rails
  - mina/rvm
  - ../lib/mina-ext.rb

# List down your hosts here, grouped by 'environment'. In this case, we have
# one production server. (In the real world, you probably will have
# `production` and `staging` at the very least, and they can share variables
# via YAML inheritance.)
hosts:
  production:
    - host: [email protected]                  # <- some variables here
      deploy_to: /var/www/myapp
      git: https://github.com/me/myapp
      rails_env: production
      shared_paths:
        - config/database.yml
        - config/settings.yml
        - public
        - logs

# Task definitions go here.
tasks:
  setup:
    - shell: mkdir -p {{deploy_to}}/{releases,tmp,shared/pids,shared/public,shared/logs}
    - shell: chown -R {{owner}} {{deploy_to}}
    - rvm: create_gemset 2.0.0-p0@myapp

  deploy.build:
    - rvm: use 2.0.0-p0@myapp
    - rails: assets_precompile
    - rails: db_migrate

  deploy.after:
    - rake: cdn:propagate
    - task: restart

  # You can write any task, and invoke it as `m2 <taskname>` (eg, in this case:
  # `m2 restart`). It can also be called in another task using `- task: <taskname>`.
  restart:
    - shell: touch tmp/restart.txt

  logs:
    - shell: tail -f {{deploy_to}}/shared/logs/production.log

  console:
    - rails: console

  # Complicated tasks are no problem.
  clean:
    - shell: |
      rm -rf {{deploy_to}}/shared/public/assets &&
      rm -rf {{deploy_to}}/shared/logs/*

Run it:

$ m2 setup
$ m2 deploy
$ m2 deploy production
$ m2 logs
$ m2 console
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment