diff --git a/.env b/.env index 99e4db5..2f16c2d 100644 --- a/.env +++ b/.env @@ -1,6 +1,6 @@ ENVIRONMENT=DEV HOST=localhost PORT=8000 -REDIS_HOST=localhost +REDIS_HOST=redis-container REDIS_PORT=6379 REDIS_DB=0 \ No newline at end of file diff --git a/.github/workflows/build-and-publish.yml b/.github/workflows/build-and-publish.yml new file mode 100644 index 0000000..e63adc4 --- /dev/null +++ b/.github/workflows/build-and-publish.yml @@ -0,0 +1,57 @@ +name: Build and Publish to Docker Hub + +on: + push: + branches: + - master + workflow_dispatch: + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + # Set to "latest" for master branch, or branch name for other branches + IMAGE_TAG: ${{ github.ref_name == 'master' && 'latest' || github.ref_name }} + DOCKER_REPO: ersanjeev/Devops-challanges # Replace with your Docker Hub repository + +jobs: + build-and-publish: + name: Build and Publish to Docker Hub + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_HUB_USERNAME }} + password: ${{ secrets.DOCKER_HUB_ACCESS_TOKEN }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Infer Tag from Branch + id: infer-tag + # Get the branch name from the ref, and replace / with - to make it a valid tag + env: + BRANCH_NAME: ${{ github.ref_name }} + run: | + if [[ $BRANCH_NAME == "master" ]]; then + echo "tag=latest" >> $GITHUB_OUTPUT + else + echo "tag=$(echo $BRANCH_NAME | sed -e 's/\//-/g')" >> $GITHUB_OUTPUT + fi + + - name: Build and Push Docker Image + uses: docker/build-push-action@v5 + with: + context: . + file: ./Dockerfile # Update path if Dockerfile is not in ./docker/ + pull: true + push: true + tags: | + ${{ env.DOCKER_REPO }}:${{ steps.infer-tag.outputs.tag }}, + ${{ env.DOCKER_REPO }}:${{ github.sha }} diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..496ddc5 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,38 @@ + +# Taking python as base image +FROM python:3.9-slim + +# Set the working directory in the container +WORKDIR /app + +# create a user appuser and make it default +RUN groupadd -r appuser && useradd -r -m -g appuser appuser +USER appuser + +# Copy the requirements.txt and install dependencies +COPY requirements.txt . + +# Upgrading the pip and setting the path + +RUN pip install --upgrade pip +ENV PATH="/home/appuser/.local/bin:$PATH" + +# Installing the required library for project +RUN pip install --no-cache-dir -r requirements.txt + +# Copy the full application code in docker image +COPY . . + +# Set environment variables from the .env file +ENV ENVIRONMENT=${ENVIRONMENT} +ENV HOST=${HOST} +ENV PORT=${PORT} +ENV REDIS_HOST=${REDIS_HOST} +ENV REDIS_PORT=${REDIS_PORT} +ENV REDIS_DB=${REDIS_DB} + +# Expose the port the app runs on. +EXPOSE ${PORT} + +# Run the application +CMD ["python", "hello.py"] \ No newline at end of file diff --git a/k8s-manifests/app-service.yml b/k8s-manifests/app-service.yml new file mode 100644 index 0000000..92f7120 --- /dev/null +++ b/k8s-manifests/app-service.yml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Service +metadata: + name: demo-service +spec: + selector: + app: demo-app + ports: + - protocol: TCP + port: 80 # Expose on port 80 within the cluster + targetPort: 8000 # Container port to which the traffic will be forwarded + nodePort: 30080 # External port on each node to access the application + type: NodePort + \ No newline at end of file diff --git a/k8s-manifests/application-deployment.yml b/k8s-manifests/application-deployment.yml new file mode 100644 index 0000000..86e00de --- /dev/null +++ b/k8s-manifests/application-deployment.yml @@ -0,0 +1,32 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: demo-deployment +spec: + replicas: 3 # Ensure 3 replicas for high availability + selector: + matchLabels: + app: demo-app + template: + metadata: + labels: + app: demo-app + spec: + containers: + - name: demo-container + image: ersanjeev/app2:latest # Replace with Docker image + ports: + - containerPort: 8000 # application will run on port 8000 inside container + envFrom: + - configMapRef: + name: application-env-variable # Reference the ConfigMap for non-sensitive envs + resources: + requests: + memory: "100Mi" + cpu: "100m" + limits: + memory: "200Mi" + cpu: "200m" # You can tweak these based on your app's requirements + imagePullSecrets: + - name: regcred + diff --git a/k8s-manifests/configmapfile.yml b/k8s-manifests/configmapfile.yml new file mode 100644 index 0000000..ec5bb42 --- /dev/null +++ b/k8s-manifests/configmapfile.yml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: application-env-variable +data: + ENVIRONMENT: "DEV" + HOST: "localhost" + PORT: "8000" + REDIS_HOST: redis-service + REDIS_PORT: "6379" + REDIS_DB: "0" \ No newline at end of file diff --git a/k8s-manifests/hpafile.yml b/k8s-manifests/hpafile.yml new file mode 100644 index 0000000..8f23d93 --- /dev/null +++ b/k8s-manifests/hpafile.yml @@ -0,0 +1,19 @@ +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: demo-app-hpa + namespace: default +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: demo-deployment + minReplicas: 3 # Minimum replicas for availability + maxReplicas: 10 # Maximum replicas for scaling up based on load + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 50 # Target 50% CPU utilization diff --git a/k8s-manifests/redis-deployment.yml b/k8s-manifests/redis-deployment.yml new file mode 100644 index 0000000..f5a9121 --- /dev/null +++ b/k8s-manifests/redis-deployment.yml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: redis-deployment +spec: + replicas: 1 + selector: + matchLabels: + app: redis + template: + metadata: + labels: + app: redis + spec: + containers: + - name: redis + image: redis:latest + ports: + - containerPort: 6379 diff --git a/k8s-manifests/redis-service.yml b/k8s-manifests/redis-service.yml new file mode 100644 index 0000000..5427392 --- /dev/null +++ b/k8s-manifests/redis-service.yml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: redis-service +spec: + selector: + app: redis + ports: + - protocol: TCP + port: 6379 + targetPort: 6379 \ No newline at end of file diff --git a/k8s-manifests/secrets.yml b/k8s-manifests/secrets.yml new file mode 100644 index 0000000..2bf55b9 --- /dev/null +++ b/k8s-manifests/secrets.yml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: regcred # Name of the secret + namespace: default # Namespace (you can change this if needed) +type: kubernetes.io/dockerconfigjson # Type for Docker registry secret +data: + .dockerconfigjson: ewoJImF1dGhzIjogewoJCSJodHRwczovL2luZGV4LmRvY2tlci5pby92MS8iOiB7CgkJCSJhdXRoIjogIlpYSnpZVzVxWldWMk9rRmhhR0Z1WVdGb1lXNGlOREV4IgoJCX0KCX0KfQ== # Replace with your base64 string