Build your vagrant machine in some dir using the files Vagrantfile
and
pre-install.app.sh
with the command vagrant up
. That will deploy a
new virtual machine accessible with vagrant ssh
, write down its ip
visible with ifconfig
and update that IP/URL in the .deliver/config
file in this guide.
ivan@z11:~/Development/elixir$ mix phx.new chaty
ivan@z11:~/Development/elixir$ cd chaty/
ivan@z11:~/Development/elixir/chaty$ mix do ecto.create, phx.server
ivan@z11:~/Development/elixir/chaty$ git init && git add . && git commit -av -m "initial"
Configure the database. This file is ignored by git, but we need it in
the home folder of each node of the cluster, so upload to each node
using scp
:
ivan@z11:~/Development/elixir/chaty (master)$ vim config/prod.secret.exs
config :chaty, DeployMe.Repo,
adapter: Ecto.Adapters.Postgres,
username: "chaty",
password: "passw0rd",
database: "chaty_prod",
pool_size: 15,
hostname: "172.28.128.7" # IP of the database server
ivan@z11:~/Development/elixir/chaty (master)$ scp config/prod.secret.exs 172.28.128.3:~/
ivan@z11:~/Development/elixir/chaty (master)$ scp config/prod.secret.exs 172.28.128.4:~/
ivan@z11:~/Development/elixir/chaty (master)$ scp config/prod.secret.exs 172.28.128.5:~/
Install edeliver
and distillery
libraries:
ivan@z11:~/Development/elixir/chaty (master)$ vim mix.exs
def deps do
...
{:edeliver, "~> 1.4.4"},
{:distillery, "~> 1.5", runtime: false},
ivan@z11:~/Development/elixir/chaty (master)$ mix deps.get
ivan@z11:~/Development/elixir/chaty (master)$ mkdir .deliver/
ivan@z11:~/Development/elixir/chaty (master)$ vim .deliver/config
# 1. Give a name to your app
#-----------------------------------------------------------------------
# This is the name of the directory on the server containing the
# application.
APP="chaty"
# 2. Declare the names of your servers and assign the public DNS
#-----------------------------------------------------------------------
# You can use IP's if they don't change, nameserver or DNS locations
ONE="172.28.128.3"
TWO="172.28.128.4"
THREE="172.28.128.4"
# 3. Specify a user
#-----------------------------------------------------------------------
# This is the user that has SSH and folder access on each of the
# previously declared servers. Note that all the servers should have
# the same user name.
USER="ivan"
# 4. Which host do you want to build the release on?
#-----------------------------------------------------------------------
# I usually point this to the server that is closest to me.
# -- But Why?? --
# Some OS specific libraries are required. This means that when you
# build a release on say, a Mac, and then transfer the release to a
# Linux system, nothing will work and you will most definitely get
# strange and utterly confusing errors.
BUILD_HOST="$ONE" # <-- PUT HERE YOUR VIRTUAL MACHINE IP
BUILD_USER=$USER
BUILD_AT="/tmp/edeliver/$APP/builds"
# 5. Optionally specify the staging host
#-----------------------------------------------------------------------
# The staging host is basically the host where you want to test the
# release at.
# STAGING_HOSTS="188.166.182.170"
# STAGING_USER="deploy"
# TEST_AT="/home/deploy/staging"
#6. Specify which host(s) the app is going to be deployed to
#-----------------------------------------------------------------------
PRODUCTION_HOSTS="$ONE $TWO $THREE" # <-- PUT HERE YOUR VIRTUAL MACHINE IP
PRODUCTION_USER=$USER
DELIVER_TO="/home/$PRODUCTION_USER"
# 7. Point to the vm.args file.
#-----------------------------------------------------------------------
# As its name suggests, this file specifies the flags used to start
# the Erlang virtual machine, like the list of nodes in a cluster
LINK_VM_ARGS=/home/$PRODUCTION_USER/vm.args
# 8.OTHER STUFF
#-----------------------------------------------------------------------
# ¯\_(ツ)_/¯
RELEASE_DIR="/tmp/edeliver/$APP/builds/_build/prod/rel/$APP"
# This is for distillery. Needed?
VMARGS_PATH="/tmp/edeliver/$APP/builds/_build/prod/rel/$APP"
# prevent re-installing node modules; this defaults to "."
#GIT_CLEAN_PATHS="_build rel priv/static"
# 9. This is for Phoenix projects
#-----------------------------------------------------------------------
# For *Phoenix* projects, symlink prod.secret.exs to our tmp source
pre_erlang_get_and_update_deps() {
local _prod_secret_path="/home/$PRODUCTION_USER/prod.secret.exs"
if [ "$TARGET_MIX_ENV" = "prod" ]; then
__sync_remote "
ln -sfn '$_prod_secret_path' '$BUILD_AT/config/prod.secret.exs'
"
fi
}
pre_erlang_clean_compile() {
status "Running phoenix.digest" # log output prepended with "----->"
__sync_remote " # runs the commands on the build host
# [ -f ~/.profile ] && source ~/.profile # load profile (optional)
source ~/.profile
# echo \$PATH # check if rbenv is in the path
set -e # fail if any command fails (recommended)
cd '$BUILD_AT/assets' # enter the build directory on the build host (required)
# prepare something
mkdir -p priv/static # required by the phx.digest task
npm install
./node_modules/brunch/bin/brunch build --production
cd '$BUILD_AT' # enter the build directory on the build host (required)
# run your custom task
APP='$APP' MIX_ENV='$TARGET_MIX_ENV' $MIX_CMD phx.digest $SILENCE
"
}
Ensure that all virtual machines have the correct IP nodes in
chaty.conf
file inside each node.
Example in chaty@172.28.128.3
chaty.conf
file:
[{kernel,
[
{sync_nodes_optional, ['chaty@172.28.128.4', 'chaty@172.28.128.5']},
{sync_nodes_timeout, 30000}
]}
].
Configure Endpoint:
ivan@z11:~/Development/elixir/chaty (master)$ vim config/prod.exs
config :chaty, DeployMeWeb.Endpoint,
# load_from_system_env: true, # COMMENT THIS!
# https://stackoverflow.com/questions/47071275
cache_static_manifest: "priv/static/cache_manifest.json",
# The port that the app runs on
http: [port: 4000],
# This is to generate links
url: [host: "example.com", port: 80],
# Leave this uncommented
config :phoenix, :serve_endpoints, true
ESTA HACE FALTA?
ivan@z11:~/Development/elixir/chaty (master)$ mix do deps.get, compile
Initialize the file rel/config.exs
using this command:
ivan@z11:~/Development/elixir/chaty (master)$ mix release.init
Add a plugin to the release to allow to link the file
ivan@z11:~/Development/elixir/chaty (master)$ vim rel/config.exs
environment :prod do
..
# Because distillery uses `:systools_make.make_tar(...)` to create
# the release tar which resoves all links using the `:dereference`
# option, the release tar needs to be repackaged including the
# links. To be able use this plugin, it must be added in the
# `rel/config.exs` distillery config as plugin like this:
plugin Releases.Plugin.LinkConfig
end
Save to control version:
ivan@z11:~/Development/elixir/chaty (master)$ echo "" >> .gitignore
ivan@z11:~/Development/elixir/chaty (master)$ echo ".deliver/releases/" >> .gitignore
ivan@z11:~/Development/elixir/chaty (master)$ git add .
ivan@z11:~/Development/elixir/chaty (master)$ git commit -m "Deployment"
ivan@z11:~/Development/elixir/chaty (master)$ mix edeliver build release production --verbose
ivan@z11:~/Development/elixir/chaty (master)$ mix edeliver deploy release production
ivan@z11:~/Development/elixir/chaty (master)$ mix edeliver start production
ivan@z11:~/Development/elixir/chaty (master)$ mix edeliver migrate production
Whenever you want to hot upgrade the production bump the version in
mix.exs
and:
$ mix edeliver build release production --verbose
$ mix edeliver deploy release production