diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..10e9896 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +.git +.gitignore +__pycache__ +*.pyc +*.pyo +.env +.venv +venv +*.egg-info +.pytest_cache +.coverage +htmlcov \ No newline at end of file diff --git a/.gitea/workflows/docker.yaml b/.gitea/workflows/docker.yaml new file mode 100644 index 0000000..9ad1966 --- /dev/null +++ b/.gitea/workflows/docker.yaml @@ -0,0 +1,54 @@ +name: Build and Push Docker Image + +on: + push: + branches: + - main + +env: + REGISTRY: repositry.talutasku.ee + IMAGE_NAME: my-python-app + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to registry + uses: docker/login-action@v3 + with: + registry: ${{ env.REGISTRY }} + username: ${{ secrets.REGISTRY_USERNAME }} + password: ${{ secrets.REGISTRY_PASSWORD }} + + - name: Extract git SHA + id: vars + run: echo "sha=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + + - name: Build and push Docker image + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: | + ${{ env.REGISTRY }}/v2/${{ env.IMAGE_NAME }}:${{ steps.vars.outputs.sha }} + ${{ env.REGISTRY }}/v2/${{ env.IMAGE_NAME }}:latest + cache-from: type=gha + cache-to: type=gha,mode=max + + - name: Update image tag file + run: | + echo "${{ steps.vars.outputs.sha }}" > k8s/image-tag.txt + + - name: Commit and push image tag + run: | + git config --local user.email "gitea-ci@example.com" + git config --local user.name "Gitea CI" + git add k8s/image-tag.txt + git commit -m "Update image tag to ${{ steps.vars.outputs.sha }}" || exit 0 + git push \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f197fa5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +FROM python:3.11-slim as builder + +WORKDIR /build +COPY requirements.txt . +RUN pip install --no-cache-dir --prefix=/install -r requirements.txt + +FROM python:3.11-slim + +WORKDIR /app +COPY --from=builder /install /usr/local +COPY app.py . + +EXPOSE 8000 +CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "8000"] \ No newline at end of file diff --git a/app.py b/app.py new file mode 100644 index 0000000..9687e2e --- /dev/null +++ b/app.py @@ -0,0 +1,13 @@ +from fastapi import FastAPI + +app = FastAPI() + + +@app.get("/") +async def root(): + return {"message": "Hello, World!"} + + +@app.get("/health") +async def health(): + return {"status": "healthy"} \ No newline at end of file diff --git a/k8s/all-in-one.yaml b/k8s/all-in-one.yaml new file mode 100644 index 0000000..f0c0051 --- /dev/null +++ b/k8s/all-in-one.yaml @@ -0,0 +1,51 @@ +apiVersion: v1 +kind: Pod +metadata: + name: python-app + labels: + app: python-app +spec: + containers: + - name: python-app + image: repositry.talutasku.ee/v2/my-python-app:latest + ports: + - containerPort: 8000 + resources: + limits: + memory: "128Mi" + cpu: "500m" + requests: + memory: "64Mi" + cpu: "100m" +--- +apiVersion: v1 +kind: Service +metadata: + name: python-app +spec: + selector: + app: python-app + ports: + - protocol: TCP + port: 80 + targetPort: 8000 + type: ClusterIP +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: python-app + annotations: + kubernetes.io/ingress.class: traefik +spec: + rules: + - host: python-app.talutasku.ee + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: python-app + port: + number: 80 \ No newline at end of file diff --git a/k8s/image-tag.txt b/k8s/image-tag.txt new file mode 100644 index 0000000..b9bc2fd --- /dev/null +++ b/k8s/image-tag.txt @@ -0,0 +1 @@ +latest \ No newline at end of file diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..6a039e7 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +fastapi>=0.100.0 +uvicorn[standard]>=0.23.0 \ No newline at end of file