| 1 | name: Deploy
|
| 2 |
|
| 3 | on:
|
| 4 | push:
|
| 5 | branches:
|
| 6 | - master # goes for production now, will become staging later on
|
| 7 | - production
|
| 8 |
|
| 9 | env:
|
| 10 | REGISTRY: ghcr.io
|
| 11 | IMAGE_NAME: ${{ github.repository }}
|
| 12 |
|
| 13 | jobs:
|
| 14 | build-and-push:
|
| 15 | name: Build & push image
|
| 16 | runs-on: ubuntu-latest
|
| 17 | permissions:
|
| 18 | contents: read
|
| 19 | packages: write
|
| 20 |
|
| 21 | outputs:
|
| 22 | image_tag: ${{ steps.meta.outputs.version }}
|
| 23 |
|
| 24 | steps:
|
| 25 | - name: Checkout
|
| 26 | uses: actions/checkout@v4
|
| 27 |
|
| 28 | - name: Log in to GHCR
|
| 29 | uses: docker/login-action@v3
|
| 30 | with:
|
| 31 | registry: ${{ env.REGISTRY }}
|
| 32 | username: ${{ github.actor }}
|
| 33 | password: ${{ secrets.GHCR_TOKEN }}
|
| 34 |
|
| 35 | - name: Docker metadata
|
| 36 | id: meta
|
| 37 | uses: docker/metadata-action@v5
|
| 38 | with:
|
| 39 | images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
|
| 40 | tags: |
|
| 41 | # main branch => tag "latest"
|
| 42 | type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
|
| 43 | # production branch => tag "production"
|
| 44 | # type=raw,value=production,enable=${{ github.ref == 'refs/heads/production' }}
|
| 45 | # always tag with short SHA for traceability
|
| 46 | type=sha,prefix=,format=short
|
| 47 |
|
| 48 | - name: Build and push
|
| 49 | uses: docker/build-push-action@v5
|
| 50 | with:
|
| 51 | context: ./api
|
| 52 | file: ./api/Dockerfile.production
|
| 53 | push: true
|
| 54 | tags: ${{ steps.meta.outputs.tags }}
|
| 55 | labels: ${{ steps.meta.outputs.labels }}
|
| 56 |
|
| 57 |
|
| 58 | deploy-production:
|
| 59 | name: Deploy to production
|
| 60 | needs: build-and-push
|
| 61 | runs-on: ubuntu-latest
|
| 62 | if: github.ref == 'refs/heads/master'
|
| 63 | environment: production
|
| 64 |
|
| 65 | steps:
|
| 66 | - name: Deploy via SSH
|
| 67 | uses: appleboy/ssh-action@v1
|
| 68 | with:
|
| 69 | host: ${{ secrets.VPS_HOST }}
|
| 70 | username: ${{ secrets.VPS_USER }}
|
| 71 | key: ${{ secrets.VPS_SSH_KEY }}
|
| 72 | script: |
|
| 73 | set -e
|
| 74 | cd /srv/app/production
|
| 75 |
|
| 76 | docker pull ghcr.io/${{ github.repository }}:latest
|
| 77 |
|
| 78 | sed -i "s/^IMAGE_TAG=.*/IMAGE_TAG=latest/" .env
|
| 79 |
|
| 80 | docker compose up -d --no-deps --force-recreate api
|
| 81 |
|
| 82 | sleep 3
|
| 83 | # Dump the logs for a while
|
| 84 | docker compose logs --tail=50 api
|