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

recap elixir deployment #61

Merged
merged 8 commits into from
Nov 10, 2022
Merged

recap elixir deployment #61

merged 8 commits into from
Nov 10, 2022

Conversation

SimonLab
Copy link
Member

@SimonLab SimonLab commented Jun 3, 2020

ref: #59

An initial markdown where I recap my research on how to deploy a Phoenix application on Linode

Similar to Heroku [Gigalixir](https://www.gigalixir.com/) provides
a platform which focus on deploying Elixir/Phoenix application.

Deploying: https://elixircasts.io/deploying-with-gigalixir-%28revised%29
Copy link
Member

Choose a reason for hiding this comment

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

👍

From there the idea is install Erlang and Elixir on the server
and then to run the application.

- Install Erlang/Elixir with asdf:
Copy link
Member

Choose a reason for hiding this comment

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

@SimonLab as previously noted dwyl/phoenix-liveview-counter-tutorial#17 (comment) please don't introduce a completely new way of managing dependencies without giving some context. This is the first mention of asdf in any file in the dwyl org.

If you want to propose using asdf https://github.com/asdf-vm/asdf as a version manager, and I have nothing against it in principal, it's as simple as opening an issue. see: dwyl/technology-stack#18
Dropping a random tool into a doc without any context is not beginner friendly and sets an undesirable example to others who may think they can add any dependency they like.

- `git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.7.8`
- Edit `~/.bashrc file` and add `. $HOME/.asdf/asdf.sh` and run `source ~/.barhrc` to access the `asdf` command
- Install required pacakges for Erlang `sudo apt install libssl-dev make automake autoconf libncurses5-dev gcc`
- Add erlang plugin to asdf: `asdf plugin-add erlang`
Copy link
Member

Choose a reason for hiding this comment

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

If we are using Linux as our Host OS then we 100% do not need to install Erlang/Elixir on the VM.
We can use Travis-CI which runs Ubuntu 18.04 ("Bionic") https://docs.travis-ci.com/user/reference/bionic
to build the package using distiliery and deploy it to the VM using edeliver.

And as soon as Ubuntu 20.04 Focal becomes available on Travis-CI we can upgrade! Right now only 18.04 is supported as noted in: internetarchive/openlibrary#3407 (comment)
I fear that I may not have fully explained "Continuous Integration + Continuous Deployment" in the issue ... #59 💭
Perhaps I should have been more explicit that we would be following the "12 Factor App" best practices and separating the "Build Phase" from the "Run Phase" see: https://12factor.net/build-release-run
This strict separation ensures that there is no way to modify the code on the production VM which dramatically enhances security because it almost eliminates the risk of arbitrary code execution (at least from the Erlang/Elixir perspective).

The whole point is that our Continuous Integration server (Travis-CI) does the testing and build phase and then just ships an executable binary of the application to the Linode VM. We definitely don't want to be installing (and thus having to manage/maintain) asdf then erlang and elixir on the VM if we don't absolutely need to.

We already demonstrated how to build and deploy a Phoenix App to a VM using distillery and edeliver:
https://github.com/dwyl/learn-microsoft-azure#deploy-your-phoenix-web-app-using-edeliver
When we shipped Healthlocker to Azure in 2017.
See: https://github.com/healthlocker/healthlocker/blob/master/.deliver/config and: .travis.yml#L33-L35
This worked without any issues and we spent a lot of time documenting all the scripts. e.g .deliver/version.sh

The only reason I did not specify using edeliver in the issue was because I wanted there to be a "fresh eyes" investigation into the best way of doing Phoenix deployment to a VPS in 2020. Installing the Erlang on the VPS and building the project on the production server is definitely not the way we want to do it. The "right" way of doing this is to build the release (binary) on Travis-CI (using someone else's compute time that they have generously provided for free!) and uploading it to S3 so that we have a full history of all our release objects. Then deploy the release to the VPS which does not have Erlang or anything unnecessary installed on it. By minimising the number of programs installed on the VM we minimise maintenance and simplify our lives. The moment we introduce a new tool (e.g. asdf) we need to understand the security+maintenance implications. If the asdf tool is installing any dependencies or running arbitrary shell scripts, who is responsible for ensuring that it's not doing something undesirable (malicious) like opening a TCP port or leaking credentials? Where is asdf sourcing it's binaries for erlang and elixir from? Who has control over them? Is there a security audit? Who is Trevor Brown and why should I trust them? He seems like a "nice guy" https://www.linkedin.com/in/trevor-brown-11136938/ but how do we know he is following security best practices cannot be "spearphished", pwned and infect all the servers running asdf?

P.S. sorry to be a pain about this in the in the PR review, I should have made it clearer in the issue.
12 Factor App. Don't install build dependencies on the Production Server. 👍

- Install Elixir: `asdf install elixir latest`
- Define which Elixir version to use `asdf global elxir <version>`

- Instsall Nodejs using nvm
Copy link
Member

Choose a reason for hiding this comment

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

We definitely don't want to install node.js or any of the node build dependencies on the Production Server.
This is a massive attack vector that would allow an attacker who successfully compromised one of the thousands of dependencies in the package-lock.json file to create a postinstall script that leaks our AWS, DB or Encryption keys to a remote server.
My (security mindset) reasoning for wanting to use OpenBSD on the Production server to minimise the number of attack vectors would be completely negated by installing node.js on the VPS.

I tolerate running Node.js on my localhost because I still maintain a bunch of NPM packages,
but I definitely don't want to run Node.js on my Server unless I have to (e.g. because the Application is written in JS...)

I can see that Linode (or similar) can be on a longer term a better tool
to manage the applications.

The simple deployement used above with Ubuntu works well,
Copy link
Member

Choose a reason for hiding this comment

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

To be clear, the instructions given above are not a "Deployment" they are a "build and run on the server". That is exactly what we don't want to do and we definitely don't want to advise other people to do it that way.

Copy link
Member

@nelsonic nelsonic left a comment

Choose a reason for hiding this comment

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

@SimonLab most of the background in this doc is OK.
But the whole section on deployment to a Linode on Ubuntu needs to be re-written.
We are definitely not going to manually install asdf, erlang, elixir and node.js on a Production Server. We need to be using mix release to create an executable and deploying that to the VPS.

@nelsonic nelsonic assigned SimonLab and unassigned nelsonic Jun 4, 2020
Copy link
Member

@nelsonic nelsonic left a comment

Choose a reason for hiding this comment

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

Merging for historical reference. 📚
But we now deploy to Fly.io 👌

@nelsonic nelsonic merged commit 5954365 into main Nov 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants