Github Workflow

Skript som setter opp en virtuell maskin og dytter nyeste oppdateringene til serveren. Deretter aktiverer workflowen et build.sh bash-skript (se nedenfor).

.github/workflows/build-website.yml

 1name: build site
 2
 3on:
 4  push:
 5    paths:
 6      - 'Prototypes/web/**'
 7      - '.github/workflows/**'
 8
 9jobs:
10  deploy: 
11    runs-on: ubuntu-latest
12
13    steps:
14      - name: get repo web
15        uses: actions/checkout@v4
16      
17      - name: setup ssh
18        run: |
19          mkdir -p ~/.ssh
20          echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
21          chmod 600 ~/.ssh/id_rsa
22          ssh-keyscan -H ${{ vars.SERVER_IP }} >> ~/.ssh/known_hosts
23        env:
24          SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
25
26      - name: copy files
27        env:
28          MQTT_ADMIN_USERNAME: ${{ secrets.MQTT_ADMIN_USERNAME }}
29          MQTT_ADMIN_PASSWORD: ${{ secrets.MQTT_ADMIN_PASSWORD }}
30          FLASK_SECRET_KEY: ${{ secrets.FLASK_SECRET_KEY }}
31        run: |
32          rsync -avz --delete -e "ssh -i ~/.ssh/id_rsa" Prototypes/web/ gruppe1@${{ vars.SERVER_IP }}:/srv
33          ssh -i ~/.ssh/id_rsa gruppe1@${{ vars.SERVER_IP }} 'cat <<EOF > /srv/.env
34          MQTT_ADMIN_USERNAME=${{ secrets.MQTT_ADMIN_USERNAME }}
35          MQTT_ADMIN_PASSWORD=${{ secrets.MQTT_ADMIN_PASSWORD }}
36          FLASK_SECRET_KEY=${{ secrets.FLASK_SECRET_KEY }}
37          EOF'
38          
39      - name: make executable
40        run: ssh -i ~/.ssh/id_rsa gruppe1@${{ vars.SERVER_IP }} 'chmod +x /srv/build.sh'
41
42      - name: run build script
43        run: ssh -i ~/.ssh/id_rsa gruppe1@${{ vars.SERVER_IP }} 'bash /srv/build.sh'

Bash-script

Skript som restarter tjenester og sørger for at python er oppdatert og kjører i riktig miljø.

build.sh

 1#!/bin/bash
 2
 3# move new files if modified
 4sudo rsync -av /srv/app/static/index.html /var/www/html/index.html
 5sudo rsync -av /srv/nginx/default /etc/nginx/sites-enabled/default
 6sudo rsync -av /srv/services/gunicorn.service /etc/systemd/system/gunicorn.service
 7sudo rsync -av /srv/services/pymqtt.service /etc/systemd/system/pymqtt.service
 8sudo rsync -av --delete /srv/mosquitto/ /etc/mosquitto/conf.d/
 9
10prj_path="/srv"
11venv="${prj_path}/venv"
12requirements="${prj_path}/requirements.txt"
13
14if [ ! -d "$venv" ]; then
15    echo "no venv found trying to setup venv"
16    if [ ! -f "$requirements" ]; then
17        echo "no requirements file exiting"
18        exit 1
19    else
20        echo "found requirements.txt setting up venv"
21        python3 -m venv $venv
22        echo "installing requirements.txt"
23        source $venv/bin/activate
24        pip3 install -r $requirements
25    fi
26fi
27
28echo "create db"
29source $venv/bin/activate
30python3 /srv/db/setup_database.py
31
32sudo systemctl daemon-reload
33
34sudo systemctl restart pymqtt
35sudo systemctl restart mosquitto
36sudo systemctl restart gunicorn
37sudo systemctl restart nginx
38echo "completed build"

Database

Enkelt python-script som setter opp test-data til nettsiden.

db/setup_database.py

 1from tinydb import TinyDB
 2import os
 3
 4base_dir = os.path.dirname(os.path.abspath(__file__))
 5nfctag_db_path = os.path.join(base_dir, "nfctags.json")
 6
 7
 8if not os.path.exists(nfctag_db_path):
 9    os.makedirs(os.path.dirname(nfctag_db_path), exist_ok=True)
10    db = TinyDB(nfctag_db_path)
11    db.insert({"nfctagID": "nfctag1", "poiID": 303578, "audio_filename": "someplace.opus"})
12    db.insert({"nfctagID": "33F55B03", "poiID": 36148, "audio_filename": "bober.opus"})
13    db.insert({"nfctagID": "83C7E411", "poiID": 1000459343, "audio_filename": "tapirbygget.opus"})
14    db.insert({"nfctagID": "93C0930D", "poiID": 1000319015, "audio_filename": "sentralbygget.opus"})
15else:
16    print("nfctagdb already exists")
17
18#https://use.mazemap.com/#v=1&campusid=1&zlevel=2&center=10.405620,63.418025&zoom=19&sharepoitype=poi&sharepoi=1000459343 tapirbygget
19#https://use.mazemap.com/#v=1&campusid=1&zlevel=3&center=10.405620,63.418025&zoom=19&sharepoitype=poi&sharepoi=36148 bober
20#https://use.mazemap.com/#v=1&campusid=1&zlevel=1&center=10.403742,63.417721&zoom=19.6&sharepoitype=poi&sharepoi=1000319015 sentralbygget
21
22uuid_db_path = os.path.join(base_dir, "uuids.json")
23
24if not os.path.exists(uuid_db_path):
25    print("creating uuid-db")
26    os.makedirs(os.path.dirname(uuid_db_path), exist_ok=True)
27    db = TinyDB(uuid_db_path)
28    r, g, b = 128, 184, 180
29    db.insert({"uuid": "123e4567-e89b-12d3-a456-426614174000", "color": f"#{r:02x}{g:02x}{b:02x}"})
30    r, g, b = 134, 181, 124
31    db.insert({"uuid": "123e4567-e89b-12d3-a456-426614174002", "color": f"#{r:02x}{g:02x}{b:02x}"})
32else:
33    print("uuiddatabase already exists")
34

Oppstart

Gunicorn kaller denne filen for å starte web-appen.

production.py

1from app import create_app
2from werkzeug.middleware.proxy_fix import ProxyFix
3
4app = create_app()
5app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1, x_proto=1, x_host=1, x_prefix=1)