This is the code samples to the GitOps talk at https://robrich.org/slides/gitops/.
This repo demonstrates two different GitOps scenarios:
- An on-prem GitOps setup
- A Docker & Kubernetes GitOps setup using ArgoCD
- A Node.js / Express.js app shows a Handlebars UI
- In
/routes/index.jsis the configuration to call the backend.
- An ASP.NET Minimal APIs app exposes APIs for creating and updating items and votes for each item.
- The data store is a static list, so restarting the app empties the "database".
The purpose of the On-Prem GitOps Setup is to show that GitOps is a methodology for deployment, and not a Kubernetes-specific toolchain or product.
The on-prem setup uses scripts in the build folder.
- build.ps1: builds the two apps and commits assets to a local repository.
- deploy.ps1: copies deployed assets to the websites running in PM2
Outside this repo and in a folder next to it, create a git repo named deploy:
- git clone this repo:
git clone https://github.com/robrich/gitops mkdir deploycd deploygit init --barecd ..
This repo is the GitOps deployment repo.
Install dependencies on your machine:
- Install Node.js
- Install ASP.NET SDK
- Install PM2:
npm install -g pm2
Setup the sites:
mkdir servercd servermkdir wwwrootcd wwwrootmkdir frontendpm2 start --name frontend index.jsThis will correctly fail because nothing exists in this directory yetcd ..cd backendpm2 start dotnet --name backend -- "backend.dll"This will correctly fail because nothing exists in this directory yetcd ../../..pm2 lsThis will show you the 2 apps are now failing but exist
-
Run
build.ps1. This is typically done by a build server. It will:- build the frontend and backend
- copy the built assets to the
distdirectory - clone the
deployrepository - copy the
distdirectory intodeploy/appsand commit it
-
Run
deploy.ps1. This is typically done on the production server by the Task Scheduler or cron. It will:- get the latest from the
deployrepository - if nothing changed, it exits early
- stop the backend site so files aren't in use
- copy new content into place
- restart all sites in pm2
- get the latest from the
-
Browse the sites:
- Visit https://localhost:3000/ to view the frontend
- Visit https://localhost:5000/ to view the backend
Now let's change the content and watch the GitOps process run.
-
Modify anything in either the frontend app or the backend app. Perhaps change the word
FrameworktoRestaurant. -
Re-run build.ps1 & deploy.ps1, simulating the build server and the production scheduled task.
-
Refresh the sites to view the changes.
This solution shows how you can use container tools with a GitOps process.
- In the
appsfolder, in each folder is aDockerfilethat outlines the build steps. - In the
k8sfolder are Kubernetes YAML files. - In the
.github/workflowsfolder is the GitHub Actions build script. - We'll use ArgoCD in your k8s cluster of choice to deploy the apps.
Argo supports k8s yaml, helm charts, and others. See https://github.com/argoproj/argocd-example-apps
- Fork this repository into your own account.
Setup the ArgoCD repo. This repo will store built assets. It is not a fork of this repo.
- Create a new repository on your GitHub account to store ArgoCD assets. I chose the name
gitops-argocd
Setup the GitHub Actions build:
-
In your forked repository's settings, create Repository Secrets for:
-
DOCKER_USERNAME: your username on https://hub.docker.com/ With slight modification, you could also use a private container registry like Azure Container Registry or Elastic Container Registry. -
DOCKER_PASSWORD: setup a Docker Hub Access Token and setup this secret with the value. -
GH_TOKEN: setup a GitHub Fine-grained Personal Access Token- Give it permission to the Argo CD repository built above
- Set
ContentstoRead & Writeand leave all other permissions tononeSet the value of this token into this secret.
Note: We're specifically not using
GITHUB_TOKENbecause that one only has access to the current repository.
-
-
In your forked repository's settings, create Repository Variables for:
ARGO_REPO: the ArgoCD repository created above. Mine is set torobrich/gitops-argocd. Make sure to NOT include thehttps://github/part.
Now the two repositories are setup.
Install mkcert, a great tool for creating self-signed certificates with a trust chain.
-
Download mkcert and put it in your path.
-
mkcert -install
Next let's setup ArgoCD in the Kubernetes cluster.
-
In your k8s cluster of choice, follow the ArgoCD Setup instructions:
-
Download the ArgoCD CLI and put it in your path.
-
Run these commands in your terminal:
mkcert localhost kubectl create namespace argocd kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.yaml kubectl create -n argocd secret tls argocd-server-tls --cert=localhost.pem --key=localhost-key.pem kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "NodePort"}}' kubectl -n argocd get secrets/argocd-initial-admin-secret --template="{{.data.password}}" | base64 -d kubectl -n argocd get svc # Note the https port for `argocd-server` argocd admin initial-password -n argocd argocd login localhost:NODE_PORT # <-- fill in the node port retrieved above # username is `admin`, password is the one you retrieved above https://localhost:NODE_PORT # <-- fill in the node port retrieved above # use the same login kubectl config get-contexts argocd cluster add docker-desktop # the name of your current kubectl context kubectl config set-context --current --namespace=argocd # change these URLs to your fork of the GitOps repo: argocd app create frontend --repo https://github.com/robrich/gitops-argocd --path apps/frontend --dest-server https://kubernetes.default.svc --dest-namespace default --sync-policy auto argocd app create backend --repo https://github.com/robrich/gitops-argocd --path apps/backend --dest-server https://kubernetes.default.svc --dest-namespace default --sync-policy auto
-
Now that you have Argo setup, refresh the ArgoCD website and see the 2 apps you have configured.
-
The apps are running because ArgoCD just deployed them, but they're likely failing because the containers don't yet exist.
-
Visit your fork of the GitOps repo. Mine is https://github.com/robrich/gitops
-
Click on Actions then choose
App Buildon the left. -
On the far right, click
Run Workflowand choose themainbranch. -
This will kick off the build, push containers to Docker Hub, then commit the k8s yaml files to the ArgoCD repo.
-
Refresh the ArgoCD dashboard.
ArgoCD checks for changes every 10 seconds. It'll notice the ArgoCD repo changed, and deploy the apps.
-
Browse the apps:
- Visit https://localhost:3000/ to view the frontend
- Visit https://localhost:5000/ to view the backend
Now we'll change something and watch it re-deploy.
-
Change something in the frontend or backend app. Perhaps change the title
FrameworkstoRestaurantsinfrontend/views/index.hbs. -
Commit and push this change.
-
Watch the GitHub Actions build complete.
-
Verify the new containers are pushed to Docker Hub.
-
Watch ArgoCD deploy these new versions to your cluster.
-
Refresh the frontend app, and notice the change.
License: MIT, Copyright Richardson & Sons, LLC