From 37243df9aaf0f30f5eac47ad0becfd983d9133aa Mon Sep 17 00:00:00 2001 From: ITO Mac Date: Tue, 14 Apr 2026 11:02:09 +0200 Subject: [PATCH] cicd --- .dockerignore | 10 +++ .gitea/workflows/ci.yaml | 55 +++++++++++++ .gitignore | 6 +- Dockerfile | 24 ++++++ app/main.py | 123 ++++++++++++++++++++++++++++++ app/requirements.txt | 2 + k8s/distribuirani/deployment.yaml | 14 +++- k8s/distribuirani/secret.yaml | 9 +++ 8 files changed, 241 insertions(+), 2 deletions(-) create mode 100644 .dockerignore create mode 100644 .gitea/workflows/ci.yaml create mode 100644 Dockerfile create mode 100644 app/main.py create mode 100644 app/requirements.txt create mode 100644 k8s/distribuirani/secret.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..c2e9c87 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,10 @@ +.git +.gitignore +*.md +LICENSE +kubeconfig-*.yaml +k8s/ +.gitea/ +__pycache__ +*.pyc +.env diff --git a/.gitea/workflows/ci.yaml b/.gitea/workflows/ci.yaml new file mode 100644 index 0000000..f458162 --- /dev/null +++ b/.gitea/workflows/ci.yaml @@ -0,0 +1,55 @@ +name: CI/CD Pipeline + +on: + push: + branches: [main] + +env: + REGISTRY: git.fpmoz.sum.ba + IMAGE_NAME: blazp04/distribuirani + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - name: Checkout koda + uses: actions/checkout@v4 + + - name: Postavi Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Prijava na Gitea Container Registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Generiraj tagove za image + id: meta + run: | + SHORT_SHA=$(echo "${{ gitea.sha }}" | cut -c1-7) + echo "short_sha=${SHORT_SHA}" >> "$GITHUB_OUTPUT" + echo "tags=${REGISTRY}/${IMAGE_NAME}:${SHORT_SHA},${REGISTRY}/${IMAGE_NAME}:latest" >> "$GITHUB_OUTPUT" + + - name: Build i push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: ${{ steps.meta.outputs.tags }} + cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest + cache-to: type=inline + + - name: Ažuriraj image tag u deployment manifestu + run: | + SHORT_SHA=${{ steps.meta.outputs.short_sha }} + sed -i "s|image: ${REGISTRY}/${IMAGE_NAME}:.*|image: ${REGISTRY}/${IMAGE_NAME}:${SHORT_SHA}|" k8s/distribuirani/deployment.yaml + cat k8s/distribuirani/deployment.yaml + + - name: Commit i push ažuriranog manifesta + run: | + git config user.name "Gitea Actions" + git config user.email "actions@git.fpmoz.sum.ba" + git add k8s/distribuirani/deployment.yaml + git diff --cached --quiet && echo "Nema promjena" || (git commit -m "ci: update image tag to ${{ steps.meta.outputs.short_sha }} [skip ci]" && git push) diff --git a/.gitignore b/.gitignore index f54494f..78cbd96 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -kubeconfig-Blazp04.yaml +kubeconfig-*.yaml +.env +__pycache__/ +*.pyc +*.pyo diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..811df7c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,24 @@ +# ---------- build stage ---------- +FROM python:3.12-slim AS builder + +WORKDIR /build +COPY app/requirements.txt . +RUN pip install --no-cache-dir --prefix=/install -r requirements.txt + +# ---------- runtime stage ---------- +FROM python:3.12-slim + +LABEL maintainer="blazp04" +LABEL org.opencontainers.image.source="https://git.fpmoz.sum.ba/blazp04/distribuirani" + +RUN adduser --disabled-password --no-create-home appuser + +WORKDIR /app +COPY --from=builder /install /usr/local +COPY app/ . + +USER appuser + +EXPOSE 8000 + +CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"] diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..fc3dd5f --- /dev/null +++ b/app/main.py @@ -0,0 +1,123 @@ +import os +import datetime +from fastapi import FastAPI +from fastapi.responses import HTMLResponse + +app = FastAPI(title="Distribuirani Sustavi - FPMOZ") + +SERVICE_NAME = os.getenv("SERVICE_NAME", "distribuirani-service") +LOG_LEVEL = os.getenv("LOG_LEVEL", "info") +WELCOME_MSG = os.getenv("WELCOME_MSG", "Pozdrav iz FPMOZ k3s clustera!") + + +@app.get("/", response_class=HTMLResponse) +def root(): + return f""" + + + + + {SERVICE_NAME} + + + +
+

Distribuirani Sustavi

+

{WELCOME_MSG}

+
+
+ Servis + {SERVICE_NAME} +
+
+ Hostname + {os.getenv("HOSTNAME", "local")} +
+
+ Log Level + {LOG_LEVEL} +
+
+ Vrijeme + {datetime.datetime.now(datetime.timezone.utc).strftime("%Y-%m-%d %H:%M:%S UTC")} +
+
+ FPMOZ K3s Cluster • GitOps CI/CD +
+ +""" + + +@app.get("/health") +def health(): + return {"status": "ok"} + + +@app.get("/info") +def info(): + return { + "service": SERVICE_NAME, + "hostname": os.getenv("HOSTNAME", "local"), + "log_level": LOG_LEVEL, + "welcome": WELCOME_MSG, + "timestamp": datetime.datetime.now(datetime.timezone.utc).isoformat(), + } diff --git a/app/requirements.txt b/app/requirements.txt new file mode 100644 index 0000000..3fb50f0 --- /dev/null +++ b/app/requirements.txt @@ -0,0 +1,2 @@ +fastapi==0.115.6 +uvicorn[standard]==0.34.0 diff --git a/k8s/distribuirani/deployment.yaml b/k8s/distribuirani/deployment.yaml index 9a1488a..553caf2 100644 --- a/k8s/distribuirani/deployment.yaml +++ b/k8s/distribuirani/deployment.yaml @@ -15,7 +15,7 @@ spec: spec: containers: - name: distribuirani - image: git.fpmoz.sum.ba/blazp04/distribuirani:1.0 + image: git.fpmoz.sum.ba/blazp04/distribuirani:latest ports: - containerPort: 8000 envFrom: @@ -32,6 +32,18 @@ spec: secretKeyRef: name: distribuirani-secret key: API_KEY + livenessProbe: + httpGet: + path: /health + port: 8000 + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + httpGet: + path: /health + port: 8000 + initialDelaySeconds: 3 + periodSeconds: 5 resources: requests: memory: "64Mi" diff --git a/k8s/distribuirani/secret.yaml b/k8s/distribuirani/secret.yaml new file mode 100644 index 0000000..7377e04 --- /dev/null +++ b/k8s/distribuirani/secret.yaml @@ -0,0 +1,9 @@ +apiVersion: v1 +kind: Secret +metadata: + name: distribuirani-secret + namespace: student-blazp04 +type: Opaque +stringData: + DB_PASSWORD: "SUPERTAJNIPASSWD" + API_KEY: "APIKEYNEKI DEMO"