From e35006ff3c1d07c44d339ae915444d410c1e351f Mon Sep 17 00:00:00 2001 From: Vitor Hideyoshi Date: Sat, 1 Nov 2025 11:48:40 -0300 Subject: [PATCH] feat: implements a better kubernetes deployment setup --- .dockerignore | 1 + .../{docker-publish.yml => deploy.yml} | 38 +++++++++++- .k8s/config.yml | 8 +++ .k8s/deployment.yaml | 59 +++++++++++++++++++ .k8s/ingress.yaml | 25 ++++++++ .k8s/service.yaml | 13 ++++ src/app/shared/service/auth.service.ts | 10 ++-- src/environments/environment.prod.ts | 1 - src/environments/environment.ts | 1 - 9 files changed, 147 insertions(+), 9 deletions(-) rename .github/workflows/{docker-publish.yml => deploy.yml} (62%) create mode 100644 .k8s/config.yml create mode 100644 .k8s/deployment.yaml create mode 100644 .k8s/ingress.yaml create mode 100644 .k8s/service.yaml diff --git a/.dockerignore b/.dockerignore index 369a80e..ff10064 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,3 +2,4 @@ .gitignore Dockerfile README.md +.k8s \ No newline at end of file diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/deploy.yml similarity index 62% rename from .github/workflows/docker-publish.yml rename to .github/workflows/deploy.yml index d1557bf..b15cd19 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/deploy.yml @@ -2,6 +2,12 @@ name: ci on: push: + workflow_dispatch: + inputs: + tag: + description: 'Tag to deploy' + required: false + default: 'latest' jobs: build: @@ -69,4 +75,34 @@ jobs: - name: Push Docker images run: | docker push $IMAGE_LATEST - docker push $IMAGE_SHA \ No newline at end of file + docker push $IMAGE_SHA + + deploy: + needs: [docker] + runs-on: ubuntu-latest + if: github.event_name == 'push' && (github.ref == 'refs/heads/main') + + steps: + - uses: actions/checkout@v4 + + - name: Set up Kubeconfig + uses: azure/setup-kubectl@v3 + with: + method: kubeconfig + kubeconfig: ${{ secrets.PORTFOLIO_KUBECONFIG }} + + - name: Deploy to Kubernetes + run: | + OWNER=$(echo "${GITHUB_REPOSITORY_OWNER}" | tr '[:upper:]' '[:lower:]') + REPO=$(echo "${GITHUB_REPOSITORY#*/}" | tr '[:upper:]' '[:lower:]') + + IMAGE_BASE="ghcr.io/${OWNER}/${REPO}" + TAG="${{ github.event.inputs.tag || 'latest' }}" + + kubectl config set-context --current --namespace=$KUBE_NAMESPACE + + # Apply any other configuration changes if needed + envsubst < .k8s/config.yml | kubectl apply -f - + envsubst < .k8s/deployment.yaml | kubectl apply -f - + envsubst < .k8s/service.yaml | kubectl apply -f - + envsubst < .k8s/ingress.yaml | kubectl apply -f - \ No newline at end of file diff --git a/.k8s/config.yml b/.k8s/config.yml new file mode 100644 index 0000000..4ca35cc --- /dev/null +++ b/.k8s/config.yml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + namespace: ${KUBE_NAMESPACE} + name: frontend-config +data: + BACKEND_URL: "${BACKEND_URL}" + GITHUB_USER: "${GH_USER}" \ No newline at end of file diff --git a/.k8s/deployment.yaml b/.k8s/deployment.yaml new file mode 100644 index 0000000..115f7e3 --- /dev/null +++ b/.k8s/deployment.yaml @@ -0,0 +1,59 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + namespace: ${KUBE_NAMESPACE} + name: frontend-deployment + labels: + app: frontend +spec: + replicas: 1 + selector: + matchLabels: + app: frontend + template: + metadata: + labels: + app: frontend + spec: + nodeSelector: + ${WORKER_NODE_LABEL} + initContainers: + - name: wait-backend-init + image: busybox:latest + args: + - /bin/sh + - -c + - > + set -x; + while [ $(curl -sw '%{http_code}' "backend-service:8000/health" -o /dev/null) -ne 200 ]; do + sleep 15; + done + containers: + - name: frontend + image: ${IMAGE_BASE}:${TAG} + imagePullPolicy: "Always" + resources: + requests: + memory: "128Mi" + cpu: "75m" + limits: + memory: "128Mi" + cpu: "256m" + ports: + - containerPort: 5000 + readinessProbe: + httpGet: + path: / + port: 5000 + initialDelaySeconds: 10 + livenessProbe: + httpGet: + path: / + port: 5000 + initialDelaySeconds: 10 + envFrom: + - configMapRef: + name: frontend-config + env: + - name: PORT + value: "5000" diff --git a/.k8s/ingress.yaml b/.k8s/ingress.yaml new file mode 100644 index 0000000..881d8c4 --- /dev/null +++ b/.k8s/ingress.yaml @@ -0,0 +1,25 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + namespace: ${KUBE_NAMESPACE} + name: nginx-ingress + annotations: + kubernetes.io/ingress.class: nginx + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: / +spec: + tls: + - hosts: + - ${KUBE_DOMAIN} + secretName: letsencrypt-cluster-certificate-tls + rules: + - host: ${KUBE_DOMAIN} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: frontend-service + port: + number: 5000 \ No newline at end of file diff --git a/.k8s/service.yaml b/.k8s/service.yaml new file mode 100644 index 0000000..c74a15e --- /dev/null +++ b/.k8s/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + namespace: ${KUBE_NAMESPACE} + name: frontend-service +spec: + selector: + app: frontend + ports: + - port: 5000 + protocol: TCP + targetPort: 5000 + type: ClusterIP diff --git a/src/app/shared/service/auth.service.ts b/src/app/shared/service/auth.service.ts index 76f2c73..8cce7b6 100644 --- a/src/app/shared/service/auth.service.ts +++ b/src/app/shared/service/auth.service.ts @@ -16,8 +16,6 @@ export class AuthService { readonly BACKEND_PATH = environment.backendPath; - readonly BACKEND_OAUTH_PATH = environment.backendOAuthPath; - constructor(private http: HttpClient) {} login(userAuthAtempt: User): void { this.validateUser(this.loginUser(userAuthAtempt)); @@ -25,14 +23,14 @@ export class AuthService { googleLogin() { window.open( - this.BACKEND_OAUTH_PATH + '/oauth2/authorization/google', + this.BACKEND_PATH + '/oauth2/authorization/google', '_self', ); } githubLogin() { window.open( - this.BACKEND_OAUTH_PATH + '/oauth2/authorization/github', + this.BACKEND_PATH + '/oauth2/authorization/github', '_self', ); } @@ -112,7 +110,7 @@ export class AuthService { }); return this.http - .get(this.BACKEND_OAUTH_PATH + '/login/oauth2/code/google', { + .get(this.BACKEND_PATH + '/login/oauth2/code/google', { withCredentials: true, params: params, }) @@ -125,7 +123,7 @@ export class AuthService { }); return this.http - .get(this.BACKEND_OAUTH_PATH + '/login/oauth2/code/github', { + .get(this.BACKEND_PATH + '/login/oauth2/code/github', { withCredentials: true, params: params, }) diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index adff1c3..6aea145 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -1,6 +1,5 @@ export const environment = { production: true, backendPath: (window)['env']['BACKEND_URL'], - backendOAuthPath: (window)['env']['BACKEND_OAUTH_URL'], githubUser: (window)['env']['GITHUB_USER'], }; diff --git a/src/environments/environment.ts b/src/environments/environment.ts index bdf5548..152857d 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -5,7 +5,6 @@ export const environment = { production: false, backendPath: 'http://localhost:8070', - backendOAuthPath: 'http://localhost:8070', githubUser: 'HideyoshiNakazone', };