Setting Up a New Service
This guide walks through onboarding a new Java service into the deployment pipeline. It assumes the service is a JHipster/Spring Boot application using Maven.
Prerequisites
-
The service repository exists on GitHub under
christhonie/ -
The service builds with Maven and produces a Docker image via Jib
-
The service has a
<revision>property in its POM (e.g.2.0.0-SNAPSHOT)
Step 1: Add Helm Chart
Create the Helm chart directory structure in the service repository:
src/main/helm/
├── Chart.yaml
├── values.yaml
└── templates/
├── config-map-application.yml
└── ... (other JHipster-generated templates)
Chart.yaml
apiVersion: v2
name: <service-name>
description: Helm chart for <Service Display Name>.
type: application
version: 0.0.0
appVersion: 0.0.0
ConfigMap Template
Create templates/config-map-application.yml to render Spring Boot configuration.
Use printf "jdbc:%s" for database URLs so that ArgoCD manifests can use the mysql:// format:
kind: ConfigMap
apiVersion: v1
metadata:
name: {{ include "<service-name>.fullname" . }}
data:
application.yaml: |-
spring:
datasource:
url: {{ printf "jdbc:%s" .Values.config.db.url }}
username: {{ .Values.config.db.username }}
See existing services for full ConfigMap examples with logging, mail, and management configuration.
Step 2: Add Maven Plugin
Add the helm-maven-plugin to the POM:
<properties>
<helm-maven-plugin.version>6.17.0</helm-maven-plugin.version>
</properties>
<!-- In build/plugins -->
<plugin>
<groupId>io.kokuwa.maven</groupId>
<artifactId>helm-maven-plugin</artifactId>
</plugin>
<!-- In build/pluginManagement/plugins -->
<plugin>
<groupId>io.kokuwa.maven</groupId>
<artifactId>helm-maven-plugin</artifactId>
<version>${helm-maven-plugin.version}</version>
<configuration>
<chartDirectory>${project.basedir}/src/main/helm</chartDirectory>
<helmVersion>3.17.3</helmVersion>
<chartVersion>${project.version}-RELEASE</chartVersion>
<appVersion>${project.version}</appVersion>
<skipPushLogin>true</skipPushLogin>
<uploadRepoStable>
<name>dockerhub-christhonie</name>
<url>registry-1.docker.io/christhonie</url>
</uploadRepoStable>
<uploadRepoSnapshot>
<name>dockerhub-christhonie</name>
<url>registry-1.docker.io/christhonie</url>
</uploadRepoSnapshot>
</configuration>
</plugin>
Step 3: Create GitHub Actions Workflows
push-dev.yml
Create .github/workflows/push-dev.yml for the develop branch:
name: 'Develop Push - Build and Test'
on:
push:
branches: [develop]
paths-ignore: ['*.md', '*.adoc', '.devcontainer/**']
jobs:
package:
name: Package
uses: christhonie/event/.github/workflows/maven-package.yml@main
with:
maven-profiles: dev,webapp (1)
jdk-version: 21 (2)
secrets:
MAVEN_PASSWORD: ${{ secrets.EVENT_PACKAGE_REPO_TOKEN }}
docker-build:
name: Docker
needs: [package]
uses: christhonie/event/.github/workflows/docker-build.yml@main
with:
maven-profiles: dev,webapp
jdk-version: 21
secrets:
DOCKER_PAT: ${{ secrets.DOCKER_PAT }}
helm-build:
name: Helm
needs: [docker-build]
if: always() && needs.docker-build.result == 'success'
uses: christhonie/event/.github/workflows/helm-build.yml@main
with:
maven-profiles: dev,webapp
jdk-version: 21
secrets:
DOCKER_PAT: ${{ secrets.DOCKER_PAT }}
update-argocd-dev:
name: Deploy Dev
needs: [helm-build]
if: always() && needs.helm-build.result == 'success'
uses: christhonie/event/.github/workflows/argocd-update.yml@main
with:
environment: dev
service-name: <service-name> (3)
chart-version: ${{ needs.helm-build.outputs.chart-version }} (4)
build-sha: ${{ github.sha }} (5)
secrets:
ARGOCD_REPO_TOKEN: ${{ secrets.ARGOCD_REPO_TOKEN }}
| 1 | Adjust Maven profiles for your service |
| 2 | Use JDK 21 for new services |
| 3 | Must match the ArgoCD manifest filename prefix |
| 4 | Sets ArgoCD targetRevision to the Helm chart version |
| 5 | Forces SNAPSHOT rollouts via pod annotation |
push-main.yml
Create .github/workflows/push-main.yml for the main branch:
name: 'Main Push - Package and Deploy'
on:
push:
branches: [main]
jobs:
package:
name: Package
uses: christhonie/event/.github/workflows/maven-package.yml@main
with:
maven-profiles: prod,webapp
jdk-version: 21
secrets:
MAVEN_PASSWORD: ${{ secrets.EVENT_PACKAGE_REPO_TOKEN }}
docker-build:
name: Docker
needs: [package]
uses: christhonie/event/.github/workflows/docker-build.yml@main
with:
maven-profiles: prod,webapp
jdk-version: 21
secrets:
DOCKER_PAT: ${{ secrets.DOCKER_PAT }}
helm-build:
name: Helm
needs: [docker-build]
uses: christhonie/event/.github/workflows/helm-build.yml@main
with:
maven-profiles: prod,webapp
jdk-version: 21
secrets:
DOCKER_PAT: ${{ secrets.DOCKER_PAT }}
update-argocd-stage:
name: Deploy Stage
needs: [helm-build]
if: always() && needs.helm-build.result == 'success'
uses: christhonie/event/.github/workflows/argocd-update.yml@main
with:
environment: stage
service-name: <service-name>
chart-version: ${{ needs.helm-build.outputs.chart-version }}
secrets:
ARGOCD_REPO_TOKEN: ${{ secrets.ARGOCD_REPO_TOKEN }}
gitflow-release-finish:
name: Gitflow
needs: [package]
uses: christhonie/event/.github/workflows/gitflow-release-finish.yml@main
Step 4: Configure Repository Secrets
Add these secrets to the GitHub repository settings:
| Secret | Value |
|---|---|
|
GitHub PAT with |
|
Docker Hub PAT with push permissions |
|
GitHub PAT with write access to |
Step 5: Build Initial Helm Chart
Before creating ArgoCD manifests, the Helm chart must exist in the registry.
Either push to develop or main to trigger the CI build (charts are built on every push), or build manually:
cd ~/dev/ems/<service-directory>
mvn helm:init helm:registry-login helm:package helm:push -Pprod
helm:registry-login is used here for local builds (where Maven settings handle credentials correctly).
In CI, the Helm CLI login is used instead due to a bug in the Maven goal.
|
Verify the chart was published:
helm pull oci://registry-1.docker.io/christhonie/<chart-name> \
--version <project-version>-RELEASE
Step 6: Create ArgoCD Manifests
Create Application manifests in christhonie/idl-xnl-jhb-rc01/argocd/.
Dev Environment
Create <service-name>-dev.yml:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: <service-name>-dev
namespace: argocd
spec:
project: default
destination:
name: idl-xnl-jhb1-rc01
namespace: event-dev
source:
repoURL: registry-1.docker.io
chart: christhonie/<chart-name>
targetRevision: <version>-RELEASE
helm:
releaseName: dev-<service-name>
valuesObject:
config:
profiles: "dev,kubernetes,api-docs"
existingsecret: event-admin-service
db:
url: mysql://idealogic-prod.mysql.svc.cluster.local:6446/<db_name>_dev?useUnicode=true&characterEncoding=utf8
username: dev
logging:
level:
ROOT: DEBUG
image:
pullPolicy: Always
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-name>-dev.idealogic.co.za
pathType: Prefix
tls: true
syncPolicy:
automated:
prune: true
selfHeal: true
allowEmpty: false
syncOptions:
- CreateNamespace=true
revisionHistoryLimit: 3
Stage and Prod
Create <service-name>-stage.yml and <service-name>-prod.yml following the environment conventions.
Key differences for prod:
-
Logging level:
INFO(notDEBUG) -
Image pull policy:
IfNotPresent(notAlways) -
No
build-shapod annotation -
No
fakerLiquibase context
Step 7: Verify Deployment
-
Push the ArgoCD manifests to
christhonie/idl-xnl-jhb-rc01 -
ArgoCD’s app-of-apps will detect the new manifests and create the Applications
-
Monitor the deployment:
export KUBECONFIG=/mnt/c/Users/chris/.kube/static/idl-xnl-jhb1-01.yaml kubectl -n event-dev get pods kubectl -n event-dev logs <pod-name> --tail=100
Checklist
Use this checklist when onboarding a new service:
-
Helm chart created in
src/main/helm/ -
helm-maven-pluginconfigured in POM -
src/main/helm/templates/added to.prettierignore -
push-dev.ymlworkflow created -
push-main.ymlworkflow created -
Repository secrets configured (
DOCKER_PAT,EVENT_PACKAGE_REPO_TOKEN,ARGOCD_REPO_TOKEN) -
Initial Helm chart published to Docker Hub
-
ArgoCD manifest created for dev
-
ArgoCD manifest created for stage
-
ArgoCD manifest created for prod
-
Deployment verified on dev environment