DeWitt Gibson commited on
Commit
1e94b85
·
1 Parent(s): 1f1545e

Adding Action to publish to GitHub Packages

Browse files
.dockerignore ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Git files
2
+ .git
3
+ .gitignore
4
+ .gitattributes
5
+
6
+ # GitHub
7
+ .github
8
+
9
+ # Python cache
10
+ __pycache__
11
+ *.py[cod]
12
+ *$py.class
13
+ *.so
14
+ .Python
15
+ build/
16
+ develop-eggs/
17
+ dist/
18
+ downloads/
19
+ eggs/
20
+ .eggs/
21
+ lib/
22
+ lib64/
23
+ parts/
24
+ sdist/
25
+ var/
26
+ wheels/
27
+ *.egg-info/
28
+ .installed.cfg
29
+ *.egg
30
+ MANIFEST
31
+
32
+ # Virtual environments
33
+ .env
34
+ .venv
35
+ env/
36
+ venv/
37
+ ENV/
38
+ env.bak/
39
+ venv.bak/
40
+
41
+ # Testing
42
+ .tox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ .hypothesis/
50
+ .pytest_cache/
51
+ test-results/
52
+
53
+ # IDE
54
+ .vscode/
55
+ .idea/
56
+ *.swp
57
+ *.swo
58
+ *~
59
+ .DS_Store
60
+
61
+ # Documentation
62
+ docs/_build/
63
+ *.md
64
+ !README.md
65
+
66
+ # Local development files
67
+ *.log
68
+ *.db
69
+ *.sqlite
70
+ *.sqlite3
71
+ .env.example
72
+
73
+ # Jupyter
74
+ .ipynb_checkpoints
75
+
76
+ # Temporary files
77
+ tmp/
78
+ temp/
79
+ *.tmp
80
+
81
+ # Docker
82
+ docker-compose.yml
83
+ Dockerfile
84
+ dockerfile
85
+ .dockerignore
86
+
87
+ # CI/CD
88
+ .travis.yml
89
+ .gitlab-ci.yml
90
+ azure-pipelines.yml
91
+
92
+ # Other
93
+ *.bak
94
+ *.backup
95
+ page/
96
+ examples_dashboard.py
97
+ demo_dashboard.py
98
+ setup.sh
99
+ run_dashboard.bat
100
+ run_dashboard.ps1
101
+ CNAME
102
+ CHANGELOG.md
103
+ CLAUDE.md
104
+ CONTRIBUTING.md
105
+ PROJECT.md
.github/workflows/README.md CHANGED
@@ -30,13 +30,60 @@ The main continuous integration workflow with three sequential jobs:
30
  - Builds Python distribution packages (sdist and wheel)
31
  - Uploads build artifacts
32
 
33
- ### 2. File Size Check (filesize.yml)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  **Trigger:** Pull Requests to `main` branch, Manual dispatch
35
 
36
  - Checks for large files (>10MB) to ensure compatibility with HuggingFace Spaces
37
  - Helps prevent repository bloat
 
38
 
39
- ### 3. HuggingFace Sync (huggingface.yml)
40
  **Trigger:** Push to `main` branch, Manual dispatch
41
 
42
  - Syncs repository to HuggingFace Spaces
@@ -55,12 +102,29 @@ This project has migrated from CircleCI to GitHub Actions. The new CI workflow p
55
 
56
  ## Required Secrets
57
 
58
- - `HF_TOKEN`: HuggingFace token for syncing to Spaces (optional, only needed if using HuggingFace sync)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
  ## Local Testing
61
 
62
  To run the same checks locally before pushing:
63
 
 
64
  ```bash
65
  # Install development dependencies
66
  pip install -e ".[dev,test]"
@@ -76,4 +140,61 @@ pytest tests/ --cov=src --cov-report=term
76
 
77
  # Build package
78
  python -m build
79
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  - Builds Python distribution packages (sdist and wheel)
31
  - Uploads build artifacts
32
 
33
+ ### 2. Security Scan (security-scan.yml)
34
+ **Trigger:** Push and Pull Requests to `main` and `develop` branches, Daily schedule (2 AM UTC), Manual dispatch
35
+
36
+ Comprehensive security scanning with multiple jobs:
37
+
38
+ #### Trivy Repository Scan
39
+ - Scans filesystem for vulnerabilities in dependencies
40
+ - Checks for CRITICAL, HIGH, and MEDIUM severity issues
41
+ - Uploads results to GitHub Security tab (SARIF format)
42
+
43
+ #### Trivy Config Scan
44
+ - Scans configuration files for security misconfigurations
45
+ - Checks Dockerfiles, GitHub Actions, and other config files
46
+
47
+ #### Dependency Review
48
+ - Reviews dependency changes in pull requests
49
+ - Fails on high severity vulnerabilities
50
+ - Posts summary comments on PRs
51
+
52
+ #### Python Safety Check
53
+ - Runs safety check on Python dependencies
54
+ - Identifies known security vulnerabilities in packages
55
+
56
+ ### 3. Docker Build & Publish (docker-publish.yml)
57
+ **Trigger:** Push to `main`, Version tags (v*.*.*), Pull Requests to `main`, Releases, Manual dispatch
58
+
59
+ Builds and publishes Docker images to GitHub Container Registry (ghcr.io):
60
+
61
+ #### Build and Push Job
62
+ - Builds Docker image using BuildKit
63
+ - Pushes to GitHub Container Registry (ghcr.io/dewitt4/llmguardian)
64
+ - Supports multi-architecture builds (linux/amd64, linux/arm64)
65
+ - Tags images with:
66
+ - Branch name (e.g., `main`)
67
+ - Semantic version (e.g., `v1.0.0`, `1.0`, `1`)
68
+ - Git SHA (e.g., `main-abc1234`)
69
+ - `latest` for main branch
70
+ - For PRs: Only builds, doesn't push
71
+ - Runs Trivy vulnerability scan on published images
72
+ - Generates artifact attestation for supply chain security
73
+
74
+ #### Test Image Job
75
+ - Pulls published image
76
+ - Validates image can run
77
+ - Checks image size
78
+
79
+ ### 4. File Size Check (filesize.yml)
80
  **Trigger:** Pull Requests to `main` branch, Manual dispatch
81
 
82
  - Checks for large files (>10MB) to ensure compatibility with HuggingFace Spaces
83
  - Helps prevent repository bloat
84
+ - Posts warnings on PRs for large files
85
 
86
+ ### 5. HuggingFace Sync (huggingface.yml)
87
  **Trigger:** Push to `main` branch, Manual dispatch
88
 
89
  - Syncs repository to HuggingFace Spaces
 
102
 
103
  ## Required Secrets
104
 
105
+ ### GitHub Container Registry
106
+ - No additional secrets needed - uses `GITHUB_TOKEN` automatically provided by GitHub Actions
107
+
108
+ ### HuggingFace (Optional)
109
+ - `HF_TOKEN`: HuggingFace token for syncing to Spaces (only needed if using HuggingFace sync)
110
+
111
+ ### Codecov (Optional)
112
+ - Coverage reports will upload anonymously, but you can configure `CODECOV_TOKEN` for private repos
113
+
114
+ ## Permissions
115
+
116
+ The workflows use the following permissions:
117
+
118
+ - **CI Workflow**: `contents: read`
119
+ - **Security Scan**: `contents: read`, `security-events: write`
120
+ - **Docker Publish**: `contents: read`, `packages: write`, `id-token: write`
121
+ - **File Size Check**: `contents: read`, `pull-requests: write`
122
 
123
  ## Local Testing
124
 
125
  To run the same checks locally before pushing:
126
 
127
+ ### Code Quality & Tests
128
  ```bash
129
  # Install development dependencies
130
  pip install -e ".[dev,test]"
 
140
 
141
  # Build package
142
  python -m build
143
+ ```
144
+
145
+ ### Security Scanning
146
+ ```bash
147
+ # Install Trivy (macOS)
148
+ brew install trivy
149
+
150
+ # Install Trivy (Linux)
151
+ wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | sudo apt-key add -
152
+ echo "deb https://aquasecurity.github.io/trivy-repo/deb $(lsb_release -sc) main" | sudo tee -a /etc/apt/sources.list.d/trivy.list
153
+ sudo apt-get update && sudo apt-get install trivy
154
+
155
+ # Run Trivy scans
156
+ trivy fs . --severity CRITICAL,HIGH,MEDIUM
157
+ trivy config .
158
+
159
+ # Run Safety check
160
+ pip install safety
161
+ safety check
162
+ ```
163
+
164
+ ### Docker Build & Test
165
+ ```bash
166
+ # Build Docker image
167
+ docker build -f docker/dockerfile -t llmguardian:local .
168
+
169
+ # Run container
170
+ docker run -p 8000:8000 -p 8501:8501 llmguardian:local
171
+
172
+ # Scan Docker image with Trivy
173
+ trivy image llmguardian:local
174
+
175
+ # Test image
176
+ docker run --rm llmguardian:local python -c "import llmguardian; print(llmguardian.__version__)"
177
+ ```
178
+
179
+ ## Using Published Docker Images
180
+
181
+ Pull and run the latest published image:
182
+
183
+ ```bash
184
+ # Pull latest image
185
+ docker pull ghcr.io/dewitt4/llmguardian:latest
186
+
187
+ # Run API server
188
+ docker run -p 8000:8000 ghcr.io/dewitt4/llmguardian:latest
189
+
190
+ # Run dashboard
191
+ docker run -p 8501:8501 ghcr.io/dewitt4/llmguardian:latest streamlit run src/llmguardian/dashboard/app.py
192
+
193
+ # Run with environment variables
194
+ docker run -p 8000:8000 \
195
+ -e LOG_LEVEL=DEBUG \
196
+ -e SECURITY_RISK_THRESHOLD=8 \
197
+ ghcr.io/dewitt4/llmguardian:latest
198
+ ```
199
+
200
+ See `docker/README.md` for more Docker usage examples.
.github/workflows/docker-publish.yml ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Docker Build & Publish
2
+
3
+ on:
4
+ push:
5
+ branches: [ main ]
6
+ tags:
7
+ - 'v*.*.*'
8
+ pull_request:
9
+ branches: [ main ]
10
+ workflow_dispatch:
11
+ release:
12
+ types: [published]
13
+
14
+ env:
15
+ REGISTRY: ghcr.io
16
+ IMAGE_NAME: ${{ github.repository }}
17
+
18
+ permissions:
19
+ contents: read
20
+ packages: write
21
+
22
+ jobs:
23
+ build-and-push:
24
+ name: Build and Push Docker Image
25
+ runs-on: ubuntu-latest
26
+ permissions:
27
+ contents: read
28
+ packages: write
29
+ id-token: write
30
+
31
+ steps:
32
+ - name: Checkout code
33
+ uses: actions/checkout@v4
34
+
35
+ - name: Set up Docker Buildx
36
+ uses: docker/setup-buildx-action@v3
37
+
38
+ - name: Log in to GitHub Container Registry
39
+ uses: docker/login-action@v3
40
+ with:
41
+ registry: ${{ env.REGISTRY }}
42
+ username: ${{ github.actor }}
43
+ password: ${{ secrets.GITHUB_TOKEN }}
44
+
45
+ - name: Extract metadata (tags, labels) for Docker
46
+ id: meta
47
+ uses: docker/metadata-action@v5
48
+ with:
49
+ images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
50
+ tags: |
51
+ type=ref,event=branch
52
+ type=ref,event=pr
53
+ type=semver,pattern={{version}}
54
+ type=semver,pattern={{major}}.{{minor}}
55
+ type=semver,pattern={{major}}
56
+ type=sha,prefix={{branch}}-
57
+ type=raw,value=latest,enable={{is_default_branch}}
58
+
59
+ - name: Build Docker image (PR)
60
+ if: github.event_name == 'pull_request'
61
+ uses: docker/build-push-action@v5
62
+ with:
63
+ context: .
64
+ file: ./docker/dockerfile
65
+ push: false
66
+ tags: ${{ steps.meta.outputs.tags }}
67
+ labels: ${{ steps.meta.outputs.labels }}
68
+ cache-from: type=gha
69
+ cache-to: type=gha,mode=max
70
+
71
+ - name: Build and push Docker image
72
+ if: github.event_name != 'pull_request'
73
+ uses: docker/build-push-action@v5
74
+ with:
75
+ context: .
76
+ file: ./docker/dockerfile
77
+ push: true
78
+ tags: ${{ steps.meta.outputs.tags }}
79
+ labels: ${{ steps.meta.outputs.labels }}
80
+ cache-from: type=gha
81
+ cache-to: type=gha,mode=max
82
+ platforms: linux/amd64,linux/arm64
83
+
84
+ - name: Run Trivy vulnerability scanner on image
85
+ if: github.event_name != 'pull_request'
86
+ uses: aquasecurity/trivy-action@master
87
+ with:
88
+ image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.meta.outputs.version }}
89
+ format: 'sarif'
90
+ output: 'trivy-image-results.sarif'
91
+ severity: 'CRITICAL,HIGH'
92
+
93
+ - name: Upload Trivy scan results to GitHub Security tab
94
+ if: github.event_name != 'pull_request'
95
+ uses: github/codeql-action/upload-sarif@v3
96
+ with:
97
+ sarif_file: 'trivy-image-results.sarif'
98
+
99
+ - name: Generate artifact attestation
100
+ if: github.event_name != 'pull_request'
101
+ uses: actions/attest-build-provenance@v1
102
+ with:
103
+ subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
104
+ subject-digest: ${{ steps.meta.outputs.digest }}
105
+ push-to-registry: true
106
+
107
+ test-image:
108
+ name: Test Docker Image
109
+ runs-on: ubuntu-latest
110
+ needs: build-and-push
111
+ if: github.event_name != 'pull_request'
112
+ permissions:
113
+ contents: read
114
+ packages: read
115
+
116
+ steps:
117
+ - name: Log in to GitHub Container Registry
118
+ uses: docker/login-action@v3
119
+ with:
120
+ registry: ${{ env.REGISTRY }}
121
+ username: ${{ github.actor }}
122
+ password: ${{ secrets.GITHUB_TOKEN }}
123
+
124
+ - name: Pull Docker image
125
+ run: |
126
+ docker pull ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
127
+
128
+ - name: Test Docker image
129
+ run: |
130
+ docker run --rm ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest python -c "import llmguardian; print(llmguardian.__version__)"
131
+
132
+ - name: Check image size
133
+ run: |
134
+ docker images ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest --format "{{.Size}}"
.github/workflows/security-scan.yml ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ name: Security Scan
2
+
3
+ on:
4
+ push:
5
+ branches: [ main, develop ]
6
+ pull_request:
7
+ branches: [ main, develop ]
8
+ schedule:
9
+ # Run security scan daily at 2 AM UTC
10
+ - cron: '0 2 * * *'
11
+ workflow_dispatch:
12
+
13
+ permissions:
14
+ contents: read
15
+ security-events: write
16
+
17
+ jobs:
18
+ trivy-repo-scan:
19
+ name: Trivy Repository Scan
20
+ runs-on: ubuntu-latest
21
+ permissions:
22
+ contents: read
23
+ security-events: write
24
+
25
+ steps:
26
+ - name: Checkout code
27
+ uses: actions/checkout@v4
28
+
29
+ - name: Run Trivy vulnerability scanner in repo mode
30
+ uses: aquasecurity/trivy-action@master
31
+ with:
32
+ scan-type: 'fs'
33
+ scan-ref: '.'
34
+ format: 'sarif'
35
+ output: 'trivy-results.sarif'
36
+ severity: 'CRITICAL,HIGH,MEDIUM'
37
+ ignore-unfixed: true
38
+
39
+ - name: Upload Trivy results to GitHub Security tab
40
+ uses: github/codeql-action/upload-sarif@v3
41
+ if: always()
42
+ with:
43
+ sarif_file: 'trivy-results.sarif'
44
+
45
+ - name: Run Trivy vulnerability scanner (table output)
46
+ uses: aquasecurity/trivy-action@master
47
+ with:
48
+ scan-type: 'fs'
49
+ scan-ref: '.'
50
+ format: 'table'
51
+ severity: 'CRITICAL,HIGH,MEDIUM'
52
+ ignore-unfixed: true
53
+
54
+ trivy-config-scan:
55
+ name: Trivy Config Scan
56
+ runs-on: ubuntu-latest
57
+ permissions:
58
+ contents: read
59
+ security-events: write
60
+
61
+ steps:
62
+ - name: Checkout code
63
+ uses: actions/checkout@v4
64
+
65
+ - name: Run Trivy config scanner
66
+ uses: aquasecurity/trivy-action@master
67
+ with:
68
+ scan-type: 'config'
69
+ scan-ref: '.'
70
+ format: 'sarif'
71
+ output: 'trivy-config-results.sarif'
72
+ exit-code: '0'
73
+
74
+ - name: Upload Trivy config results to GitHub Security tab
75
+ uses: github/codeql-action/upload-sarif@v3
76
+ if: always()
77
+ with:
78
+ sarif_file: 'trivy-config-results.sarif'
79
+
80
+ dependency-review:
81
+ name: Dependency Review
82
+ runs-on: ubuntu-latest
83
+ if: github.event_name == 'pull_request'
84
+ permissions:
85
+ contents: read
86
+ pull-requests: write
87
+
88
+ steps:
89
+ - name: Checkout code
90
+ uses: actions/checkout@v4
91
+
92
+ - name: Dependency Review
93
+ uses: actions/dependency-review-action@v4
94
+ with:
95
+ fail-on-severity: high
96
+ comment-summary-in-pr: true
97
+
98
+ python-safety-check:
99
+ name: Python Safety Check
100
+ runs-on: ubuntu-latest
101
+ permissions:
102
+ contents: read
103
+
104
+ steps:
105
+ - name: Checkout code
106
+ uses: actions/checkout@v4
107
+
108
+ - name: Set up Python
109
+ uses: actions/setup-python@v5
110
+ with:
111
+ python-version: '3.11'
112
+ cache: 'pip'
113
+
114
+ - name: Install safety
115
+ run: pip install safety
116
+
117
+ - name: Run safety check
118
+ run: |
119
+ pip install -r requirements.txt
120
+ safety check --json
121
+ continue-on-error: true
.gitignore CHANGED
@@ -167,3 +167,4 @@ cython_debug/
167
  CNAME
168
  CLAUDE.md
169
  PROJECT.md
 
 
167
  CNAME
168
  CLAUDE.md
169
  PROJECT.md
170
+ GITHUB_ACTIONS_SUMMARY.md
docker/README.md CHANGED
@@ -1 +1,160 @@
1
- # Docker configuration
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Docker Configuration
2
+
3
+ This directory contains Docker configuration for LLMGuardian.
4
+
5
+ ## Quick Start
6
+
7
+ ### Using Pre-built Images from GitHub Container Registry
8
+
9
+ Pull and run the latest image:
10
+
11
+ ```bash
12
+ docker pull ghcr.io/dewitt4/llmguardian:latest
13
+ docker run -p 8000:8000 -p 8501:8501 ghcr.io/dewitt4/llmguardian:latest
14
+ ```
15
+
16
+ ### Building Locally
17
+
18
+ Build the Docker image:
19
+
20
+ ```bash
21
+ docker build -f docker/dockerfile -t llmguardian:local .
22
+ ```
23
+
24
+ Run the container:
25
+
26
+ ```bash
27
+ docker run -p 8000:8000 -p 8501:8501 llmguardian:local
28
+ ```
29
+
30
+ ## Available Tags
31
+
32
+ - `latest` - Latest stable release from main branch
33
+ - `v*.*.*` - Specific version tags (e.g., v1.0.0)
34
+ - `main` - Latest commit on main branch
35
+ - `develop` - Latest commit on develop branch
36
+
37
+ ## Environment Variables
38
+
39
+ Configure the container using environment variables:
40
+
41
+ ```bash
42
+ docker run -p 8000:8000 \
43
+ -e SECURITY_RISK_THRESHOLD=8 \
44
+ -e LOG_LEVEL=DEBUG \
45
+ -e API_SERVER_PORT=8000 \
46
+ ghcr.io/dewitt4/llmguardian:latest
47
+ ```
48
+
49
+ See `.env.example` in the root directory for all available environment variables.
50
+
51
+ ## Exposed Ports
52
+
53
+ - `8000` - API Server
54
+ - `8501` - Dashboard (Streamlit)
55
+
56
+ ## Volume Mounts
57
+
58
+ Mount volumes for persistent data:
59
+
60
+ ```bash
61
+ docker run -p 8000:8000 \
62
+ -v $(pwd)/logs:/app/logs \
63
+ -v $(pwd)/data:/app/data \
64
+ ghcr.io/dewitt4/llmguardian:latest
65
+ ```
66
+
67
+ ## Docker Compose (Example)
68
+
69
+ Create a `docker-compose.yml` file:
70
+
71
+ ```yaml
72
+ version: '3.8'
73
+
74
+ services:
75
+ llmguardian-api:
76
+ image: ghcr.io/dewitt4/llmguardian:latest
77
+ ports:
78
+ - "8000:8000"
79
+ environment:
80
+ - LOG_LEVEL=INFO
81
+ - SECURITY_RISK_THRESHOLD=7
82
+ volumes:
83
+ - ./logs:/app/logs
84
+ - ./data:/app/data
85
+ restart: unless-stopped
86
+
87
+ llmguardian-dashboard:
88
+ image: ghcr.io/dewitt4/llmguardian:latest
89
+ command: ["streamlit", "run", "src/llmguardian/dashboard/app.py"]
90
+ ports:
91
+ - "8501:8501"
92
+ environment:
93
+ - DASHBOARD_PORT=8501
94
+ - DASHBOARD_HOST=0.0.0.0
95
+ depends_on:
96
+ - llmguardian-api
97
+ restart: unless-stopped
98
+ ```
99
+
100
+ Run with:
101
+
102
+ ```bash
103
+ docker-compose up -d
104
+ ```
105
+
106
+ ## Health Check
107
+
108
+ The container includes a health check endpoint:
109
+
110
+ ```bash
111
+ curl http://localhost:8000/health
112
+ ```
113
+
114
+ ## Security Scanning
115
+
116
+ All published images are automatically scanned with Trivy for vulnerabilities. Check the [Security tab](https://github.com/dewitt4/LLMGuardian/security) for scan results.
117
+
118
+ ## Multi-Architecture Support
119
+
120
+ Images are built for both AMD64 and ARM64 architectures:
121
+
122
+ ```bash
123
+ # Automatically pulls the correct architecture
124
+ docker pull ghcr.io/dewitt4/llmguardian:latest
125
+ ```
126
+
127
+ ## Troubleshooting
128
+
129
+ ### Permission Issues
130
+
131
+ If you encounter permission issues with volume mounts:
132
+
133
+ ```bash
134
+ docker run --user $(id -u):$(id -g) \
135
+ -v $(pwd)/logs:/app/logs \
136
+ ghcr.io/dewitt4/llmguardian:latest
137
+ ```
138
+
139
+ ### View Logs
140
+
141
+ ```bash
142
+ docker logs <container-id>
143
+ ```
144
+
145
+ ### Interactive Shell
146
+
147
+ ```bash
148
+ docker run -it --entrypoint /bin/bash ghcr.io/dewitt4/llmguardian:latest
149
+ ```
150
+
151
+ ## CI/CD Integration
152
+
153
+ Images are automatically built and published via GitHub Actions:
154
+
155
+ - **On push to main**: Builds and publishes `latest` tag
156
+ - **On version tags**: Builds and publishes version-specific tags
157
+ - **On pull requests**: Builds image but doesn't publish
158
+ - **Daily security scans**: Automated Trivy scans
159
+
160
+ See `.github/workflows/docker-publish.yml` for workflow details.
docker/dockerfile CHANGED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # LLMGuardian Docker Image
2
+ FROM python:3.11-slim
3
+
4
+ # Set environment variables
5
+ ENV PYTHONUNBUFFERED=1 \
6
+ PYTHONDONTWRITEBYTECODE=1 \
7
+ PIP_NO_CACHE_DIR=1 \
8
+ PIP_DISABLE_PIP_VERSION_CHECK=1
9
+
10
+ # Set working directory
11
+ WORKDIR /app
12
+
13
+ # Install system dependencies
14
+ RUN apt-get update && apt-get install -y --no-install-recommends \
15
+ gcc \
16
+ git \
17
+ && rm -rf /var/lib/apt/lists/*
18
+
19
+ # Copy requirements files
20
+ COPY requirements/ /app/requirements/
21
+ COPY requirements.txt /app/
22
+
23
+ # Install Python dependencies
24
+ RUN pip install --upgrade pip && \
25
+ pip install -r requirements.txt
26
+
27
+ # Copy source code
28
+ COPY src/ /app/src/
29
+ COPY setup.py /app/
30
+ COPY pyproject.toml /app/
31
+ COPY README.md /app/
32
+ COPY LICENSE /app/
33
+
34
+ # Install the package
35
+ RUN pip install -e .
36
+
37
+ # Create necessary directories
38
+ RUN mkdir -p /app/logs /app/data /app/.cache
39
+
40
+ # Expose ports for API and Dashboard
41
+ EXPOSE 8000 8501
42
+
43
+ # Add health check
44
+ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
45
+ CMD python -c "import requests; requests.get('http://localhost:8000/health')" || exit 1
46
+
47
+ # Default command (can be overridden)
48
+ CMD ["python", "-m", "llmguardian.api.app"]
src/llmguardian/api/routes.py CHANGED
@@ -9,6 +9,12 @@ from .security import verify_token
9
  router = APIRouter()
10
 
11
 
 
 
 
 
 
 
12
  @router.post("/scan", response_model=SecurityResponse)
13
  async def scan_content(request: SecurityRequest, token: str = Depends(verify_token)):
14
  try:
 
9
  router = APIRouter()
10
 
11
 
12
+ @router.get("/health")
13
+ async def health_check():
14
+ """Health check endpoint for container orchestration"""
15
+ return {"status": "healthy", "service": "llmguardian"}
16
+
17
+
18
  @router.post("/scan", response_model=SecurityResponse)
19
  async def scan_content(request: SecurityRequest, token: str = Depends(verify_token)):
20
  try: