Hi everyone,
Here is a small article on how I successfully deployed my Django application through Github actions. Basically, what I needed was pretty simple, as soon as I push a new commit (on master), I want to:
- connect through SSH on my remote server
- restart my
cfptime
service (which will do all the magic)
My cfptime.org project is something like ~3 years old and at the beginning, I was deploying by hand and I created a bash script in order to ease this part and this is what it looked like:
#!/bin/bash
cd /path/to/cfptime
git pull
source env/bin/activate
python manage.py makemigrations;
python manage.py migrate;
python manage.py collectstatic --noinput;
gunicorn --access-logfile - --workers 1 --bind unix:/path/to/cfptime/cfptime.sock cfptime.wsgi:application
By using a socket file (cfptime.sock), I can access it locally without having to open a port (even on the localhost). A bit off-topic but my nginx configuration file looks like this:
server {
listen 443;
server_name api.cfptime.org;
location /static/ {
alias /path/to/cfptime/cfptime/static/;
}
location / {
proxy_pass http://unix:/path/to/cfptime/cfptime.sock:/;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Host $server_name;
}
location = / {
return 301 https://api.cfptime.org/api/docs;
}
}
Later on, I created a systemd service allowing me to restart the service even more easily:
[Unit]
Description=CFP Time daemon
After=network.target
[Service]
User=www-data
Group=www-data
WorkingDirectory=/path/to/cfptime
ExecStart=/path/to/cfptime/launch.sh
[Install]
WantedBy=multi-user.target
I was then able to restart automatically cfptime
with a simple: service cfptime restart
!
Finally, I used Github actions in order to restart my service automatically, which will:
- Pulls the code from Github
- Performs all Django migrations (if applicable)
- Collect static files (if applicable)
- And finally, restart the app :)
My Github action looks like this:
name: remote ssh command
on: [push]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: executing remote ssh commands using password
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.USER }}
key: ${{ secrets.PRIVATE_KEY }}
port: ${{ secrets.PORT }}
script: |
sudo service cfptime restart
In order to make this work, you just need to specify the HOST, USER, PRIVATE_KEY and PORT variables in your repository’s secrets and… you should be good to go!
Happy deployment :)