NGINX Security in CI/CD Pipelines

Automate NGINX configuration security scanning with Gixy. Complete examples for GitHub Actions, GitLab CI, Jenkins, CircleCI, and Docker.

Updated: January 2025 12 min read

Why Automate NGINX Security Scanning?

Manual security reviews are error-prone and don't scale. By integrating Gixy into your CI/CD pipeline, you:

  • Catch issues early — before they reach staging or production
  • Enforce security standards — every PR is automatically checked
  • Create audit trails — every scan is logged and traceable
  • Shift security left — developers get immediate feedback

GitHub Actions

The most popular CI/CD platform. Here's a complete workflow:

.github/workflows/nginx-security.yml
name: NGINX Security Scan

on:
  push:
    paths:
      - 'nginx/**'
      - '.github/workflows/nginx-security.yml'
  pull_request:
    paths:
      - 'nginx/**'

jobs:
  gixy-scan:
    name: Security Scan
    runs-on: ubuntu-latest
    
    steps:
      - name: Checkout code
        uses: actions/checkout@v4
      
      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: '3.11'
      
      - name: Install Gixy
        run: pip install gixy-ng
      
      - name: Run Security Scan
        run: |
          echo "## NGINX Security Scan Results" >> $GITHUB_STEP_SUMMARY
          echo "" >> $GITHUB_STEP_SUMMARY
          
          # Run Gixy and capture output
          if gixy -f text nginx/*.conf 2>&1 | tee scan-results.txt; then
            echo "✅ No security issues found!" >> $GITHUB_STEP_SUMMARY
          else
            echo "⚠️ Security issues detected:" >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
            cat scan-results.txt >> $GITHUB_STEP_SUMMARY
            echo '```' >> $GITHUB_STEP_SUMMARY
          fi
      
      - name: Fail on HIGH severity
        run: gixy -lll nginx/*.conf
      
      - name: Upload scan results
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: gixy-results
          path: scan-results.txt

GitLab CI

For GitLab-based workflows:

.gitlab-ci.yml
stages:
  - security

nginx-security-scan:
  stage: security
  image: python:3.11-slim
  
  before_script:
    - pip install gixy-ng
  
  script:
    - echo "Running NGINX security scan..."
    - gixy -f text nginx/*.conf
    - gixy -lll nginx/*.conf  # Fail on HIGH severity
  
  artifacts:
    when: always
    reports:
      junit: gixy-report.xml
    paths:
      - gixy-report.xml
  
  rules:
    - changes:
        - nginx/**/*
        - .gitlab-ci.yml

Jenkins

For Jenkins pipelines (Declarative syntax):

Jenkinsfile
pipeline {
    agent any
    
    stages {
        stage('NGINX Security Scan') {
            steps {
                sh '''
                    pip install gixy-ng
                    gixy -f json nginx/*.conf > gixy-results.json || true
                    gixy -f text nginx/*.conf
                '''
            }
        }
        
        stage('Fail on Critical') {
            steps {
                sh 'gixy -lll nginx/*.conf'
            }
        }
    }
    
    post {
        always {
            archiveArtifacts artifacts: 'gixy-results.json'
        }
    }
}

Docker

Run Gixy in a container for reproducible scans:

Dockerfile.gixy
FROM python:3.11-slim

RUN pip install --no-cache-dir gixy-ng

ENTRYPOINT ["gixy"]
CMD ["--help"]
Usage
# Build the image
docker build -t gixy -f Dockerfile.gixy .

# Scan a local config
docker run --rm -v $(pwd)/nginx:/nginx gixy /nginx/nginx.conf

# Scan with JSON output
docker run --rm -v $(pwd)/nginx:/nginx gixy -f json /nginx/nginx.conf

CircleCI

.circleci/config.yml
version: 2.1

jobs:
  nginx-security:
    docker:
      - image: cimg/python:3.11
    steps:
      - checkout
      - run:
          name: Install Gixy
          command: pip install gixy-ng
      - run:
          name: Run Security Scan
          command: gixy -f text nginx/*.conf
      - run:
          name: Fail on Critical
          command: gixy -lll nginx/*.conf
      - store_artifacts:
          path: gixy-results.json

workflows:
  security:
    jobs:
      - nginx-security

Exit Codes and Severity Filtering

Gixy uses exit codes for CI/CD integration:

  • 0 — No issues found (or all filtered out)
  • 1 — Issues found matching the severity filter
  • 2 — Configuration or runtime error

Use severity flags to control pipeline behavior:

# Fail on any issue (LOW, MEDIUM, or HIGH)
gixy nginx.conf

# Fail on MEDIUM or HIGH only
gixy -ll nginx.conf

# Fail on HIGH only (recommended for blocking PRs)
gixy -lll nginx.conf
💡 Best Practice: Use -lll (HIGH only) for blocking pipeline failures, but run the full scan and save results as artifacts for visibility into all issues.

JSON Output for Custom Processing

Use JSON output for custom reporting or integration with other tools:

# Generate JSON report
gixy -f json nginx.conf > report.json

# Process with jq
cat report.json | jq '.[] | select(.severity == "HIGH")'

# Count issues by severity
cat report.json | jq 'group_by(.severity) | map({severity: .[0].severity, count: length})'

Scanning nginx -T Output

For production servers, use nginx -T to capture the complete configuration:

# On the server
nginx -T > nginx-dump.conf

# Copy to CI or scan locally
gixy nginx-dump.conf

# Or pipe directly (if running on the same host)
nginx -T | gixy -

Recommended Pipeline Strategy

  1. PR/MR Check — Run on every pull request, fail on HIGH severity
  2. Main Branch — Run full scan, save artifacts, notify on any issues
  3. Scheduled — Weekly full audit of production configs
Complete GitHub Actions Example
name: NGINX Security

on:
  push:
    branches: [main]
  pull_request:
  schedule:
    - cron: '0 0 * * 0'  # Weekly on Sunday

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pip install gixy-ng
      
      # Always run full scan and save results
      - run: gixy -f json nginx/*.conf > results.json || true
      - uses: actions/upload-artifact@v4
        with:
          name: security-report
          path: results.json
      
      # Block PRs on HIGH severity only
      - run: gixy -lll nginx/*.conf
        if: github.event_name == 'pull_request'
Want Continuous Security Monitoring? CI/CD catches issues at deploy time, but what about config drift? GetPageSpeed Amplify runs Gixy automatically 24/7 and alerts you to security issues in real-time.