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.