Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 18 You must be signed in to star a gist
  • Fork 10 You must be signed in to fork a gist
  • Save davoclavo/61b9d84f2248f182c95ae7738490ddd1 to your computer and use it in GitHub Desktop.
Save davoclavo/61b9d84f2248f182c95ae7738490ddd1 to your computer and use it in GitHub Desktop.
Getting Elixir / Phoenix running on Digital Ocean with edeliver

Build Server

  • Go to Digital Ocean
  • Create new ubuntu droplet

Setup Server

  • ssh root@<droplet ip>
  • Create deploy user
    • sudo adduser deploy
    • add deploy to sudo group: sudo adduser deploy sudo
    • add passwordless sudo: visudo -> s/%sudo ALL=(ALL:ALL) ALL/%sudo ALL=NOPASSWD: ALL
    • copy SSH public keys: find .ssh -print | cpio -pdmv --owner=deploy ~deploy
    • su deploy
  • sudo apt-get -y install git
  • wget https://packages.erlang-solutions.com/erlang-solutions_1.0_all.deb && sudo dpkg -i erlang-solutions_1.0_all.deb
  • sudo apt-get update
  • sudo apt-get install -y elixir
  • sudo apt-get install -y esl-erlang
  • mix local.hex
  • mix archive.install https://github.com/phoenixframework/archives/raw/master/phoenix_new.ez
  • curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -
  • sudo apt-get install -y nodejs
  • sudo mkdir /opt && sudo chmod -R 777 /opt
  • sudo mkdir /git && sudo chmod -R 777 /git

Setup EDeliver Project

  • add edeliver dependency (pointing to master branch on GH for now...): {:edeliver, git: "https://github.com/boldpoker/edeliver.git"}
  • comment import_config "prod.secret.exs"
  • add :edeliver to applications list
  • mix deps.get
  • mix deps.compile
  • create .deliver/config file
  • populate config file with the following:
#!/usr/bin/env bash

APP="my_awesome_app" # name of your release

BUILD_HOST="server ip / hostname" # host where to build the release
BUILD_USER="deploy" # local user at build host
BUILD_AT="/git/my_awesome_app/builds" # build directory on build host
RELEASE_DIR="/git/my_awesome_app/builds/rel/my_awesome_app"

STAGING_HOSTS="server ip / hostname" # staging / test hosts separated by space
STAGING_USER="git" # local user at staging hosts
TEST_AT="/test/my_awesome_app" # deploy directory on staging hosts. default is DELIVER_TO

PRODUCTION_HOSTS="server ip / hostname" # deploy / production hosts separated by space
PRODUCTION_USER="deploy" # local user at deploy hosts
DELIVER_TO="/opt/my_awesome_app" # deploy directory on production hosts

Establish Production Config

We will be using env vars in your config/prod.exs Make sure to add server: true as we are building a release. Also add check_origin: false if you want to allow websockets from any origin.

config :my_awesome_app, MyAwesomeApp.Endpoint,
  http: [port: {:system, "PORT"}],
  url: [host: System.get_env("HOSTNAME"),
  server: true,
  check_origin: false
...
# import_config "prod.secret.exs"
config :my_awesome_app, MyAwesomeApp.Endpoint,
  secret_key_base: System.get_env("SECRET_KEY_BASE")

Set up environment vars in build host

Add env variables to ~/.profile

export PORT=4000
export HOSTNAME="your-website.com or ip"
export SECRET_KEY_BASE="<generate one using `mix phoenix.gen.secret`>"
```

Bind privileged ports
===========

Forward port 80 to 4000. [Source](http://zotonic.com/docs/0.x/developer-guide/deployment/privilegedports.html)
TODO: Would be cool to instead use `authbind` with edeliver to avoid opening the non-privileged port as well

```
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to 4000
```

Build On Server
============

- `mix edeliver build release --verbose` in case of error, try: `mix edeliver build release --verbose --skip-mix-clean`
- `mix edeliver deploy release to production --verbose`
- `mix edeliver start production --verbose`

double check that everything is running at your-ip:4000
In order to troubleshoot ssh into the prod host and look at the /opt/app/app/log files

@OpsCaptain
Copy link

For those not comfortable on the linux command line or without much experience, you could use a tool like OpsCaptain to deploy elixir, phoenix apps to your droplet. Simply buy a droplet or a server from Vultr, Linode etch and provide OpsCaptain root access to the droplet and download the OpsCaptain CLI and run [opscaptain deploy] to push your app. OpsCaptain takes care of everything for you so you do not have to do all that is written above. Under the hood, OpsCaptain uses Docker and the Open source elixir buildpack. You can learn more and get started here:
https://www.opscaptain.com/elixir-phoenix-hosting

@alxvallejo
Copy link

Don't you need a "DATABASE_URL" var? Where would you put that?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment