Skip to content

Commit 8a1fdd8

Browse files
Dev NirwalDev Nirwal
authored andcommitted
CI/CD Pipeline k8s
1 parent b57eb57 commit 8a1fdd8

File tree

12 files changed

+278
-8
lines changed

12 files changed

+278
-8
lines changed

.github/workflows/deploy.yml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
name: CI/CD Pipeline
2+
3+
on:
4+
push:
5+
branches: [ "main" ] # Trigger the pipeline on pushes to the main branch
6+
pull_request:
7+
branches: [ "main" ]
8+
9+
env:
10+
# GHCR image name: ghcr.io/owner/repo-name
11+
IMAGE_NAME: ghcr.io/${{ github.repository_owner }}/simple-rag
12+
13+
jobs:
14+
build-and-push:
15+
runs-on: ubuntu-latest
16+
permissions:
17+
contents: read
18+
packages: write # Required for pushing to GHCR
19+
steps:
20+
- name: Check out the repo
21+
uses: actions/checkout@v4
22+
23+
- name: Log in to GitHub Container Registry
24+
uses: docker/login-action@v3
25+
with:
26+
registry: ghcr.io
27+
username: ${{ github.actor }}
28+
password: ${{ secrets.GITHUB_TOKEN }}
29+
30+
- name: Build and push Docker image
31+
uses: docker/build-push-action@v5
32+
with:
33+
context: .
34+
push: ${{ github.event_name != 'pull_request' }}
35+
tags: |
36+
${{ env.IMAGE_NAME }}:latest
37+
${{ env.IMAGE_NAME }}:${{ github.sha }}
38+
# Ensure image is lowered for GHCR if repository name contains uppercase
39+
labels: |
40+
org.opencontainers.image.source=https://github.com/${{ github.repository }}
41+
42+
# Optional job to automatically update kubernetes deployment.
43+
# This requires a kubernetes cluster setup and kubeconfig secret.
44+
deploy:
45+
needs: build-and-push
46+
if: github.event_name == 'push'
47+
runs-on: ubuntu-latest
48+
steps:
49+
- name: Check out the repo
50+
uses: actions/checkout@v4
51+
52+
# Example step using an external tool to deploy, or setup kubectl
53+
- name: Set up kubectl
54+
uses: azure/setup-kubectl@v3
55+
with:
56+
version: 'latest'
57+
58+
- name: Configure Kubernetes context
59+
uses: azure/k8s-set-context@v3
60+
with:
61+
method: kubeconfig
62+
kubeconfig: ${{ secrets.KUBECONFIG }}
63+
64+
- name: Update deployment image
65+
run: |
66+
kubectl set image deployment/simple-rag-deployment simple-rag=${{ env.IMAGE_NAME }}:${{ github.sha }}
67+
kubectl rollout status deployment/simple-rag-deployment

.gitignore

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Django
2+
*.log
3+
*.pot
4+
*.pyc
5+
__pycache__/
6+
local_settings.py
7+
db.sqlite3
8+
db.sqlite3-journal
9+
media/
10+
staticfiles/
11+
vector_stores/
12+
13+
# OS
14+
.DS_Store
15+
.DS_Store?
16+
._*
17+
.Spotlight-V100
18+
.Trashes
19+
ehthumbs.db
20+
Thumbs.db
21+
22+
# Environments
23+
.env
24+
.venv
25+
env/
26+
venv/
27+
ENV/
28+
v/
29+
30+
# IDEs
31+
.vscode/
32+
.idea/
33+
34+
# Docker
35+
.dockerignore
36+
37+
# Kubernetes
38+
k8s/secrets.yaml

Dockerfile

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
FROM python:3.10-slim
2+
3+
# Install system dependencies including sqlite3
4+
RUN apt-get update && apt-get install -y --no-install-recommends \
5+
build-essential \
6+
sqlite3 \
7+
libsqlite3-dev \
8+
&& rm -rf /var/lib/apt/lists/*
9+
10+
WORKDIR /app
11+
12+
# Install Python dependencies
13+
COPY requirements.txt .
14+
RUN pip install --no-cache-dir -r requirements.txt
15+
16+
# Copy application code
17+
COPY . .
18+
19+
# Create a data directory that we will mount as a persistent volume
20+
RUN mkdir -p /app/data
21+
22+
# Expose port
23+
EXPOSE 8000
24+
25+
# Set environment variables
26+
ENV PYTHONUNBUFFERED=1
27+
ENV DJANGO_SETTINGS_MODULE="pdf_chat_project.settings"
28+
# Default DATA_DIR (can be overridden by k8s but this is a fallback)
29+
ENV DATA_DIR="/app/data"
30+
31+
# Command to run the application using Gunicorn
32+
CMD ["sh", "-c", "python manage.py migrate && python manage.py collectstatic --noinput && gunicorn pdf_chat_project.wsgi:application --bind 0.0.0.0:8000 --workers 3"]

chat/views.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def upload_pdf(request):
2222
pdf_doc = form.save()
2323

2424
# Ensure vector_stores directory exists
25-
vector_store_root = os.path.join(settings.BASE_DIR, 'vector_stores')
25+
vector_store_root = os.path.join(getattr(settings, 'DATA_DIR', settings.BASE_DIR), 'vector_stores')
2626
if not os.path.exists(vector_store_root):
2727
os.makedirs(vector_store_root)
2828

k8s/deployment.yaml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: simple-rag-deployment
5+
labels:
6+
app: simple-rag
7+
spec:
8+
replicas: 1 # Important: Because we use SQLite, we shouldn't scale beyond 1 replica safely without a shared volume that supports multiple concurrent writers properly, and even then SQLite handles it poorly. If you need more replicas, migrate to PostgreSQL.
9+
selector:
10+
matchLabels:
11+
app: simple-rag
12+
template:
13+
metadata:
14+
labels:
15+
app: simple-rag
16+
spec:
17+
containers:
18+
- name: simple-rag
19+
# UPDATE: Replace <GITHUB_OWNER> with your GitHub username or organization name
20+
image: ghcr.io/<GITHUB_OWNER>/simple-rag:latest
21+
imagePullPolicy: Always
22+
ports:
23+
- containerPort: 8000
24+
env:
25+
- name: DATA_DIR
26+
value: "/app/data"
27+
- name: DEBUG
28+
value: "False"
29+
- name: ALLOWED_HOSTS
30+
value: "*"
31+
- name: GOOGLE_API_KEY
32+
valueFrom:
33+
secretKeyRef:
34+
name: simple-rag-secrets
35+
key: google-api-key
36+
- name: DATABASE_URL
37+
valueFrom:
38+
secretKeyRef:
39+
name: simple-rag-secrets
40+
key: database-url
41+
volumeMounts:
42+
- name: data-volume
43+
mountPath: /app/data
44+
volumes:
45+
- name: data-volume
46+
persistentVolumeClaim:
47+
claimName: simple-rag-pvc

k8s/postgres-deployment.yaml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: postgres-deployment
5+
spec:
6+
replicas: 1
7+
selector:
8+
matchLabels:
9+
app: postgres
10+
template:
11+
metadata:
12+
labels:
13+
app: postgres
14+
spec:
15+
containers:
16+
- name: postgres
17+
image: postgres:15
18+
ports:
19+
- containerPort: 5432
20+
env:
21+
- name: POSTGRES_DB
22+
value: "simple_rag_db"
23+
- name: POSTGRES_USER
24+
value: "rag_user"
25+
- name: POSTGRES_PASSWORD
26+
valueFrom:
27+
secretKeyRef:
28+
name: simple-rag-secrets
29+
key: postgres-password
30+
volumeMounts:
31+
- name: postgres-storage
32+
mountPath: /var/lib/postgresql/data
33+
volumes:
34+
- name: postgres-storage
35+
persistentVolumeClaim:
36+
claimName: postgres-pvc

k8s/postgres-pvc.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: v1
2+
kind: PersistentVolumeClaim
3+
metadata:
4+
name: postgres-pvc
5+
spec:
6+
accessModes:
7+
- ReadWriteOnce
8+
resources:
9+
requests:
10+
storage: 5Gi

k8s/postgres-service.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: postgres-service
5+
spec:
6+
selector:
7+
app: postgres
8+
ports:
9+
- protocol: TCP
10+
port: 5432
11+
targetPort: 5432

k8s/pvc.yaml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
apiVersion: v1
2+
kind: PersistentVolumeClaim
3+
metadata:
4+
name: simple-rag-pvc
5+
labels:
6+
app: simple-rag
7+
spec:
8+
accessModes:
9+
- ReadWriteOnce
10+
resources:
11+
requests:
12+
storage: 5Gi

k8s/service.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: simple-rag-service
5+
labels:
6+
app: simple-rag
7+
spec:
8+
# Use LoadBalancer if you are on a cloud provider like AWS/GCP, or NodePort/ClusterIP for local k8s (minikube)
9+
type: LoadBalancer
10+
ports:
11+
- port: 80
12+
targetPort: 8000
13+
protocol: TCP
14+
selector:
15+
app: simple-rag

0 commit comments

Comments
 (0)