Deploying Elixir

Deploying Elixir

Martin Kavalar @mkvlr and me talking about production experience of deploying Elixir projects.

64afebe5db598b0b043f35560bf940df?s=128

Martin Schürrer

April 24, 2015
Tweet

Transcript

  1. Martin Kavalar @mkvlr Martin Schurrer @msch Deploying Elixir

  2. PSPDFKit

  3. None
  4. None
  5. None
  6. OTP Applications

  7. def application do [applications: [:logger], mod: {BoldPoker, []}] end

  8. defmodule BoldPoker do use Application def start(_type, _args) do import

    Supervisor.Spec children = [ worker(BP.TableManager, []), supervisor(BP.Client.Supervisor, []), supervisor(BP.Table.Supervisor, []) ] opts = [strategy: :one_for_one] Supervisor.start_link(children, opts) end end
  9. iex> :observer.start

  10. iex> :observer.start

  11. OTP Releases

  12. ‣ rebar ‣ relx ‣ exrm

  13. % mix release ==> Building release with MIX_ENV=prod. ==> Generating

    relx configuration... ==> Generating sys.config... ==> Generating boot script... ==> Performing protocol consolidation... ==> Generating revision file ==> Generating release... ==> Generating nodetool... ==> Deleting revision file ==> Packaging release... ==> The release for boldpoker_game-1.2.4 is ready!
  14. boldpoker_game-1.2.4.tar.gz ├── bin │ ├── boldpoker_game │ └── nodetool ├──

    erts-6.4 ├── lib │ ├── boldpoker_game-1.2.4 │ ├── cowboy-1.0.0 │ ├── elixir-1.0.4 │ ├── stdlib-2.4 │ └── ... └── releases ├── 1.2.4 └── RELEASES
  15. bin/boldpoker_game start bin/boldpoker_game attach bin/boldpoker_game stop

  16. Hot Code Upgrades

  17. 1. suspend processes 2. update code and state (code_change) 3.

    resume processes
  18. use GenServer def code_change(old_vsn, state, extra) do new_state = Map.put(state,

    :hand_history, []) {:ok, new_state} end
  19. None
  20. None
  21. You might want to write a few scripts to automate

    this.
  22. None
  23. % mix release ==> Building release with MIX_ENV=prod. ==> Generating

    relx configuration... ==> Generating sys.config... ==> Generating boot script... ==> Performing protocol consolidation... ==> Generating revision file ==> Generating release... ==> Generated .appup for boldpoker_game 1.2.4 -> 1.2.5 ==> relup successfully created! ==> Generating nodetool... ==> Deleting revision file ==> Packaging release... ==> The release for boldpoker_game-1.2.5 is ready!
  24. {‘1.2.5', [{'1.2.4', [ {:load_module, Poker} ]}], [{'1.2.4', [ {:load_module, Poker}

    ]}] } appup
  25. {'1.2.5', [{'1.2.4', [], [ {:load_object_code, {:bp_game, '1.2.5', [Poker]}}, :point_of_no_return, {:load,

    {Poker, :brutal_purge, :brutal_purge}} ]}], [{'1.2.4', [], [ {:load_object_code, {:bp_game, '1.2.4', [Poker]}}, :point_of_no_return, {:load, {Poker, :brutal_purge, :brutal_purge}} ]}] } relup
  26. {‘1.2.5', [{'1.2.4', [ {:update, BoldPoker.Table, {:advanced, []}}, [{'1.2.4', [ {:update,

    BoldPoker.Table, {:advanced, []}}, ]}] } appup
  27. {'1.2.5', [{'1.2.4', [], [{:load_object_code, {:bp_game, '1.2.5', [BP.Table]}}, :point_of_no_return, {:suspend, [BP.Table]},

    {:load, {BP.Table, :brutal_purge, :brutal_purge}}, {:code_change, :up, [{BP.Table, []}]}, {:resume, [BP.Table]} ]}], [{'1.2.4', [], [{:load_object_code, {:bp_game, '1.2.4', [BP.Table]}}, :point_of_no_return, {:suspend, [BP.Table]}, {:code_change, :down, [{BP.Table, []}]}, {:load, {BP.Table, :brutal_purge, :brutal_purge}}, {:resume, [BP.Table]} ]}]} relup
  28. boldpoker_game-1.2.5.tar.gz ├── bin │ ├── boldpoker_game │ └── nodetool ├──

    erts-6.4 ├── lib │ ├── boldpoker_game-1.2.4 │ ├── boldpoker_game-1.2.5 │ ├── elixir-1.0.4 │ ├── stdlib-2.4 │ └── ... └── releases ├── 1.2.4 ├── 1.2.5 ├── RELEASES └── start_erl.data
  29. None
  30. 1. Have previous release available 2. mix release
 → boldpoker_game-1.2.5.tar.gz

    3. Server: mkdir -p releases/1.2.5 4. Put the .tar.gz into releases/1.2.5/ boldpoker_game.tar.gz 5. bin/boldpoker_game upgrade "1.2.5"
  31. Out of scope for those tools • Where do I

    store my previous releases so I can build the upgrades? • Releases include native code, no way to cross- compile • Deployment to multiple servers?
  32. None
  33. Production Staging Build Host Developer
 with edeliver Release Store
 S3

  34. defp deps, do: [ { :edeliver, github: "boldpoker/edeliver" } ]

    end mix.exs
  35. APP="boldpoker_game" BUILD_HOST="builder.boldpoker.net" BUILD_USER="deploy" BUILD_AT="~/build/boldpoker_game" RELEASE_STORE="s3://ACCESS_KEY:SECRET_ACCESS_KEY@bucket" PRODUCTION_HOSTS="app1.boldpoker.net app2.boldpoker.net" PRODUCTION_USER="deploy" DELIVER_TO="/srv/boldpoker-game/" .deliver/config

  36. % ./edeliver build release Using local release store. BUILDING RELEASE

    OF BOLDPOKER_GAME APP ON BUILD HOST -----> Authorizing hosts -----> Ensuring hosts are ready to accept git pushes -----> Pushing new commits with git to: msch@localhost -----> Resetting remote hosts to 7d02ecd8a -----> Stashing build directory on remote build host -----> Fetching / Updating dependencies -----> Compiling sources -----> Generating release -----> Copying release to local release store -----> Copying boldpoker_game-1.2.0.tar.gz to release store RELEASE BUILD OF BOLDPOKER_GAME WAS SUCCESSFUL!
  37. Build Host Developer
 with edeliver Release Store
 S3/scp

  38. % ./edeliver deploy release to production --version=1.2.0 Using local release

    store. DEPLOYING RELEASE OF BOLDPOKER_GAME APP TO PRODUCTION HOSTS -----> Authorizing hosts -----> Uploading archive of release 1.2.0 from local release store -----> Extracting archive boldpoker_game_1.2.0.tar.gz DEPLOYED RELEASE TO PRODUCTION!
  39. Production Developer
 with edeliver Release Store
 S3/scp

  40. % ./edeliver start production Using local release store. EDELIVER BOLDPOKER_GAME

    WITH START COMMAND -----> starting production servers production node: user : msch host : localhost path : /opt/boldpoker-game/ Connection to localhost closed. START DONE!
  41. Production Developer
 with edeliver

  42. % ./edeliver build upgrade --from=1.2.0 Using local release store. BUILDING

    UPGRADE OF BOLDPOKER_GAME APP ON BUILD HOST -----> Authorizing hosts -----> Validating * version 1.2.0 is in local release store -----> Ensuring hosts are ready to accept git pushes -----> Pushing new commits with git to: msch@localhost -----> Resetting remote hosts to 896d81a67 -----> Stashing build directory on remote build host -----> Checking out 896d81a676df3c477689d2c72c5562d5edcf1999 -----> Fetching / Updating dependencies -----> Compiling sources -----> Uploading archive of release 1.2.0 from local release store -----> Extracting archive boldpoker_game_1.2.0.tar.gz -----> Generating release -----> Copying release to local release store -----> Copying boldpoker_game-1.2.4.tar.gz to release store UPGRADE BUILD OF BOLDPOKER_GAME WAS SUCCESSFUL!
  43. % ./edeliver deploy upgrade to production Using local release store.

    DEPLOYING UPGRADE OF BOLDPOKER_GAME APP TO PRODUCTION HOSTS -----> Authorizing hosts -----> Uploading archive of release 1.2.4 from local release store -----> Upgrading release to 1.2.4 DEPLOYED UPGRADE TO PRODUCTION!
  44. None
  45. Outlook ‣ fetch version from server ‣ continuous deployment

  46. Outlook ‣ Slack Integration ‣ Phoenix Web Interface ‣ Upgrade

    Testing
  47. github.com/boldpoker/edeliver github.com/boldpoker/edeliver Thank you! Questions? Martin Kavalar @mkvlr Martin Schurrer

    @msch