A git hook-based Phoenix deploy

This is what I did. Suggestions or improvements are welcome. Here I’m assuming the app is called my_app and it will run as app_user.

Create a bare git repository

ssh app_user@my_server
mkdir repo
cd repo
git init --bare

Create a post-receive hook /home/app_user/repo/hooks/post-receive with something like this

#!/bin/bash

echo "Updating code.."
git --work-tree=/home/app_user/app --git-dir=/home/app_user/repo checkout -f

cd /home/app_user/app
export SECRET_KEY_BASE="[whatever it is]"

echo "Updating dependencies..."
mix deps.get --only prod

echo "Compiling app..."
MIX_ENV=prod mix compile

echo "Updating JS dependencies.."
npm install --prefix ./assets

echo "Compiling assets..."
npm run deploy --prefix ./assets
mix phx.digest

echo "Building app..."
MIX_ENV=prod mix release --overwrite

echo "Restarting server..."
sudo systemctl restart my_app

echo "Done!"

Now make the bare repository a remote

git remote add production app_user@my_server:repo

You can now deploy with

git push production master

The service is handled by systemd. This is how the service is defined (/etc/systemd/system/my_app.service):

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

[Service]
Type=simple
User=app_user
Group=app_user
WorkingDirectory=/home/my_app/app/_build/prod/rel/my_app
ExecStart=/home/my_app/app/_build/prod/rel/my_app/bin/my_app start
ExecStop=/home/my_app/app/_build/prod/rel/my_app/bin/my_app stop
Environment=LANG=en_US.utf8
Environment=MIX_ENV=prod

Environment=PORT=4000
LimitNOFILE=65535
UMask=0027
SyslogIdentifier=my_app
Restart=always

[Install]
WantedBy=multi-user.target