Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save hafizio/a55263fc164c111743fc957cb37d0435 to your computer and use it in GitHub Desktop.
Save hafizio/a55263fc164c111743fc957cb37d0435 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

@hafizio
Copy link
Author

hafizio commented Oct 13, 2016

@hafizio
Copy link
Author

hafizio commented Oct 13, 2016

sudo MIX_ENV=prod mix do compile, phoenix.digest, release --env=prod --verbose
to solve the issue of not building a release. maybe i was using sudo in mix gatling?

@hafizio
Copy link
Author

hafizio commented Oct 13, 2016

@hafizio
Copy link
Author

hafizio commented Oct 16, 2016

The main issue is the port variable was empty (harcode it in the prod.exs) and also sudo permission to run mix release in production.

sudo mix release --upgrade --upfrom=0.0.1476606097 --env=prod

remove warning as error option (it prevents compilation)

@hafizio
Copy link
Author

hafizio commented Oct 17, 2016

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

@hafizio
Copy link
Author

hafizio commented Oct 17, 2016

@hafizio
Copy link
Author

hafizio commented Oct 18, 2016

to kill bind to 80
sudo fuser -k 80/tcp

@hafizio
Copy link
Author

hafizio commented Oct 18, 2016

@hafizio
Copy link
Author

hafizio commented Oct 18, 2016

@hafizio
Copy link
Author

hafizio commented Oct 18, 2016

sudo chmod 400 /etc/letsencrypt/live/hafiz.postco.com.my/privkey.pem
sudo chmod 400 /etc/letsencrypt/live/hafiz.postco.com.my/fullchain.pem

@hafizio
Copy link
Author

hafizio commented Oct 18, 2016

sudo chmod -R 755 /etc/letsencrypt/live

sudo chmod 755 -R /etc/letsencrypt/archive/

@hafizio
Copy link
Author

hafizio commented Oct 18, 2016

sudo rel/postco_plugin/bin/postco_plugin foreground

missing sudo will cause tonne of prob

@hafizio
Copy link
Author

hafizio commented Oct 18, 2016

http://stackoverflow.com/questions/37216626/elixir-phoenix-production-server-has-issue-with-letsencrypt-renewal

use priv folder to setup the lets encrypt folder (avoid using let's enctyp folder)

@hafizio
Copy link
Author

hafizio commented Oct 19, 2016

sudo nginx -t

prev setup:

server {
    #listen 80 default_server;
    #listen [::]:80 default_server;
    #listen 443 ssl http2 default_server;
    #listen [::]:443 ssl http2 default_server;

    #server_name hafiz.postco.com.my;
    #include snippets/ssl-hafiz.postco.com.my.conf;
    #include snippets/ssl-params.conf;

    root /var/www/html;
    index index.html index.htm index.nginx-debian.html;

        location ~ /.well-known {
                allow all;
        }
}

@hafizio
Copy link
Author

hafizio commented Oct 19, 2016

kill all the process redeploy and start the process again

@hafizio
Copy link
Author

hafizio commented Oct 19, 2016

sudo systemctl status nginx

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