-
Notifications
You must be signed in to change notification settings - Fork 0
Add automated production deployment #19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
2f2cd73
daad27a
0a09437
b31df0e
6f68469
3f8f2ae
ddc30a0
feb453c
3dc7981
fb32c5c
66735a0
c2ee65d
626e938
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| .git | ||
| .venv | ||
| venv | ||
| __pycache__ | ||
| *.pyc | ||
| .env | ||
| data/uploads | ||
| data/logs | ||
| models/*.whl | ||
| *.pt | ||
| *.dat | ||
| *.yml | ||
| *.yaml |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| MARIADB_DATABASE=proctoring | ||
| MARIADB_USER=proctor | ||
| MARIADB_PASSWORD=replace-with-a-long-random-password | ||
| MARIADB_ROOT_PASSWORD=replace-with-a-different-long-random-password | ||
| PROCTOR_SECRET_KEY=replace-with-a-long-random-secret | ||
| PROCTOR_DATABASE_URI=mysql+pymysql://proctor:replace-with-a-long-random-password@db:3306/proctoring | ||
| PROCTOR_MODEL_DIR=/app/models | ||
| PROCTOR_DATA_DIR=/app/data | ||
| PROCTOR_INFERENCE_DEVICE=auto | ||
| PROCTOR_LOG_LEVEL=INFO | ||
| PROCTOR_MAX_UPLOAD_SIZE=5242880 | ||
| PROCTOR_ALLOWED_HOSTS=localhost,127.0.0.1 | ||
| PROCTOR_BIND_ADDRESS=127.0.0.1 | ||
| PROCTOR_PORT=8000 | ||
| PROCTOR_FRAME_INTERVAL_MS=1000 | ||
| PROCTOR_FRAME_JPEG_QUALITY=75 | ||
| PROCTOR_FRAME_MAX_WIDTH=1280 | ||
| PROCTOR_FRAME_MAX_HEIGHT=720 | ||
| PROCTOR_ENABLE_AUDIO=true |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -5,6 +5,7 @@ on: | |
| branches: [main] | ||
| pull_request: | ||
| branches: [main] | ||
| workflow_call: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,79 @@ | ||
| name: Deploy Proctor | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| concurrency: | ||
| group: proctor-production | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| validate: | ||
| uses: ./.github/workflows/ci.yml | ||
|
|
||
| deploy: | ||
| name: Deploy to vps01 through IONOS | ||
| needs: validate | ||
| runs-on: ubuntu-latest | ||
| environment: production | ||
| steps: | ||
| - name: Configure SSH | ||
| env: | ||
| DEPLOY_SSH_KEY: ${{ secrets.DEPLOY_SSH_KEY }} | ||
| DEPLOY_KNOWN_HOSTS: ${{ secrets.DEPLOY_KNOWN_HOSTS }} | ||
| run: | | ||
| install -d -m 700 "$HOME/.ssh" | ||
| printf '%s\n' "$DEPLOY_SSH_KEY" > "$HOME/.ssh/proctor_deploy" | ||
| printf '%s\n' "$DEPLOY_KNOWN_HOSTS" > "$HOME/.ssh/known_hosts" | ||
| chmod 600 "$HOME/.ssh/proctor_deploy" "$HOME/.ssh/known_hosts" | ||
| eval "$(ssh-agent -s)" | ||
| ssh-add "$HOME/.ssh/proctor_deploy" | ||
| echo "SSH_AUTH_SOCK=$SSH_AUTH_SOCK" >> "$GITHUB_ENV" | ||
|
|
||
| - name: Pull, rebuild, and verify the production app | ||
| env: | ||
| DEPLOY_HOST: ${{ secrets.DEPLOY_HOST }} | ||
| DEPLOY_USER: ${{ secrets.DEPLOY_USER }} | ||
| VPS01_KNOWN_HOSTS: ${{ secrets.VPS01_KNOWN_HOSTS }} | ||
| APP_DIR: ${{ vars.PROCTOR_APP_DIR }} | ||
| run: | | ||
| ssh -A \ | ||
| -o BatchMode=yes \ | ||
| -o StrictHostKeyChecking=yes \ | ||
| "$DEPLOY_USER@$DEPLOY_HOST" \ | ||
| "VPS01_KNOWN_HOSTS='$VPS01_KNOWN_HOSTS' APP_DIR='${APP_DIR:-/opt/apps/proctor}' bash -s" <<'IONOS' | ||
| set -euo pipefail | ||
| install -d -m 700 "$HOME/.ssh" | ||
| printf '%s\n' "$VPS01_KNOWN_HOSTS" > "$HOME/.ssh/proctor_vps01_known_hosts" | ||
| chmod 600 "$HOME/.ssh/proctor_vps01_known_hosts" | ||
| ssh -A -o BatchMode=yes -o StrictHostKeyChecking=yes \ | ||
| -o UserKnownHostsFile="$HOME/.ssh/proctor_vps01_known_hosts" \ | ||
| munashe@vps01 "APP_DIR='$APP_DIR' bash -s" <<'VPS01' | ||
| set -euo pipefail | ||
| cd "$APP_DIR" | ||
| git fetch --prune origin main | ||
| if git show-ref --verify --quiet refs/heads/main; then | ||
| git checkout main | ||
| else | ||
| git checkout -B main origin/main | ||
| fi | ||
| git reset --hard origin/main | ||
| docker compose up -d --build app | ||
| docker compose run --rm app python scripts/verify_models.py | ||
| for attempt in $(seq 1 30); do | ||
| if curl --fail --silent --show-error http://127.0.0.1:8000/health >/tmp/proctor-health.json; then | ||
| cat /tmp/proctor-health.json | ||
| exit 0 | ||
| fi | ||
| sleep 2 | ||
| done | ||
| docker compose ps | ||
| docker compose logs --tail=100 app | ||
| exit 1 | ||
|
Comment on lines
+69
to
+77
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift 🔎 Supported by static analysis🏁 Script executed: sed -n '45,90p' .github/workflows/deploy.ymlRepository: mudabs/Proctor Length of output: 1616 🏁 Script executed: sed -n '1,240p' scripts/verify_models.py
printf '\n--- docker-compose service definitions ---\n'
sed -n '1,120p' docker-compose.ymlRepository: mudabs/Proctor Length of output: 2712 Rollback every failed post-deployment validation.
Save the previous revision or image before replacement. Use one failure handler to restore it and restart the application before returning the validation failure. 🤖 Prompt for AI Agents |
||
| VPS01 | ||
| IONOS | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| venv/ | ||
| .env | ||
| __pycache__/ | ||
| requirements_clean.txt | ||
| issues.md | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
Deploy the validated commit instead of mutable
origin/main.A later push can update
origin/mainwhile an earlier workflow is running. The earlier workflow then deploys the later commit before its validation job completes.Pass
${{ github.sha }}through both SSH hops. Fetch and reset to that exact commit.🤖 Prompt for AI Agents