1- # Inspired the workflow from https://faun.pub/full-ci-cd-with-docker-github-actions-digitalocean-droplets-container-registry-db2938db8246
2- name : CI
1+ # Name of the workflow
2+ name : Create, Publish, and Deploy Docker Image
33
4- # 1
5- # Controls when the workflow will run
4+ # Configures this workflow to run every time a change is pushed to the branch called `praveshan`.
65on :
7- # Triggers the workflow on push events but only for the master branch
86 push :
9- branches : [ praveshan ]
7+ branches : [' praveshan' ]
108
11- # Allows you to run this workflow manually from the Actions tab
12- workflow_dispatch :
13- inputs :
14- version :
15- description : ' Image version'
16- required : true
17- # 2
9+ # Defines environment variables available to all jobs in the workflow.
1810env :
19- REGISTRY : " registry.digitalocean.com/praveshan "
20- IMAGE_NAME : " ammentor-backend-praveshan "
11+ REGISTRY : ghcr.io
12+ IMAGE_NAME : ${{ github.repository }}
2113
22- # 3
14+ # Defines the jobs that will run as part of the workflow.
2315jobs :
24- build_and_push :
16+ # JOB 1: Builds the Docker image and pushes it to the GitHub Container Registry.
17+ build-and-push-image :
2518 runs-on : ubuntu-latest
19+ permissions :
20+ contents : read
21+ packages : write
22+ attestations : write
23+ id-token : write
24+
2625 steps :
27- - name : Checkout the repo
28- uses : actions/checkout@v2
29-
30- - name : List files in repository
31- run : ls -laR
32-
33- - name : Build container image
34- # This now builds the image with both the commit tag and the 'latest' tag
35- run : docker build -t $(echo $REGISTRY)/$(echo $IMAGE_NAME):$(echo $GITHUB_SHA | head -c7) -t $(echo $REGISTRY)/$(echo $IMAGE_NAME):latest .
26+ - name : Checkout repository
27+ uses : actions/checkout@v4
3628
37- - name : Install doctl
38- uses : digitalocean/action-doctl@v2
29+ - name : Log in to GitHub Container Registry
30+ uses : docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
3931 with :
40- token : ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }}
41-
42- - name : Log in to DigitalOcean Container Registry with short-lived credentials
43- run : doctl registry login --expiry-seconds 1800
32+ registry : ${{ env.REGISTRY }}
33+ username : ${{ github.actor }}
34+ password : ${{ secrets.GITHUB_TOKEN }}
35+
36+ - name : Extract metadata (tags, labels) for Docker
37+ id : meta
38+ uses : docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
39+ with :
40+ images : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
4441
42+ - name : Build and push Docker image
43+ id : push
44+ uses : docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
45+ with :
46+ context : .
47+ push : true
48+ tags : ${{ steps.meta.outputs.tags }}
49+ labels : ${{ steps.meta.outputs.labels }}
4550
46- - name : Push image to DigitalOcean Container Registry
47- # This now pushes both the commit tag and the 'latest' tag
48- run : |
49- docker push $(echo $REGISTRY)/$(echo $IMAGE_NAME):$(echo $GITHUB_SHA | head -c7)
50- docker push $(echo $REGISTRY)/$(echo $IMAGE_NAME):latest
51-
52- # This removes the old images from the container registry
53- - name : Remove old images from Container Registry
54- uses : henrik242/docr-image-remove@v1
51+ - name : Generate artifact attestation
52+ uses : actions/attest-build-provenance@v2
5553 with :
56- image_repository : ammentor-backend-praveshan
57- buffer_size : 10
58- exclude : ^(latest)$
54+ subject-name : ${{ env.REGISTRY }}/${{ env.IMAGE_NAME}}
55+ subject-digest : ${{ steps.push.outputs.digest }}
56+ push-to-registry : true
5957
58+ # JOB 2: Deploys the new image to your Virtual Machine.
6059 deploy :
60+ # This job will only run after the 'build-and-push-image' job is successful.
61+ needs : build-and-push-image
6162 runs-on : ubuntu-latest
62- needs : build_and_push
63- steps :
64- - name : Checkout the repo
65- uses : actions/checkout@v2
6663
67- - name : Copy docker-compose.yml to Droplet
68- uses : appleboy/scp-action@master
69- with :
70- host : ${{ secrets.HOST }}
71- username : ${{ secrets.USERNAME }}
72- key : ${{ secrets.SSHKEY }}
73- passphrase : ${{ secrets.PASSPHRASE }}
74- source : " docker-compose.yml"
75- target : " myapp"
76-
77- - name : Deploy to Digital Ocean droplet via SSH action
78- uses : appleboy/ssh-action@master
64+ steps :
65+ - name : SSH into VM and redeploy
66+ 7967 with :
80- host : ${{ secrets.HOST }}
81- username : ${{ secrets.USERNAME }}
82- key : ${{ secrets.SSHKEY }}
83- passphrase : ${{ secrets.PASSPHRASE }}
84- envs : IMAGE_NAME,REGISTRY,{{ secrets.DIGITALOCEAN_ACCESS_TOKEN }},GITHUB_SHA
68+ host : ${{ secrets.VM_HOST }}
69+ username : ${{ secrets.VM_USERNAME }}
70+ key : ${{ secrets.SSH_KEY }}
8571 script : |
86- # Navigate to the app directory
87- cd myapp
72+ # Pull the image tagged with the specific branch name (e.g., 'praveshan')
73+ docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
8874
89- # Login to registry
90- docker login -u ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} -p ${{ secrets.DIGITALOCEAN_ACCESS_TOKEN }} registry.digitalocean.com
91-
92- # Update the image definition in docker-compose.yml to use the new tag
93- # This makes sure we run the exact version we just built
94- sed -i 's|image: .*|image: $(echo $REGISTRY)/$(echo $IMAGE_NAME):$(echo $GITHUB_SHA | head -c7)|' docker-compose.yml
95-
96- # Pull the new backend image
97- docker compose pull backend
75+ # Stop and remove the old container to avoid conflicts
76+ docker stop my-app-container || true
77+ docker rm my-app-container || true
9878
99- # Stop and recreate ONLY the backend service with the new image
100- docker compose up -d --no-deps backend
79+ # Run the new container using the correct image tag
80+ docker run -d \
81+ --restart always \
82+ -p 8080:80 \
83+ --name my-app-container \
84+ ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.ref_name }}
0 commit comments