Skip to content

Commit

Permalink
merge: deployment workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
FranciZhong committed Oct 3, 2024
1 parent 76d03fb commit 8da6e47
Show file tree
Hide file tree
Showing 15 changed files with 375 additions and 33 deletions.
5 changes: 4 additions & 1 deletion .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ node_modules
npm-debug.log
.git
.env
.env.*
.env.*

# Ignore generated credentials from google-github-actions/auth
gha-creds-*.json
48 changes: 24 additions & 24 deletions .github/workflows/deploy-gke.yml → .github/workflows/cd.yml
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
name: 'Build and Deploy to GKE'
name: 'CD'

on:
push:
branches:
- '"deploy-workflow"'
- 'main'
pull_request:
branches:
- '"main"'
- 'main'

env:
PROJECT_ID: 'chatemo'
GAR_LOCATION: 'australia-southeast1'
GKE_CLUSTER: 'chatemo-cluster'
GKE_ZONE: 'australia-southeast1-c'
DEPLOYMENT_NAME: 'chatemo'
REPOSITORY: 'francizhong'
IMAGE: 'chatemo'
WORKLOAD_IDENTITY_PROVIDER: 'projects/642179943052/locations/global/workloadIdentityPools/github-pool/providers/git-actions-provider'
PROJECT_ID: ${{ secrets.PROJECT_ID }}
GAR_LOCATION: ${{ secrets.GAR_LOCATION }}
GKE_CLUSTER: ${{ secrets.GKE_CLUSTER }}
GKE_ZONE: ${{ secrets.GKE_ZONE }}
DEPLOYMENT_NAME: ${{ secrets.DEPLOYMENT_NAME }}
REPOSITORY: ${{ secrets.REPOSITORY }}
IMAGE: ${{ secrets.IMAGE }}

jobs:
setup-build-publish-deploy:
Expand All @@ -39,7 +38,9 @@ jobs:
name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/auth@v2'
with:
workload_identity_provider: '${{ env.WORKLOAD_IDENTITY_PROVIDER }}'
project_id: '${{ env.PROJECT_ID }}'
workload_identity_provider: '${{ secrets.WORKLOAD_IDENTITY_PROVIDER }}'
service_account: ${{ secrets.SERVICE_ACCOUNT }}

# Authenticate Docker to Google Cloud Artifact Registry
- name: 'Docker Auth'
Expand All @@ -58,28 +59,27 @@ jobs:

# Build the Docker image
- name: 'Build and push Docker container'
id: build-image
run: |-
gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin https://${GAR_LOCATION}-docker.pkg.dev
DOCKER_TAG="${GAR_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE}:${GITHUB_SHA}"
LATEST_DOCKER_TAG="${GAR_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE}:latest"
docker build \
--tag "${DOCKER_TAG}" \
--tag "${LATEST_DOCKER_TAG}" \
--build-arg GITHUB_SHA="${GITHUB_SHA}" \
--build-arg GITHUB_REF="${GITHUB_REF}" \
.
docker push "${DOCKER_TAG}"
docker push "${LATEST_DOCKER_TAG}"
echo "::set-output name=image::${DOCKER_TAG}"
# Set up kustomize
- name: 'Set up Kustomize'
run: |-
curl -sfLo kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/kustomize%2Fv5.4.3/kustomize_v5.4.3_linux_amd64.tar.gz
chmod u+x ./kustomize
# Deploy the Docker image to the GKE cluster
- name: 'Deploy to GKE'
# Update the image in the GKE deployment
- name: 'Update Image in GKE'
run: |-
# replacing the image name in the k8s template
./kustomize edit set image LOCATION-docker.pkg.dev/PROJECT_ID/REPOSITORY/IMAGE:TAG=$GAR_LOCATION-docker.pkg.dev/$PROJECT_ID/$REPOSITORY/$IMAGE:$GITHUB_SHA
./kustomize build . | kubectl apply -f -
kubectl rollout status deployment/$DEPLOYMENT_NAME
kubectl set image deployment/${{ env.DEPLOYMENT_NAME }} ${{env.IMAGE}}=${{ steps.build-image.outputs.image }}
kubectl rollout status deployment/${{ env.DEPLOYMENT_NAME }}
kubectl get services -o wide
6 changes: 3 additions & 3 deletions .github/workflows/db-migrate.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name: Deploy
name: Prisma DB Migrate
on:
push:
paths:
- prisma/migrations/** # Only run this workflow when migrations are updated
branches:
- main
- deploy-workflow

pull_request:
paths:
Expand All @@ -28,4 +28,4 @@ jobs:
- name: Apply all pending migrations to the database
run: npx prisma migrate deploy
env:
DATABASE_URL: ${{ secrets.DATABASE_URL }}
DATABASE_URL: ${{ secrets.EXTERNAL_DATABASE_URL }}
111 changes: 111 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
name: 'Initialize Deployment to GKE'

on:
workflow_dispatch:

env:
PROJECT_ID: ${{ secrets.PROJECT_ID }}
GAR_LOCATION: ${{ secrets.GAR_LOCATION }}
GKE_CLUSTER: ${{ secrets.GKE_CLUSTER }}
GKE_ZONE: ${{ secrets.GKE_ZONE }}
REPOSITORY: ${{ secrets.REPOSITORY }}
IMAGE: ${{ secrets.IMAGE }}

jobs:
setup-build-publish-deploy:
name: 'Deploy Postgres, Redis and Build Chatemo as the latest'
runs-on: 'ubuntu-latest'

permissions:
contents: 'read'
id-token: 'write'

steps:
- name: 'Checkout'
uses: 'actions/checkout@v4'

# Configure Workload Identity Federation and generate an access token.
#
# See https://github.com/google-github-actions/auth for more options,
# including authenticating via a JSON credentials file.
- id: 'auth'
name: 'Authenticate to Google Cloud'
uses: 'google-github-actions/auth@v2'
with:
project_id: '${{ env.PROJECT_ID }}'
workload_identity_provider: '${{ secrets.WORKLOAD_IDENTITY_PROVIDER }}'
service_account: ${{ secrets.SERVICE_ACCOUNT }}

# Authenticate Docker to Google Cloud Artifact Registry
- name: 'Docker Auth'
uses: 'docker/login-action@v3'
with:
username: 'oauth2accesstoken'
password: '${{ steps.auth.outputs.auth_token }}'
registry: '${{ env.GAR_LOCATION }}-docker.pkg.dev'

# Get the GKE credentials so we can deploy to the cluster
- name: 'Set up GKE credentials'
uses: 'google-github-actions/get-gke-credentials@v2'
with:
cluster_name: '${{ env.GKE_CLUSTER }}'
location: '${{ env.GKE_ZONE }}'

# Set up config map and secrets
- name: 'Apply config map and secret'
run: |-
kubectl create configmap env-config \
--from-literal=NEXTAUTH_URL=${{ secrets.NEXTAUTH_URL }} \
--from-literal=GOOGLE_CLIENT_ID=${{ secrets.GOOGLE_CLIENT_ID }} \
--from-literal=AWS_ACCESS_KEY_ID=${{ secrets.AWS_ACCESS_KEY_ID }} \
--from-literal=AWS_REGION=${{ secrets.AWS_REGION }} \
--from-literal=AWS_S3_BUCKET_NAME=${{ secrets.AWS_S3_BUCKET_NAME }} \
--dry-run=client -o yaml | kubectl apply -f -
kubectl create secret generic env-secret \
--from-literal=REDIS_PASSWORD=${{ secrets.REDIS_PASSWORD }} \
--from-literal=POSTGRES_PASSWORD=${{ secrets.POSTGRES_PASSWORD }} \
--from-literal=DATABASE_URL=${{ secrets.DATABASE_URL }} \
--from-literal=NEXTAUTH_SECRET=${{ secrets.NEXTAUTH_SECRET }} \
--from-literal=GOOGLE_CLIENT_SECRET=${{ secrets.GOOGLE_CLIENT_SECRET }} \
--from-literal=AWS_SECRET_ACCESS_KEY=${{ secrets.AWS_SECRET_ACCESS_KEY }} \
--dry-run=client -o yaml | kubectl apply -f -
# Deploy Postgres
- name: 'Deploy Postgres in GKE'
run: |-
kubectl apply -f ./k8s/postgres-pvc.yml
kubectl apply -f ./k8s/postgres-deployment.yml
kubectl apply -f ./k8s/postgres-service.yml
kubectl rollout status deployment/postgres
# Deploy Redis
- name: 'Deploy Redis in GKE'
run: |-
kubectl apply -f ./k8s/redis-pvc.yml
kubectl apply -f ./k8s/redis-deployment.yml
kubectl apply -f ./k8s/redis-service.yml
kubectl rollout status deployment/redis
# Build the Docker image with latest tag
- name: 'Build and push Docker container'
id: build-image
run: |-
gcloud auth print-access-token | docker login -u oauth2accesstoken --password-stdin https://${GAR_LOCATION}-docker.pkg.dev
DOCKER_TAG="${GAR_LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPOSITORY}/${IMAGE}:latest"
docker build \
--tag "${DOCKER_TAG}" \
.
docker push "${DOCKER_TAG}"
echo "::set-output name=image::${DOCKER_TAG}"
# Deploy Redis
- name: 'Deploy Chatemo in GKE'
run: |-
kubectl apply -f ./k8s/chatemo-deployment.yml
kubectl apply -f ./k8s/chatemo-service.yml
kubectl rollout status deployment/chatemo
kubectl get services -o wide
83 changes: 83 additions & 0 deletions k8s/chatemo-deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: chatemo
spec:
replicas: 2
selector:
matchLabels:
app: chatemo
template:
metadata:
labels:
app: chatemo
spec:
restartPolicy: Always
containers:
- name: chatemo
image: australia-southeast1-docker.pkg.dev/chatemo/francizhong/chatemo:latest
imagePullPolicy: Always
ports:
- containerPort: 3000
resources:
requests:
memory: '512Mi'
cpu: '500m'
limits:
memory: '1Gi'
cpu: '1'
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: env-secret
key: DATABASE_URL
- name: REDIS_HOST
value: 'redis'
- name: REDIS_PORT
value: '6379'
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: env-secret
key: REDIS_PASSWORD
- name: NEXTAUTH_URL
valueFrom:
configMapKeyRef:
name: env-config
key: NEXTAUTH_URL
- name: NEXTAUTH_SECRET
valueFrom:
secretKeyRef:
name: env-secret
key: NEXTAUTH_SECRET
- name: GOOGLE_CLIENT_ID
valueFrom:
configMapKeyRef:
name: env-config
key: GOOGLE_CLIENT_ID
- name: GOOGLE_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: env-secret
key: GOOGLE_CLIENT_SECRET
- name: AWS_ACCESS_KEY_ID
valueFrom:
configMapKeyRef:
name: env-config
key: AWS_ACCESS_KEY_ID
- name: AWS_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: env-secret
key: AWS_SECRET_ACCESS_KEY
- name: AWS_REGION
valueFrom:
configMapKeyRef:
name: env-config
key: AWS_REGION
- name: AWS_S3_BUCKET_NAME
valueFrom:
configMapKeyRef:
name: env-config
key: AWS_S3_BUCKET_NAME
12 changes: 12 additions & 0 deletions k8s/chatemo-service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: chatemo
spec:
type: LoadBalancer
selector:
app: chatemo
ports:
- protocol: TCP
port: 80
targetPort: 3000
45 changes: 45 additions & 0 deletions k8s/postgres-deployment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres
spec:
replicas: 1
selector:
matchLabels:
app: postgres
template:
metadata:
labels:
app: postgres
spec:
restartPolicy: Always
containers:
- name: postgres
image: postgres:17-alpine
ports:
- containerPort: 5432
resources:
requests:
memory: '512Mi'
cpu: '500m'
limits:
memory: '1Gi'
cpu: '1'
env:
- name: POSTGRES_DB
value: 'chatemo'
- name: POSTGRES_USER
value: 'postgres'
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: env-secret
key: POSTGRES_PASSWORD
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-storage
subPath: chatemo-data
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-pvc
11 changes: 11 additions & 0 deletions k8s/postgres-pvc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-pvc
spec:
storageClassName: standard
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi
12 changes: 12 additions & 0 deletions k8s/postgres-service.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: postgres
spec:
type: LoadBalancer
selector:
app: postgres
ports:
- protocol: TCP
port: 5432
targetPort: 5432
Loading

0 comments on commit 8da6e47

Please sign in to comment.