1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297
|
User guide
==========
Setting up a project
--------------------
Let's deploy a project using Mina.
### Step 1: Create a config/deploy.rb
In your project, type `mina init` to create a sample of this file.
$ mina init
Created config/deploy.rb.
This is just a Rake file with tasks! See [About deploy.rb](#about-deployrb) for
more info on what *deploy.rb* is. You will want to at least configure your
server:
~~~ ruby
# config/deploy.rb
set :user, 'username'
set :domain, 'your.server.com'
set :deploy_to, '/var/www/flipstack.com'
...
~~~
### Step 2: Set up your server
Make a directory in your server called `/var/www/flipstack.com` (in *deploy_to*)
change it's ownership to the correct user.
$ ssh username@your.server.com
# Once in your server, create the deploy folder:
~@your.server.com$ mkdir /var/www/flipstack.com
~@your.server.com$ chown -R username /var/www/flipstack.com
### Step 3: Run 'mina setup'
Back at your computer, do `mina setup` to set up the [folder
structure](#directory_structure) in this path. This will connect to your server
via SSH and create the right directories.
$ mina setup
-----> Creating folders... done.
See [directory structure](#directory_structure) for more info.
### Step 4: Deploy!
Use `mina deploy` to run the `deploy` task defined in *config/deploy.rb*.
$ mina deploy
-----> Deploying to 2012-06-12-040248
...
Lots of things happening...
...
-----> Done.
About deploy.rb
---------------
The file `deploy.rb` is simply a Rakefile invoked by Rake. In fact, `mina` is
mostly an alias that invokes Rake to load `deploy.rb`.
~~~ ruby
# Sample config/deploy.rb
set :domain, 'your.server.com'
task :restart do
queue 'sudo service restart apache'
end
~~~
As it's all Rake, you can define tasks that you can invoke using `mina`. In this
example, it provides the `mina restart` command.
The magic of Mina is in the new commands it gives you.
The `queue` command queues up Bash commands to be run on the remote server.
If you invoke `mina restart`, it will invoke the task above and run the queued
commands on the remote server `your.server.com` via SSH.
See [the command queue](#the-command-queue) for more information on the *queue*
command.
The command queue
-----------------
At the heart of it, Mina is merely sugar on top of Rake to queue commands
and execute them remotely at the end. Take a look at this minimal *deploy.rb*
configuration:
~~~ ruby
# config/deploy.rb
set :user, 'john'
set :domain, 'flipstack.com'
task :logs do
queue 'echo "Contents of the log file are as follows:"'
queue "tail -f /var/log/apache.log"
end
~~~
Once you type `mina logs` in your terminal, it invokes the *queue*d commands
remotely on the server using the command `ssh john@flipstack.com`.
~~~ sh
$ mina logs --simulate
# Execute the following commands via
# ssh john@flipstack.com:
#
echo "Contents of the log file are as follows:"
tail -f /var/log/apache.log
~~~
Subtasks
--------
Mina provides the helper `invoke` to invoke other tasks from a
task.
~~~ ruby
# config/deploy.rb
task :down do
invoke :maintenance_on
invoke :restart
end
task :maintenance_on
queue 'touch maintenance.txt'
end
task :restart
queue 'sudo service restart apache'
end
~~~
In this example above, if you type `mina down`, it simply invokes the other
subtasks which queues up their commands. The commands will be run after
everything.
Directory structure
-------------------
The deploy procedures make the assumption that you have a folder like so:
/var/www/flipstack.com/ # The deploy_to path
|- releases/ # Holds releases, one subdir per release
| |- 1/
| |- 2/
| |- 3/
| '- ...
|- shared/ # Holds files shared between releases
| |- logs/ # Log files are usually stored here
| `- ...
'- current/ # A symlink to the current release in releases/
It also assumes that the `deploy_to` path is fully writeable/readable for the
user we're going to SSH with.
Deploying
---------
Mina provides the `deploy` command which *queue*s up a deploy script for
you.
~~~ ruby
# config/deploy.rb
set :domain, 'flipstack.com'
set :user, 'flipstack'
set :deploy_to, '/var/www/flipstack.com'
set :repository, 'http://github.com/flipstack/flipstack.git'
task :deploy do
deploy do
# Put things that prepare the empty release folder here.
# Commands queued here will be run on a new release directory.
invoke :'git:clone'
invoke :'bundle:install'
# These are instructions to start the app after it's been prepared.
to :launch do
queue 'touch tmp/restart.txt'
end
# This optional block defines how a broken release should be cleaned up.
to :clean do
queue 'log "failed deployment"'
end
end
end
~~~
It works by capturing the *queue*d commands inside the block, wrapping them
in a deploy script, then *queue*ing them back in.
### How deploying works
Here is an example of a deploy! (Note that some commands have been simplified
to illustrate the point better.)
### Step 1: Build it
The deploy process builds a new temp folder with instructions you provide.
In this example, it will do `git:clone` and `bundle:install`.
$ mina deploy --verbose
-----> Creating the build path
$ mkdir tmp/build-128293482394
-----> Cloning the Git repository
$ git clone https://github.com/flipstack/flipstack.git . -n --recursive
Cloning... done.
-----> Installing gem dependencies using Bundler
$ bundle install --without development:test
Using i18n (0.6.0)
Using multi_json (1.0.4)
...
Your bundle is complete! It was installed to ./vendor/bundle
### Step 2: Move it to releases
Once the project has been built, it will be moved to `releases/`. A symlink
called `current/` will be created to point to the active release.
$
-----> Moving to releases/4
$ mv "./tmp/build-128293482394" "releases/4"
-----> Symlinking to current
$ ln -nfs releases/4 current
### Step 3: Launch it
Invoke the commands queued up in the `to :launch` block. These often
commands to restart the webserver process. Once this in complete, you're done!
$
-----> Launching
$ cd releases/4
$ sudo service nginx restart
-----> Done. Deployed v4
### What about failure?
If it fails at any point, the release path will be deleted. If any commands are
queued using the `to :clean` block, they will be run. It will be as if nothing
happened. Lets see what happens if a build fails:
$
-----> Launching
$ cd releases/4
$ sudo service nginx restart
Starting nginx... error: can't start service
-----> ERROR: Deploy failed.
-----> Cleaning up build
$ rm -rf tmp/build-128293482394
-----> Unlinking current
$ ln -nfs releases/3 current
OK
Command line options
--------------------
Basic usage:
$ mina [OPTIONS] [TASKS] [VAR1=val VAR2=val ...]
### Options
* `-v` / `--verbose` - This will show commands being done on the server. Off by
default.
* `-S` / `--simulate` - This will not invoke any SSH connections; instead, it
will simply output the script it builds.
* `-t` / `--trace` - Show backtraces when errors occur.
* `-f FILE` - Use a custom deploy.rb configuration.
* `-V` / `--version` - Shows the current version.
### Tasks
There are many tasks available. See the [tasks reference](http://mina-deploy.github.io/mina/tasks/), or
type `mina tasks`.
### Variables
You may specify additional variables in the `KEY=value` style, just like Rake.
You can add as many variables as needed.
$ mina restart on=staging
# This sets the ENV['on'] variable to 'staging'.
|