Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Step 5: Remote Deployment with Gigalixir #5

Merged
merged 8 commits into from
Mar 4, 2019
Merged

Conversation

joeyrosztoczy
Copy link
Owner

@joeyrosztoczy joeyrosztoczy commented Mar 1, 2019

It's time to ship our software to somewhere it can be useful! We'll abstract most of our remote deployment tooling / devops by using Gigalixir!

Gigalixir is a platform as a service for hosting Elixir applications and others. We're using it for a few key benefits here:

  1. We get a free server + db instance for use with the example ^^.

  2. Gigalixir uses k8s behind the scenes, so we'll get a peak at plumbing our Elixir application throughout k8s via libcluster. Even if you're just distributing Elixir nodes, libcluster can be helpful.

  3. Gigalixr allows for a pluggable backend, and slightly decouples our application from a cloud provider, so if you're using this as a starter project, you get that benefit in the future.

Interesting files:
rel/config.exs (refactored to use a Mix Config Provider)
rel/config/config.exs (added configuration for libcluster to automate cluster formation through k8s, with a setting for local testing with EPMD)

@@ -0,0 +1,5 @@
cd $assets_dir
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because Gigalixir's default compile script uses brunch, but we're using Phoenix 1.4, we can use a custom static asset compile script here to use webpack:

https://github.com/gjaldon/heroku-buildpack-phoenix-static#compile

@@ -25,6 +24,17 @@ config :logger, :console,
# Use Jason for JSON parsing in Phoenix
config :phoenix, :json_library, Jason

# Add a base libcluster config for Epmd (erlang distribution protocol)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This basically lets us test a release locally without k8s, keeping everything else equal w/ concerns to libcluster & cluster initialization.

cache_static_manifest: "priv/static/cache_manifest.json",
code_reloader: false,
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's worth noting for the purposes of a release, this all gets overwritten in rel/config/config.exs. That being said, I think its really valuable to be able to mirror a pure dev environment (i.e. with Mix only) with the release setup.

@@ -0,0 +1,70 @@
defmodule GoldenPath.ReleaseTasks do
Copy link
Owner Author

@joeyrosztoczy joeyrosztoczy Mar 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is an example task within a release that can be used remotely. Since we can't use "mix bah", we could ssh into a remote shell and run a migrate command.

Gigalixir provides a proxy command for us via $ gigalixir ps:migrate, but since this is probably one of the more common needed commands, it's provided as an example.

@@ -56,7 +56,8 @@ defmodule GoldenPath.MixProject do
{:excoveralls, "~> 0.8", only: :test},
{:credo, "~> 1.0", only: [:dev, :test], runtime: false},
{:dialyxir, "~> 1.0.0-rc.4", only: [:dev], runtime: false},
{:distillery, "~> 2.0"}
{:distillery, "~> 2.0"},
{:libcluster, "~> 3.0.3"}
Copy link
Owner Author

@joeyrosztoczy joeyrosztoczy Mar 1, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Liblcuster is used primarily to allow Erlang VM to self-heal / distribute itself in a Kubernetes environment (which Gigalixir uses), but has some useful properties even for Elixir/Erlang only node clusters.

To learn more about libcluster, checkout out the libary repo and this blog post I wrote about it: https://medium.com/@TehBrofessor/whats-going-on-in-libcluster-76f239f00d57

]
)

set(
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is basically a wonderful runtime Config Provider that allows us to use mix like terminology within a release, see here for more:

https://hexdocs.pm/distillery/config/runtime.html

topologies: [
k8s_example: [
strategy: Cluster.Strategy.Kubernetes,
config: [
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The basename's and selectors are provided as env variables by Gigalixir, allowing us to plumb through k8s and connect our nodes (initially, the first node we'll connect is a "hidden" local node to run Observer).

The hidden node allows us to connect to our cluster, without disturbing the runtime (i.e. having local processes impact the production system).

Official docs description of a hidden node: http://erlang.org/doc/reference_manual/distributed.html#hidden-nodes

@joeyrosztoczy joeyrosztoczy merged commit fec63a6 into master Mar 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant