Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How I Deploy at Crevalle

How I Deploy at Crevalle

Crevalle has several company Elixir products and is creating new ones all the time. We need an easy way to deploy new applications and regularly update our existing ones. Here, we'll look at how the company uses Distillery and eDeliver to deploy our apps to a single server running Ubuntu.

Desmond Bowe

December 12, 2017
Tweet

More Decks by Desmond Bowe

Other Decks in Programming

Transcript

  1. The Situation • single frontend host runs all apps •

    worker runs all datastores • different apps run on different ports • apps are separate, but could be in umbrella • one instance of Postgres, multiple databases frontend NGINX KLEO Lily BiC https://kleo.crevalle.io https://lily.crevalle.io http://becauseitscool.net Postgres
 worker
  2. The Situation frontend NGINX KLEO Lily BiC https://kleo.crevalle.io https://lily.crevalle.io http://becauseitscool.net

    Postgres
 worker ~/ apps/ bic/ kleo/ lily/ secrets/ bic.secret.exs kleo.secret.exs lily.secret.exs
  3. What’s a Release? • executable++ • includes dependencies • allows

    you to specify VM args • versioned • can compile Erlang itself into your release executable, so you don’t need Erlang installed on your production machine $ mix release
  4. What’s a Release? ~/apps/kleo/ bin/ erl_crash.dump erts-9.0/ lib/ releases/ var/

    executables for current release debugging Erlang Source your app’s source and dependencies executables and configs for each release VM configs and logs for current release
  5. Caveats • must build release on same architecture as host

    • handle compile-time interpolation of system variables • must have a Version
  6. Distillery Config Path.join(["rel", "plugins", "*.exs"]) |> Path.wildcard() |> Enum.map(&Code.eval_file(&1)) use

    Mix.Releases.Config, default_release: :default, default_environment: Mix.env() environment :dev do set dev_mode: true set include_erts: false set cookie: :”secret cookie" end environment :prod do set include_erts: true set include_src: false set cookie: :”super secret cookie" end release :crevalle do set version: String.trim(File.read!("VERSION.txt")) set commands: [ "migrate": "rel/commands/migrate.sh" ] set applications: [ :runtime_tools ] end
  7. eDeliver • orchestrates building of release on specified hosts •

    uploads release to production host • starts | stops release • sets up logging directories w/ autorotate • other helpful commands • run deploy scripts • compile Phoenix assets • symlink secret files • does not actually build the release “edeliver is based on deliver and enables you to build and deploy Elixir and Erlang applications and perform hot-code upgrades.”
  8. eDeliver #!/usr/bin/sh APP="kleo" USING_DISTILLERY=true CREVALLE="23.92.18.58" BUILD_HOST="$CREVALLE" BUILD_USER="desmond" BUILD_AT="/home/desmond/edeliver/$APP/builds" RELEASE_DIR="$BUILD_AT/_build/prod/rel/kleo" GIT_CLEAN_PATHS="_build

    rel apps/kleo/priv/static" # STAGING_HOSTS="staging1 staging2" # STAGING_USER="deploy" # TEST_AT="/home/deploy/staging" PRODUCTION_HOSTS="$CREVALLE" PRODUCTION_USER="desmond" DELIVER_TO="/home/desmond/apps" pre_erlang_get_and_update_deps() { local _kleo_secret_path="/home/desmond/apps/kleo.secret.exs" if [ "$TARGET_MIX_ENV" = "prod" ]; then __sync_remote " ln -sfn '$_kleo_secret_path' '$BUILD_AT/apps/kleo/config/kleo.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 source ~/.bash_env set -e # fail if any command fails (recommended) # gather assets cd '$BUILD_AT/apps/kleo' mkdir -p priv/static cd assets && npm install && ./node_modules/brunch/bin/brunch build --production cd .. # run your custom task APP='$APP' MIX_ENV='$TARGET_MIX_ENV' $MIX_CMD do deps.get, phx.digest $SILENCE " }
  9. Putting it Together <update VERSION.txt> $ mix edeliver build release

    $ mix edeliver deploy release to production --version=<VERSION> --start-deploy
  10. Putting it Together <update VERSION.txt> $ mix edeliver build release

    $ mix edeliver deploy release to production --version=<VERSION> --start-deploy
  11. Gettin’ Fancy <update VERSION.txt> $ mix edeliver build release $

    mix edeliver deploy release to production --version=<VERSION> --start-deploy $ rel/deploy.rb
  12. Is this Right for You? • is this your first

    Elixir app? • do you need high uptime and server redundancy? • do you want containerization?
  13. Why Don’t I…? • no clustering avoids distributing data •

    no downtime requirements • plenty of capacity for load • Docker doesn’t add much benefit for additional complexity