Isnor Creative
Isnor Creative Blog
Ruby, Ruby on Rails, Ember, Elm, Phoenix, Elixir, React, Vue

Aug 30, 2015

Elixir Phoenix deployment with Mina

Update April 6 2018 –– edeliver is great, but for a new application I would also suggest looking at Nanobox –- I have not personally used Nanobox for Elixir yet, but for Rails applicatioins it is brilliant and I imagine the Elixir support is equally solid.

Update: This is a world of hurt. I have subsequently discovered [edeliver](https://github.com/boldpoker/edeliver) and it looks solid. I will update this with better notes on server setup and edeliver deploys.

This is how I am deploying a Phoenix application to a Linode using Mina.

Note that my Phoenix application is an API only and so I did not need to look into compiling and deploying assets with Brunch. This may need to be addressed in the Mina recipe for an application that does require static assets.

I followed the Phoenix exrm deployment guides and also referred to some other blog articles and projects for reference:

  • https://github.com/ohr486/elixirdeployexample/blob/master/README.md
  • http://learnelixir.com/blog/2014/10/16/deploy-phoenix-application-to-a-ubuntu-server/
  • https://github.com/maruware/capistrano-phoenix

I configured upstart as per the Phoenix guides, and added Erlang and Elixir via Chef recipes:

cookbook 'erlang', github: 'opscode-cookbooks/erlang'
cookbook 'elixir', github: 'parroty/chef-cookbook-elixir'

I added a Gemfile:

source 'https://rubygems.org'
gem 'mina'

And then installed Mina:

bundle

This is my Mina deploy.rb file:

require 'mina/git'
require 'mina/rbenv'

set :domain, 'www.example.com'
set :deploy_to, '/path/to/my/app'

set :repository, 'ssh://git@example.com/me/my-app.git'
set :branch, 'master'
set :app_name, 'my-app'

set :shared_paths, ['log', 'config/prod.secret.exs']

set :user, 'me'
set :forward_agent, true
set :identity_file, '/path/to/my/key'

set :log_path, "#{deploy_to}/#{current_path}/rel/#{app_name}/log"

task :setup do
  queue %[sudo mkdir -p "#{log_path}"]
  queue %[sudo chmod g+rx,u+rwx "#{log_path}"]
end

desc "Deploys the current version to the server."
task :deploy do
  deploy do
    invoke :'git:clone'
    invoke :'deploy:link_shared_paths'
    queue %[mix deps.get]
    queue %[MIX_ENV=prod mix release]
    
    to :launch do
      invoke :'elixir:stop'
      invoke :'elixir:start'
    end

    to :clean do
      queue 'echo "Failed deployment"'
    end

  end
end

namespace :elixir do

  desc "start"
  task :start do
    queue "echo 'Elixir #{cmd}'"
    queue "sudo start #{app_name}"
  end

  desc "stop"
  task :stop do
    queue "echo 'Elixir stop'"
    queue "sudo stop #{app_name}"
  end

  desc "ping"
  task :ping do
    queue "echo 'Elixir ping'"
    queue "cd #{deploy_to}/#{current_path}/rel/#{app_name}/bin && ./#{app_name} ping"
  end

end

task :logs do
  queue 'echo "Contents of the log file are as follows:"'
  queue "tail -f `/bin/ls -1td #{log_path}/*| /usr/bin/head -n1`"
end

To deploy:

mina deploy

And to view logs:

mina logs

I am available for Elixir/Phoenix consulting work – get in touch to learn more.

Gordon B. Isnor

Gordon B. Isnor writes about Ruby on Rails, Ember.js, Elm, Elixir, Phoenix, React, Vue and the web.
If you enjoyed this article, you may be interested in the occasional newsletter.

I am now available for project work. I have availability to build greenfield sites and applications, to maintain and update/upgrade existing applications, team augmentation. I offer website/web application assessment packages that can help with SEO/security/performance/accessibility and best practices. Let’s talk

comments powered by Disqus