Manifest: Deployment example
Below is the Deployment manifest used in this demo. It deploys 10 replicas of thehighway-animation app and exposes the app container on port 3000. Argo CD will track this manifest in the manifest repository.
Create an Argo CD Application
Create an Argo CD Application that points to the manifest repository for the Jenkins demo. In the UI choose a name such asjenkins-demo, set the sync policy to manual initially (so you can control when changes are applied), and enable auto-creation of the target namespace.

jenkins-demo namespace and deploys the resources. In this demo the Deployment creates 10 Pods.

Developer workflow with GitOps
With GitOps the developer makes changes to application source, builds a new image, pushes it to a registry, and updates the image tag in the manifest repository. Argo CD monitors the manifest repo and applies changes once they land on the tracked branch (e.g.,main).
For this demo we migrated the app source from GitHub to a self-hosted Gitea instance and made small UI/server fixes. The migration UI looks like this:

highway-animation repository contains:
public/index.html(UI)- frontend JS files (
ui.js,app.js) package.jsonDockerfileJenkinsfile(CI/CD)
deployment.yaml you will see a structure similar to the image below:

Application fixes and snippets
Representative fixes made while preparing the demo:- Ensure server listens on port 3000 (was 3001).
- Serve static assets from
public/. - Add a
/healthendpoint and a/api/pod-infoendpoint that readsPOD_COUNTfrom environment variables.
- Adjust vehicle color selection to use a red palette:
- Example daytime sun drawing in the background:
Jenkins pipeline (full CI/CD automation)
After making source changes you build a new Docker image and push it to a registry. The Jenkins pipeline automates:- Build and tag the image (using BUILD_ID and Git commit).
- Push the image to the registry using stored credentials.
- Clone or pull the manifest repository.
- Update the
deployment.yamlwith the new image tag (usingsed). - Commit and push a feature branch and open a PR via the Gitea API.
Never hard-code tokens or registry credentials in pipelines or repository files. Use Jenkins Credentials (or a secret manager) and reference them via
credentials() in the pipeline.Store tokens and registry credentials in Jenkins Credentials (or another secret manager) and reference them via
credentials() in the pipeline. Avoid hard-coding secrets in scripts or repository files.Gitea: creating tokens and using the API
If you need to create a personal access token in Gitea (so Jenkins can push/raise PRs), go to your Gitea user settings → Applications and generate a token with repository write permissions. The token is shown only once — copy it to a secure secret store.

GITEA_TOKEN environment variable and assumes the repo owner/name and branch names are set appropriately:
gitea-pr.sh (example):
Pipeline stages at a glance
| Stage | Purpose | Example action |
|---|---|---|
| Unit Tests | Verify application logic | Run npm test or equivalent |
| Build Image | Build and tag container | docker build -t highway-animation:... |
| Push Image | Push image to registry | docker push <repo>/highway-animation:... |
| Update Manifest | Update deployment image in Git | sed replace in deployment.yaml |
| Commit & PR | Push branch and open PR for review | Use Gitea API to create PR |
| Argo CD sync | Apply manifest changes to cluster | Argo CD observes main and applies |
End-to-end flow (summary)
- Developer updates application source (UI or server).
- Jenkins builds, tags, and pushes a new image to the registry.
- Jenkins clones/pulls the manifest repo, updates
deployment.yamlwith the new image tag, commits, and pushes a feature branch. - Jenkins opens a PR in Gitea for the manifest change.
- A reviewer inspects and merges the PR; once merged, Argo CD detects the change on
mainand applies it to the cluster (or Argo CD can be configured for automated sync).
- Argo CD docs: https://argo-cd.readthedocs.io/
- Jenkins pipeline docs: https://www.jenkins.io/doc/
- Gitea API docs (Swagger): https://docs.gitea.io/en-us/swagger/