What is the best way to deploy a Phoenix application to EC2 or Digital Ocean?

What is the best way to deploy a Phoenix application to EC2 or Digital Ocean - to Ubuntu box?
I found this article Deploy Phoenix to Ubuntu VPS - Server Preparation | Devato - it is working. However, both the libraries mentioned edeliver and distillery have not been updated in the last 2 years. Further, the Phoenix documentation at Introduction to Deployment — Phoenix v1.5.9 did not mention either of the libraries.
I would want to deploy the entire application to one EC2 instance ( including Postgresql). What is the best way to do that? Does Docker provide a better way?
Confused. Soliciting views and pointers.
Thanks.

I’ve been using fly.io for a while now and it has been working great, they also have a really detailed guide for deploying Elixir apps.

Edit: Sorry, totally ignored the question! Might be worth a look though :slight_smile:

1 Like

Hard to answer the question without you specifying more details about what you mean by “best”. How do you measure that? Most control? No maintenance? Ease of setup? Cost?

I’m really happy with deploying a Phoenix app to DigitalOcean App Platform: I use Docker + mix release. Simple to setup, no maintenance, handles HTTPS for you, quite cheap also.

3 Likes

Agree @stefanchrobot. Question was incomplete. I meant - a single developer - idea is not just POC - one step above. :slight_smile: So, low maintenance, low cost are the first two characteristics. Third important one is - I have some credits with AWS.
So, the question should have been how to deploy Phoenix Application to EC2 instance? Due to cost aspect, I want to put both DB and App on single instance.

I’ve recently switched back to dedicated servers from gigalixir for a bunch of our apps and just went with mix release and systemd for running them.

For handling updates I have a rebuild script in all my app directories that basically does a git pull, mix deps.update, compiles the assets for phoenix apps and mix release then restarts the systemd service.

Then I have a really basic github action that sshs to the server and runs the script.

It’s been running well across the board for me so far with no real issues and it’s really easy to roll up a new server.

Scripts I use(definitely taken from someones blog post but I cannot find a source right now so if it’s yours let me know and I’ll add a link)

#!/usr/bin/env bash
# exit on error
set -o errexit
. /home/ubuntu/.asdf/asdf.sh
. /home/ubuntu/.asdf/completions/asdf.bash
cd /home/ubuntu/appname
git checkout .
git pull

mix local.hex --force
mix local.rebar --force

mix deps.get
MIX_ENV=prod mix compile

npm install --prefix ./assets
npm run deploy --prefix ./assets
mix phx.digest

MIX_ENV=prod mix release --overwrite

sudo service appname restart

and systemd

[Unit]
Description=AppName
After=local-fs.target network.target

[Service]
Type=simple
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/appname/_build/prod/rel
ExecStart=/home/ubuntu/appname/_build/prod/rel/appname/bin/appname start
ExecStop=/home/ubuntu/appname/_build/prod/rel/appname/bin/appname stop
EnvironmentFile=/etc/default/appname.env
Environment=LANG=en_US.utf8
Environment=MIX_ENV=prod


Environment=PORT=4001
LimitNOFILE=65535
UMask=0027
SyslogIdentifier=appname
Restart=always


[Install]
WantedBy=multi-user.target

I use a releases.exs config and put all my env stuff in /etc/default

the github action

name: Deploy Appname
on:
  push:
    branches: [ master ]
jobs:
  job_one:
    name: Deploy
    runs-on: ubuntu-latest
    steps:
    - name: run deploy script
      uses: garygrossgarten/github-action-ssh@release
      with:
        host: myserver.com
        username: ubuntu
        privateKey: ${{ secrets.APP_SECRET }}
        command: /home/ubuntu/appname/rebuild.sh

I also have ansible setup for some of my apps which are located on multiple servers though the only difference between that and the single server setup is it is ansible running the rebuild script not github.

9 Likes