fix: python-app healthcheck endpoint to /api/health #17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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" |