ArgoCD Deployment
ArgoCD manages Kubernetes deployments using a GitOps pattern. Application manifests are stored in a dedicated repository and ArgoCD automatically syncs the desired state to the cluster.
Repository Structure
The ArgoCD manifests live in christhonie/idl-xnl-jhb-rc01:
argocd/ ├── event-admin-service-dev.yml ├── event-admin-service-stage.yml ├── event-admin-service-prod.yml ├── membership-ui-dev.yml ├── membership-ui-stage.yml ├── membership-ui-prod.yml ├── registration-portal-dev.yml ├── registration-portal-stage.yml └── registration-portal-prod.yml
Each file is a standalone ArgoCD Application resource.
The naming convention is <service-name>-<environment>.yml.
App-of-Apps Pattern
An app-of-apps Application (named idl-xnl-jhb1-rc01) watches the argocd/ directory and manages all child Applications.
This parent Application must have auto-sync enabled to pick up new or modified child manifests.
Application Manifest Structure
Each ArgoCD Application manifest follows this structure:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: membership-ui-dev (1)
namespace: argocd
spec:
project: default
destination:
name: idl-xnl-jhb1-rc01 (2)
namespace: event-dev (3)
source:
repoURL: registry-1.docker.io (4)
chart: christhonie/membership-ui
targetRevision: 2.0.0-SNAPSHOT-RELEASE (5)
helm:
releaseName: dev-membership-ui
valuesObject: (6)
config:
profiles: "dev,kubernetes,api-docs"
existingsecret: event-admin-service
db:
url: mysql://host:port/db_name?params
username: dev
services:
eventadminservice: http://dev-event-admin-service
apikey: "..."
mail:
from: [email protected]
logging:
level:
ROOT: DEBUG
image:
pullPolicy: Always (1)
imagePullSecrets:
- name: christhonie-docker
ingress:
enabled: true
className: "nginx"
annotations:
"cert-manager.io/cluster-issuer": "letsencrypt-prod"
"external-dns.alpha.kubernetes.io/cloudflare-proxied": "false"
hostname: service-dev.idealogic.co.za
pathType: Prefix
tls: true
podAnnotations: (7)
app.kubernetes.io/build-sha: <git-sha>
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false (8)
syncOptions:
- CreateNamespace=true
revisionHistoryLimit: 3 (9)
| 1 | Unique Application name: <service>-<env> |
| 2 | Target cluster name |
| 3 | Kubernetes namespace per environment |
| 4 | OCI registry for Helm charts |
| 5 | Chart version (Maven version + -RELEASE) |
| 6 | Helm values inline — overrides values.yaml from the chart |
| 7 | image.tag is intentionally omitted — the chart’s appVersion defaults to the correct Docker image tag via {{ .Values.image.tag | default .Chart.AppVersion }} in the deployment template |
| 8 | Pod annotation to force rollout on SNAPSHOT rebuilds (set by CI) |
| 9 | Prevent accidental deletion of all resources |
| 10 | Limit stored revision history |
Environment Conventions
| Setting | Dev | Stage | Prod | Notes |
|---|---|---|---|---|
Namespace |
|
|
|
|
Spring Profiles |
|
|
|
Dev includes |
Logging Level |
|
|
|
Prod must be INFO |
Image Pull Policy |
|
|
|
Prod uses fixed releases |
|
Yes |
No |
No |
Only for SNAPSHOT rollouts |
|
|
|
|
Always set explicitly |
Liquibase Contexts |
|
(none) |
(none) |
Faker data only in dev |
Database URL Pattern
Database URLs in ArgoCD manifests use the mysql:// format (without jdbc: prefix):
db:
url: mysql://idealogic-prod.mysql.svc.cluster.local:6446/database_name?useUnicode=true&characterEncoding=utf8
The Helm chart’s ConfigMap template prepends jdbc: automatically:
url: {{ printf "jdbc:%s" .Values.config.db.url }}
The deployed Helm chart version must contain the printf template.
If you change the manifest URL format before the chart is updated, the application will fail with URL must start with 'jdbc'.
|
Database Naming Convention
| Service | Database | Username |
|---|---|---|
admin-service |
|
|
membership-ui |
|
|
registration-portal |
|
|
SNAPSHOT Deployment Strategy
SNAPSHOT versions use the same image tag for every build. To force Kubernetes to pull the latest image and restart pods:
-
The
argocd-update.ymlworkflow setschart-version(updatingtargetRevision) andbuild-sha(updatingpodAnnotations."app.kubernetes.io/build-sha") -
Since SNAPSHOT chart versions may already exist in the registry, the Helm push uses
continue-on-errorto tolerate duplicate tags -
The
build-shaannotation change triggers a pod rollout even though the chart version and image tag are unchanged -
Image pull policy is set to
Alwaysfor dev and stage environments
Forcing a Hard Refresh
If ArgoCD has cached a stale chart version, force a hard refresh:
export KUBECONFIG=/mnt/c/Users/chris/.kube/static/aks-rancher-idealogic.yaml
kubectl -n argocd patch application <app-name> \
--type merge \
-p '{"metadata":{"annotations":{"argocd.argoproj.io/refresh":"hard"}}}'
Monitoring Deployments
Check pod status on the workload cluster:
export KUBECONFIG=/mnt/c/Users/chris/.kube/static/idl-xnl-jhb1-01.yaml
# Check pods in a specific namespace
kubectl -n event-dev get pods
# View logs for a specific pod
kubectl -n event-dev logs <pod-name> --tail=100
# Check events for troubleshooting
kubectl -n event-dev get events --sort-by='.lastTimestamp'
Common Issues
- Liquibase Checksum Mismatch
-
After upgrading JHipster, the Liquibase changeset order may change without altering the schema. Clear the checksum to allow re-validation:
UPDATE DATABASECHANGELOG SET MD5SUM = NULL WHERE ID = '00000000000001'; - Chart Not Found
-
Ensure the Helm chart has been published with the exact version referenced in
targetRevision. Charts are built on every push to bothdevelopandmain.