From 39f3033b2ac4d11c623ed8d6245d964266b19d2e Mon Sep 17 00:00:00 2001 From: areeqakbr Date: Mon, 17 Feb 2025 16:18:31 +0700 Subject: [PATCH] adding deployment --- .dockerignore | 14 ++ .gitea/workflows/dev.yaml | 81 +++++++++ deploy/docker/Dockerfile | 18 ++ deploy/kubernetes/dev.yaml | 334 +++++++++++++++++++++++++++++++++++++ 4 files changed, 447 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitea/workflows/dev.yaml create mode 100644 deploy/docker/Dockerfile create mode 100644 deploy/kubernetes/dev.yaml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..837ecc4 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +# Ignore compiled binaries and temp files +*.exe +*.out +*.o +*.a + +# Ignore Go build artifacts +bin/ +pkg/ +vendor/ + +# Ignore git files +.git +.gitignore diff --git a/.gitea/workflows/dev.yaml b/.gitea/workflows/dev.yaml new file mode 100644 index 0000000..d88f44f --- /dev/null +++ b/.gitea/workflows/dev.yaml @@ -0,0 +1,81 @@ +name: Deploy Golang App to Kubernetes Cluster +on: + push: + branches: + - dev + +jobs: + build: + name: Build and push image + runs-on: ubuntu-latest + container: + image: ghcr.io/catthehacker/ubuntu:act-latest + steps: + - name: Check out repository code + uses: actions/checkout@v3 + + - name: Get short SHA + id: get-short-sha + run: | + id=$(echo ${{ github.sha }} | cut -c 1-7) + echo "id=$id" >> $GITHUB_ENV + + - name: Login to registry + uses: docker/login-action@v3 + with: + registry: git.winteraccess.id + username: ${{ vars.REGISTRY_USER }} + password: ${{ secrets.REGISTRY_TOKEN }} + + - name: Build and push to registry + uses: docker/build-push-action@v5 + with: + context: . + file: deploy/docker/Dockerfile + push: true + tags: | + git.winteraccess.id/winter-access/backend_nam:dev-${{ env.id }} + git.winteraccess.id/winter-access/backend_nam:dev + git.winteraccess.id/winter-access/backend_nam:latest + + deploy: + name: Deploy to Kubernetes Cluster + runs-on: ubuntu-latest + needs: + - build + container: + image: ghcr.io/catthehacker/ubuntu:act-latest + steps: + - name: Check out repository code + uses: actions/checkout@v3 + + - name: Get short SHA + id: get-short-sha + run: | + id=$(echo ${{ github.sha }} | cut -c 1-7) + echo "id=$id" >> $GITHUB_ENV + + - name: Create Kubeconfig + run: | + mkdir -p $HOME/.kube + echo "${{ secrets.KUBECONFIG }}" > $HOME/.kube/config + + - name: Setup Kubectl + uses: azure/setup-kubectl@v4 + + - name: Set the Kubernetes context + uses: azure/k8s-set-context@v2 + with: + method: service-account + k8s-url: ${{ vars.KUBE_URL }} + k8s-secret: ${{ secrets.KUBE_SECRET }} + + - name: Deploy to Kubernetes cluster + uses: azure/k8s-deploy@v5 + with: + action: deploy + namespace: nam-backend-dev + manifests: | + deploy/kubernetes/dev.yaml + images: | + git.winteraccess.id/winter-access/backend_nam:dev-${{ env.id }} diff --git a/deploy/docker/Dockerfile b/deploy/docker/Dockerfile new file mode 100644 index 0000000..01f6ffb --- /dev/null +++ b/deploy/docker/Dockerfile @@ -0,0 +1,18 @@ +# Use the official Golang image +FROM golang:1.21 + +# Set the working directory inside the container +WORKDIR /app + +# Copy go.mod and go.sum files and download dependencies +COPY go.mod go.sum ./ +RUN go mod download + +# Copy the rest of the application source code +COPY . . + +# Expose the application's port (change if needed) +EXPOSE 5678 + +# Command to run the application +CMD ["go", "run", "main.go"] diff --git a/deploy/kubernetes/dev.yaml b/deploy/kubernetes/dev.yaml new file mode 100644 index 0000000..9e59999 --- /dev/null +++ b/deploy/kubernetes/dev.yaml @@ -0,0 +1,334 @@ +apiVersion: v1 +kind: Secret +metadata: + name: nam-backend-dev-secret + namespace: nam-backend-dev + labels: + app.kubernetes.io/name: nam-backend-dev + app.kubernetes.io/instance: nam-backend-dev + io.portainer.kubernetes.application.name: nam-backend-dev + io.portainer.kubernetes.application.owner: admin +type: Opaque +data: + DB_PASSWORD: MTIzUVdFYXNkenhjLQ== +--- + +apiVersion: v1 +kind: ConfigMap +metadata: + name: nam-backend-dev-config + namespace: nam-backend-dev + labels: + app.kubernetes.io/name: nam-backend-dev + app.kubernetes.io/instance: nam-backend-dev + io.portainer.kubernetes.application.name: nam-backend-dev + io.portainer.kubernetes.application.owner: admin +data: + ".env": | + DB_HOST=172.16.224.55 + DB_PORT=5433 + DB_NAME=db_asset_network + DB_USER=cifo_asset_network + DB_DRIVER=postgres + API_PORT=5678 + API_LOGIN_URL=https://demo.api-hrm.winteraccess.id/api/v2/auth/login + API_ME_URL=https://demo.api-hrm.winteraccess.id/api/v2/auth/me + API_LOGOUT_URL=https://demo.api-hrm.winteraccess.id/api/v2/auth/logout +--- + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + volume.alpha.kubernetes.io/storage-class: generic + volume.beta.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner + volume.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner + labels: + app.kubernetes.io/name: nam-backend-dev + app.kubernetes.io/instance: nam-backend-dev + io.portainer.kubernetes.application.name: nam-backend-dev + io.portainer.kubernetes.application.owner: admin + name: nam-backend-dev-storage + namespace: nam-backend-dev +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + storageClassName: nfs + volumeMode: Filesystem +--- + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + volume.alpha.kubernetes.io/storage-class: generic + volume.beta.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner + volume.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner + labels: + app.kubernetes.io/name: nam-backend-dev + app.kubernetes.io/instance: nam-backend-dev + io.portainer.kubernetes.application.name: nam-backend-dev + io.portainer.kubernetes.application.owner: admin + name: nam-backend-dev-public + namespace: nam-backend-dev +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + storageClassName: nfs + volumeMode: Filesystem +--- + +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + annotations: + volume.alpha.kubernetes.io/storage-class: generic + volume.beta.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner + volume.kubernetes.io/storage-provisioner: cluster.local/nfs-nfs-subdir-external-provisioner + labels: + app.kubernetes.io/instance: nam-backend-dev + app.kubernetes.io/name: nam-backend-dev + io.portainer.kubernetes.application.name: nam-backend-dev + io.portainer.kubernetes.application.owner: admin + name: nam-backend-dev-public + namespace: nam-backend-dev +spec: + accessModes: + - ReadWriteMany + resources: + requests: + storage: 1Gi + storageClassName: nfs + volumeMode: Filesystem +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: nam-backend-dev + namespace: nam-backend-dev + labels: + app.kubernetes.io/instance: nam-backend-dev + app.kubernetes.io/name: nam-backend-dev + io.portainer.kubernetes.application.name: nam-backend-dev + io.portainer.kubernetes.application.owner: admin +spec: + progressDeadlineSeconds: 600 + replicas: 3 + revisionHistoryLimit: 10 + selector: + matchLabels: + app.kubernetes.io/instance: nam-backend-dev + app.kubernetes.io/name: nam-backend-dev + strategy: + rollingUpdate: + maxSurge: 1 + maxUnavailable: 1 + type: RollingUpdate + template: + metadata: + labels: + app.kubernetes.io/instance: nam-backend-dev + app.kubernetes.io/name: nam-backend-dev + spec: + affinity: + podAntiAffinity: + preferredDuringSchedulingIgnoredDuringExecution: + - weight: 100 + podAffinityTerm: + labelSelector: + matchLabels: + app.kubernetes.io/instance: nam-backend-dev + app.kubernetes.io/name: nam-backend-dev + topologyKey: "kubernetes.io/hostname" + containers: + - name: web + image: https://git.winteraccess.id/winter-access/backend_nam:dev + imagePullPolicy: Always + env: + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: nam-backend-dev-secret + key: DB_PASSWORD + resources: + limits: + cpu: "250m" + memory: 1024M + requests: + cpu: "100m" + memory: 512M + ports: + - containerPort: 80 + name: http + protocol: TCP + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + add: ["NET_ADMIN", "SYS_TIME"] + readOnlyRootFilesystem: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /app + name: app + initContainers: + - name: init + image: https://git.winteraccess.id/winter-access/backend_nam:dev + imagePullPolicy: Always + command: ["/scripts/initialize"] + env: + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: nam-backend-dev-secret + key: DB_PASSWORD + resources: + limits: + cpu: "250m" + memory: 1024M + requests: + cpu: "100m" + memory: 512M + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + add: ["NET_ADMIN", "SYS_TIME"] + readOnlyRootFilesystem: true + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + volumeMounts: + - mountPath: /app + name: app + imagePullSecrets: + - name: winter-registry + dnsPolicy: ClusterFirst + restartPolicy: Always + schedulerName: default-scheduler + securityContext: + runAsUser: 10001 + runAsGroup: 10001 + fsGroup: 10001 + runAsNonRoot: true + terminationGracePeriodSeconds: 30 + volumes: + - name: cache + emptyDir: {} + - name: run + emptyDir: {} + - name: logs + emptyDir: {} + - name: tmp + emptyDir: {} + - name: psysh + emptyDir: {} + - name: config + configMap: + name: nam-backend-dev-config + - name: public + persistentVolumeClaim: + claimName: nam-backend-dev-public + - name: storage + persistentVolumeClaim: + claimName: nam-backend-dev-storage +--- + +apiVersion: v1 +kind: Service +metadata: + name: nam-backend-dev + namespace: nam-backend-dev + annotations: + traefik.ingress.kubernetes.io/service.sticky.cookie: "true" + traefik.ingress.kubernetes.io/service.sticky.cookie.name: "backend_nam_dev" + traefik.ingress.kubernetes.io/service.sticky.cookie.secure: "true" + traefik.ingress.kubernetes.io/service.sticky.cookie.samesite: "none" + labels: + app.kubernetes.io/name: nam-backend-dev + app.kubernetes.io/instance: nam-backend-dev + io.portainer.kubernetes.application.name: nam-backend-dev + io.portainer.kubernetes.application.owner: admin +spec: + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: http + port: 80 + protocol: TCP + targetPort: 5678 + selector: + app.kubernetes.io/instance: nam-backend-dev + app.kubernetes.io/name: nam-backend-dev + sessionAffinity: None + type: ClusterIP + +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + kubernetes.io/ingress.class: traefik + traefik.ingress.kubernetes.io/router.entrypoints: web + traefik.ingress.kubernetes.io/router.middlewares: default-https-redirect@kubernetescrd + labels: + app.kubernetes.io/instance: nam-backend-dev + app.kubernetes.io/name: nam-backend-dev + io.portainer.kubernetes.application.name: nam-backend-dev + io.portainer.kubernetes.application.owner: admin + name: nam-backend-dev-http + namespace: nam-backend-dev +spec: + ingressClassName: traefik + rules: + - host: dev-nam.winteraccess.id + http: + paths: + - backend: + service: + name: nam-backend-dev + port: + number: 80 + path: / + pathType: Prefix +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + annotations: + cert-manager.io/cluster-issuer: letsencrypt-production + kubernetes.io/ingress.class: traefik + traefik.ingress.kubernetes.io/router.entrypoints: websecure + labels: + app.kubernetes.io/instance: nam-backend-dev + app.kubernetes.io/name: nam-backend-dev + io.portainer.kubernetes.application.name: nam-backend-dev + io.portainer.kubernetes.application.owner: admin + name: nam-backend-dev-https + namespace: nam-backend-dev +spec: + ingressClassName: traefik + rules: + - host: dev-nam.winteraccess.id + http: + paths: + - backend: + service: + name: nam-backend-dev + port: + number: 80 + path: / + pathType: Prefix + tls: + - hosts: + - dev-nam.winteraccess.id + secretName: nam-backend-dev-tls +