Skip to content
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

Frontend CICD #23

Merged
merged 20 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .github/workflows/dev-frontend.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Dev frontend workflow

on:
push:
branches:
- 'dev/frontend@**'
workflow_dispatch:

jobs:
trigger-frontend-ci:
uses: ./.github/workflows/frontend-ci.yml

# cd part use watchtower to update the container will be changed to a more clever way once we scale up our services
58 changes: 58 additions & 0 deletions .github/workflows/frontend-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
name: Build and upload docker image of frontend to GHCR

on:
workflow_dispatch:
workflow_call:



# Configures this workflow to run every time a change is pushed to the branch called `release`.

# Defines two custom environment variables for the workflow. These are used for the Container registry domain, and a name for the Docker image that this workflow builds.
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/pastexam/frontend

# There is a single job in this workflow. It's configured to run on the latest available version of Ubuntu.
jobs:
build-and-push-image:
runs-on: ubuntu-latest
# Sets the permissions granted to the `GITHUB_TOKEN` for the actions in this job.
permissions:
contents: read
packages: write
attestations: write
id-token: write
#
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
Comment on lines +31 to +35
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Use GITHUB_TOKEN with minimum required permissions

The workflow uses GITHUB_TOKEN with broad permissions. Consider:

  1. Using a fine-grained PAT for GHCR access
  2. Implementing OIDC authentication

[security]

Example configuration:

permissions:
  packages: write
  contents: read

steps:
  - name: Log in to the Container registry
    uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
    with:
      registry: ${{ env.REGISTRY }}
      username: ${{ github.actor }}
      password: ${{ secrets.GHCR_TOKEN }}

# This step uses [docker/metadata-action](https://github.com/docker/metadata-action#about) to extract tags and labels that will be applied to the specified image. The `id` "meta" allows the output of this step to be referenced in a subsequent step. The `images` value provides the base name for the tags and labels.
- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@9ec57ed1fcdbf14dcef7dfbe97b2010124a938b7
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=raw,value=latest
type=ref,event=branch
type=ref,event=tag
# This step uses the `docker/build-push-action` action to build the image, based on your repository's `Dockerfile`. If the build succeeds, it pushes the image to GitHub Packages.
# It uses the `context` parameter to define the build's context as the set of files located in the specified path. For more information, see "[Usage](https://github.com/docker/build-push-action#usage)" in the README of the `docker/build-push-action` repository.
# It uses the `tags` and `labels` parameters to tag and label the image with the output from the "meta" step.
- name: Build and push Docker image
id: push
uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
with:
context: ./frontend
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
Comment on lines +49 to +56
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add security scanning and build optimization

Consider adding:

  1. Container vulnerability scanning
  2. Docker layer caching
  3. Build context optimization

Example enhancement:

steps:
  - name: Build and push Docker image
    uses: docker/build-push-action@f2a1d5e99d037542a71f64918e516c093c6f3fc4
    with:
      context: ./frontend
      push: true
      tags: ${{ steps.meta.outputs.tags }}
      labels: ${{ steps.meta.outputs.labels }}
      cache-from: type=gha
      cache-to: type=gha,mode=max

  - name: Run Trivy vulnerability scanner
    uses: aquasecurity/trivy-action@master
    with:
      image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
      format: 'table'
      exit-code: '1'
      ignore-unfixed: true
      vuln-type: 'os,library'
      severity: 'CRITICAL,HIGH'



8 changes: 8 additions & 0 deletions watchtower/compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
watchtower:
image: containrrr/watchtower
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Comment on lines +4 to +5
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security concern: Docker socket mounting creates a potential security risk

Mounting the Docker socket gives the container root-equivalent access to the host. Consider:

  1. Using a non-root user within the container
  2. Implementing socket proxy (e.g., docker-socket-proxy) to restrict API access

Example socket proxy configuration:

services:
  socket-proxy:
    image: tecnativa/docker-socket-proxy
    privileged: false
    environment:
      - CONTAINERS=1
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
  watchtower:
    image: containrrr/watchtower
    environment:
      - DOCKER_HOST=tcp://socket-proxy:2375
    depends_on:
      - socket-proxy

command:
--interval 10 --cleanup
Comment on lines +6 to +7
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Performance concern: 10-second update interval is too aggressive

Such a short interval could:

  1. Increase load on Docker registry
  2. Potentially hit rate limits
  3. Consume unnecessary resources

Consider increasing the interval to at least 5 minutes (300 seconds).

🧰 Tools
🪛 yamllint (1.35.1)

[error] 6-6: trailing spaces

(trailing-spaces)

restart: always
Comment on lines +1 to +8
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Add container filters and authentication configuration

Current configuration will update all containers. Consider:

  1. Adding filters to target specific containers
  2. Configuring registry authentication
  3. Adding resource limits

Example enhanced configuration:

services:
  watchtower:
    image: containrrr/watchtower
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - WATCHTOWER_POLL_INTERVAL=300
      - WATCHTOWER_LABEL_ENABLE=true
      - WATCHTOWER_CLEANUP=true
      - REGISTRY_USERNAME=${GHCR_USERNAME}
      - REGISTRY_PASSWORD=${GHCR_TOKEN}
    command: --label-enable
    deploy:
      resources:
        limits:
          memory: 256M
        reservations:
          memory: 128M
    restart: always
🧰 Tools
🪛 yamllint (1.35.1)

[error] 6-6: trailing spaces

(trailing-spaces)

Loading