Skip to content

fix: adjust healthcheck config for faster checks with longer grace pe… #18

fix: adjust healthcheck config for faster checks with longer grace pe…

fix: adjust healthcheck config for faster checks with longer grace pe… #18

Workflow file for this run

name: CloudLab CI/CD Pipeline
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
REGISTRY: ghcr.io
NODE_APP_IMAGE: cloudlab-nodejs-app
PYTHON_APP_IMAGE: cloudlab-python-app
jobs:
# Lint and validate configurations
validate:
name: Validate Configurations
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Validate Docker Compose
run: docker compose config
- name: Generate SSL Certificates
run: |
mkdir -p nginx/ssl
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout nginx/ssl/key.pem \
-out nginx/ssl/cert.pem \
-subj "/C=ID/ST=Jakarta/L=Jakarta/O=CloudLab/OU=Dev/CN=localhost"
- name: Validate Nginx config
run: |
docker run --rm \
--add-host nodejs-app:127.0.0.1 \
--add-host python-app:127.0.0.1 \
--add-host grafana:127.0.0.1 \
--add-host prometheus:127.0.0.1 \
-v $(pwd)/nginx/nginx.conf:/etc/nginx/nginx.conf:ro \
-v $(pwd)/nginx/ssl:/etc/nginx/ssl:ro \
nginx:alpine nginx -t
# Build all applications using matrix strategy
build-apps:
name: Build ${{ matrix.app.name }}
runs-on: ubuntu-latest
needs: validate
strategy:
matrix:
app:
- name: nodejs-app
image: cloudlab-nodejs-app
context: ./apps/demo-apps/nodejs-app
port: 3001
health_endpoint: /health
metrics_endpoint: /metrics
sleep_time: 5
- name: python-app
image: cloudlab-python-app
context: ./apps/demo-apps/python-app
port: 5000
health_endpoint: /api/health
metrics_endpoint: /metrics
sleep_time: 20
fail-fast: false # Continue building other apps even if one fails
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build ${{ matrix.app.name }} Docker image
uses: docker/build-push-action@v5
with:
context: ${{ matrix.app.context }}
file: ${{ matrix.app.context }}/Dockerfile
push: false
load: true
tags: ${{ matrix.app.image }}:${{ github.sha }}
cache-from: type=gha,scope=${{ matrix.app.name }}
cache-to: type=gha,mode=max,scope=${{ matrix.app.name }}
- name: Test ${{ matrix.app.name }}
run: |
docker run -d --name test-${{ matrix.app.name }} -p ${{ matrix.app.port }}:${{ matrix.app.port }} ${{ matrix.app.image }}:${{ github.sha }}
sleep ${{ matrix.app.sleep_time }}
if ! curl -f http://127.0.0.1:${{ matrix.app.port }}${{ matrix.app.health_endpoint }}; then
echo "::error::Health check failed for ${{ matrix.app.name }}!"
echo "::group::Container Logs"
docker logs test-${{ matrix.app.name }}
echo "::endgroup::"
exit 1
fi
curl -f http://127.0.0.1:${{ matrix.app.port }}${{ matrix.app.metrics_endpoint }} || exit 1
docker stop test-${{ matrix.app.name }}
docker rm test-${{ matrix.app.name }}
# Security scanning - Runs in parallel
security-scan:
name: Security Scan
runs-on: ubuntu-latest
needs: validate # Only needs code checkout/validation
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Run Trivy vulnerability scanner - Node.js
uses: aquasecurity/trivy-action@master
with:
scan-type: "fs"
scan-ref: "./apps/demo-apps/nodejs-app"
format: "sarif"
output: "trivy-nodejs-results.sarif"
- name: Run Trivy vulnerability scanner - Python
uses: aquasecurity/trivy-action@master
with:
scan-type: "fs"
scan-ref: "./apps/demo-apps/python-app"
format: "sarif"
output: "trivy-python-results.sarif"
# Validate Kubernetes Manifests
lint-k8s:
name: Lint Kubernetes
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install kubeconform
run: |
wget https://github.com/yannh/kubeconform/releases/download/v0.6.3/kubeconform-linux-amd64.tar.gz
tar xf kubeconform-linux-amd64.tar.gz
sudo mv kubeconform /usr/local/bin/
- name: Validate Manifests
run: kubeconform -summary -output text -ignore-missing-schemas k8s/
# Integration test
integration-test:
name: Integration Tests
runs-on: ubuntu-latest
needs: [build-apps, security-scan, lint-k8s]
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Start all services
run: docker compose up -d
- name: Wait for services to be ready
run: |
sleep 30
docker compose ps
- name: Test Nginx reverse proxy
run: |
curl -k -f https://localhost/health || exit 1
- name: Test Node.js app through Nginx
run: |
curl -k -f https://localhost/ || exit 1
- name: Test Python API through Nginx
run: |
curl -k -f https://localhost/api || exit 1
- name: Test Prometheus
run: |
curl -f http://localhost:9090/-/healthy || exit 1
- name: Test Grafana
run: |
curl -f http://localhost:3000/api/health || exit 1
- name: Check Prometheus targets
run: |
curl -f http://localhost:9090/api/v1/targets | grep -q "nodejs-app"
curl -f http://localhost:9090/api/v1/targets | grep -q "python-app"
- name: Show logs on failure
if: failure()
run: docker compose logs
- name: Cleanup
if: always()
run: docker compose down -v
# Deployment (optional - uncomment when ready)
# deploy:
# name: Deploy to Environment
# runs-on: ubuntu-latest
# needs: [integration-test, security-scan]
# if: github.ref == 'refs/heads/main'
# steps:
# - name: Checkout code
# uses: actions/checkout@v4
#
# - name: Deploy to production
# run: |
# echo "Add your deployment steps here"