DevOps Jenkins Secure Scan + node js + python +Trivy +Hadolint +Gitleaks
202
DevOps Jenkins Secure Scan + node js + python +Trivy +Hadolint +Gitleaks + Bandit Who need ? (Someone need to testing DevOps pipeline for CI/CD and Security/Soucecode scan and has problem can't apt-get install node js + python +Trivy +Hadolint +Gitleaks + Bandit
Who Needs This Jenkins + Docker DevSecOps Stack?
✅ 1. DevSecOps Engineers / Security Champions
Who want to run secure CI/CD pipelines inside a controlled container.
Need to scan code with Semgrep, Gitleaks, Bandit, Trivy, and Hadolint automatically.
Don't want to install tools manually every time.
✅ 2. Developers or QA Teams Who are learning or testing CI/CD pipelines locally or on Synology / Home NAS.
Want an easy way to build/test Node.js, Python, or .NET apps in CI.
Face issues like:
❌ apt-get doesn't work inside limited Docker envs
❌ Can't install dev tools due to security or network policies
✅ 3. Teams Using Synology or Other Docker Hosts Need a portable and secure Jenkins setup (like your ZIP file).
Want to avoid complex manual setup on Docker GUI.
Want to reuse the same pipeline logic across test/dev/prod.
✅ 4. Security Auditors / Compliance Teams Need a way to quickly spin up secure pipelines that include:
SAST (Static App Security Testing)
Secret detection
Dockerfile linting
Without depending on external services or large installs.
❗ Pain Points It Solves ❌ apt-get blocked in restricted containers (Synology / minimal base image)
❌ Missing wget, pip, node, or go dependencies
❌ Permission issues with /var/run/docker.sock
❌ Time-consuming setup for CI tools in Dev environments)
🔐 Secure, Automated, Scalable This repository delivers a comprehensive DevSecOps CI/CD solution powered by Docker, focused on integrating security scanning and automation tools into your software development lifecycle. It is optimized for projects using Node.js and Python, and is designed to be extensible, reproducible, and production-ready.
✅ Key Features 🧩 Jenkins in a Container Fully containerized Jenkins server pre-configured for secure pipeline execution with optional plugins and SSH credential bindings.
🕵️ Trivy Integration Automatic scanning of Docker images and project dependencies for vulnerabilities using Aqua Trivy.
📏 Hadolint (Dockerfile Linter) Enforces Dockerfile best practices with real-time linting and developer-friendly feedback.
🔍 Gitleaks for Secret Detection Scans your Git history and working directory for exposed secrets (API keys, tokens, credentials).
🧪 Bandit for Python Security Analysis Static code analysis tool to find common security issues in Python codebases.
🚀 Node.js & Python Support Includes runtime environments and libraries for Node.js and Python-based applications.
📈 HTML Reports + Dashboard Ready Generates visual reports (HTML) for all scans — easy to integrate into Jenkins or static dashboards.
🛠️ Use Cases Secure CI/CD pipelines for full-stack JavaScript or Python applications
Automated compliance checks in containerized environments
Educational sandbox for learning modern DevSecOps tooling
Internal development platform for startups and teams embracing security-first culture
.
├── docker-compose.yml # Multi-service setup for Jenkins, scanning tools
├── Jenkinsfile # Secure CI/CD pipeline with integrated scans
├── Dockerfile # Custom build including CLI tools
├── scripts/
│ ├── run_trivy.sh # Trivy scan script
│ ├── run_bandit.sh # Python security check
│ └── run_gitleaks.sh # Gitleaks scanner
├── reports/ # Auto-generated scan reports (HTML, JSON)
├── node_app/ # Sample Node.js app
└── python_app/ # Sample Python app
\
📌 Getting Started Clone this repository
Run docker-compose up to bring up Jenkins and toolchain
Access Jenkins on http://localhost:8080
Run pipelines or scans via Jenkins or CLI
🤝 Contributing Contributions are welcome! Whether it's improving security scans, adding a new linter, or optimizing the Docker build — your input helps build a better DevSecOps toolkit.
docker-compose.yml using for docker in docker
services:
jenkins:
build: .
container_name: secure-jenkins
user: root
privileged: true
ports:
- "8080:8080"
- "50000:50000"
volumes:
- jenkins_home:/var/jenkins_home
- /var/run/docker.sock:/var/run/docker.sock
restart: always
Sample Jenkins pipeline script
pipeline { agent any tools { dotnetsdk 'dotnet-6.0' #Change to system config }
environment {
SONAR_TOKEN = credentials('sonarqube-token') // Jenkins Credential
SONAR_HOST = 'http://192.168.1.55:9000' #Change to SVN Server
}
stages {
stage('Checkout SVN') {
steps {
checkout([
$class: 'SubversionSCM',
locations: [[
remote: 'http://192.168.1.55:8088/svn/ChatGPT-RD/apra-a-tool/NetworkTool', #Change to SVN Project
credentialsId: 'svn-credentials-id'
]],
workspaceUpdater: [$class: 'UpdateUpdater']
])
}
}
stage('Restore & Build') {
steps {
dir('NetworkTool') {
sh 'dotnet restore'
sh 'dotnet build -c Release'
}
}
}
stage('Security Scan: Trivy') {
steps {
sh '''
trivy fs . --exit-code 0 --severity HIGH,CRITICAL --format table > trivy-report.txt || true
'''
}
}
stage('Security Scan: Semgrep') {
steps {
sh '''
semgrep scan --config=auto --json > semgrep-report.json || true
'''
}
}
stage('Security Scan: Bandit (Python)') {
steps {
sh '''
bandit -r . -f json -o bandit-report.json || true
'''
}
}
stage('Security Scan: Gitleaks') {
steps {
sh '''
gitleaks detect --no-git --source . --report-format json --report-path gitleaks-report.json || true
'''
}
}
stage('SonarQube Analysis') {
steps {
withSonarQubeEnv('MySonarQube') {
dir('NetworkTool') {
sh '''
export PATH="$HOME/.dotnet/tools:$PATH"
dotnet-sonarscanner begin /k:networktool /d:sonar.host.url=$SONAR_HOST /d:sonar.login=$SONAR_TOKEN \
/d:sonar.scm.disabled=true \
/d:sonar.scm.provider=svn \
/d:sonar.scm.username=Username-change \
/d:sonar.scm.password.secured=password-change\
/d:sonar.exclusions="**/bin/**,**/obj/**"
dotnet build
dotnet-sonarscanner end /d:sonar.login=$SONAR_TOKEN
'''
}
}
}
}
stage('Generate HTML Report') {
steps {
sh 'python3 generate_report.py'
}
}
}
post {
always {
archiveArtifacts artifacts: '**/*.json, **/*.txt, publish/**', allowEmptyArchive: true
archiveArtifacts artifacts: 'summary-report.html', allowEmptyArchive: true
}
success {
echo '✅ Build and Security Scans completed successfully.'
}
failure {
echo '❌ Build or scan failed.'
}
}
}
Don't forget setup credential of jenkins
Sample generate_report.py
/--------------------------------------------------
//*
import json, os, html
def read_file(path): if os.path.exists(path): with open(path, encoding="utf-8") as f: return f.read() return ""
def html_escape(text): return html.escape(text)
def section(title, link, content): return f"""
html_out = """
Security Scan Summary body {{ font-family: Arial, sans-serif; margin: 40px; background: #f9f9f9; }} h1 {{ color: #2c3e50; }} h2 {{ color: #34495e; }} code {{ background: #f4f4f4; padding: 2px 6px; border-radius: 4px; color: #c0392b; }} pre {{ background: #fff; padding: 10px; border-left: 5px solid #3498db; overflow-x: auto; }} section {{ margin-bottom: 40px; }} a {{ text-decoration: none; color: #2980b9; }} a:hover {{ text-decoration: underline; }} table {{ width: 100%; border-collapse: collapse; background: white; }} th, td {{ padding: 8px 12px; border: 1px solid #ddd; }} th {{ background: #ecf0f1; text-align: left; }}trivy_raw = read_file("trivy-report.txt") if trivy_raw: html_out += section("Trivy Report", "trivy-report.txt", f"
{html_escape(trivy_raw)}semgrep_json = read_file("semgrep-report.json") if semgrep_json: data = json.loads(semgrep_json) rows = "" for item in data.get("results", []): rows += f""" {item['check_id']} {item['path']}:{item['start']['line']} {html_escape(item['extra'].get('message', ''))} """ table = f"""
{rows}| Rule | Location | Message |
|---|
bandit_json = read_file("bandit-report.json") if bandit_json: data = json.loads(bandit_json) rows = "" for issue in data.get("results", []): rows += f""" {issue['filename']}:{issue['line_number']} {html_escape(issue['issue_text'])} {issue.get('severity')} """ table = f"""
{rows}| Location | Issue | Severity |
|---|
gitleaks_json = read_file("gitleaks-report.json") if gitleaks_json: leaks = json.loads(gitleaks_json) rows = "" for leak in leaks: rows += f""" {leak.get('file')}:{leak.get('line')} {leak.get('rule')} {html_escape(leak.get('secret', '')[:10])}... """ table = f"""
{rows}| Location | Rule | Leaked (Partial) |
|---|
html_out += ""
with open("summary-report.html", "w", encoding="utf-8") as f: f.write(html_out)
*/
Content type
Image
Digest
sha256:dfc502506…
Size
1.6 GB
Last updated
over 1 year ago
docker pull nunut/devops-jenkins-secure