Service Pod Architecture Changes for Self-Managed Environments
Frontend, JFBus, and JFmelt now run as standalone Kubernetes Deployments by default, and Helm requires a resolvable Join Key and Master Key for every installation.
Starting with 107.161.x Self-Managed release, the artifactory and artifactory-ha Helm charts run Frontend, JFBus, and JFmelt as standalone Kubernetes Deployments by default. This is a potentially breaking change if you use custom Helm values, are missing a Join Key or Master Key, or have network policies tuned for the previous single-pod layout.
These three services reached this state differently:
- Frontend genuinely moved out of the Artifactory StatefulSet pod, where it previously ran as a container. It became available as an optional standalone Deployment in 107.146.x. From 107.161.x, enabled by default.
- JFBus and JFmelt are newer platform services that were introduced directly as standalone Kubernetes Deployments — neither ever ran as a container inside the Artifactory StatefulSet pod. What changed for them in this release is that they are now enabled by default, where they previously required opting in.
| Service | Standalone Deployment introduced | Enabled by default |
|---|---|---|
| Frontend | Split from the Artifactory StatefulSet container | Chart update, 107.161.x |
| JFBus | Introduced directly as a standalone Deployment | Chart update, 107.161.x |
| JFmelt | Introduced directly as a standalone Deployment | Chart update, 107.161.x |
Breaking Change Summary
Two things change by default in this release: Frontend, JFBus, and JFmelt now run as separate pods, and Helm now fails
install/upgradeearly if a Join Key and Master Key cannot be resolved. Review Breaking Changes and Customer Impact before upgrading.
Components Affected
| Component | Helm Value | Default (this release) | Deployment Model | Notes |
|---|---|---|---|---|
| Frontend | frontend.enabled, frontend.asPod | true / true | Standalone Deployment | Serves the JFrog Platform UI (jffe service ID). Previously ran as a container in the Artifactory StatefulSet pod; now split out and enabled by default. |
| JFBus | jfbus.enabled | true | Standalone Deployment | Platform event bus; used by Metadata and other services. Always a standalone Deployment since its introduction; now enabled by default instead of opt-in. |
| JFmelt | jfmelt.enabled | true | Standalone Deployment | Event collection and dispatch pipeline; requires jfbus.enabled: true and jfconnect.enabled: true, Pro only. Always a standalone Deployment since its introduction; now enabled by default instead of opt-in. |
| Artifactory core | artifactory.* | unchanged | StatefulSet | Remaining microservices still run as containers in the Artifactory pod (splitServicesToContainers: true) |
To disable any of these services (restoring Frontend to the Artifactory StatefulSet pod, or turning JFBus/JFmelt off entirely), see Configure Frontend, JFBus, and JFmelt Deployments.
New Pod Topology
flowchart TB
subgraph FE["Frontend Pod"]
F1["frontend + router + observability"]
end
subgraph JB["JFBus Pod"]
J1["jfbus + router + observability"]
end
subgraph AF["Artifactory StatefulSet Pod"]
A1["artifactory, metadata, event, jfconnect, router, observability, ..."]
end
subgraph JM["JFmelt Pod (Pro only)"]
M1["jfmelt + router + observability"]
end
FE --> AF
JB --> AF
AF --> JM
Why These Services Run as Standalone Deployments
Frontend previously ran as a container inside a single Artifactory StatefulSet pod, alongside Artifactory and other microservices. That model had limits that motivated splitting Frontend out, and that also shaped JFBus and JFmelt as standalone services from their introduction:
- Coupled lifecycle — Restarting or upgrading one service restarted the entire pod.
- No independent scaling — Frontend could not be scaled separately under load.
- Resource contention — Services sharing one pod compete for that pod's CPU/memory limits.
- SaaS parity — SaaS already runs these as separate services; this release aligns Self-Hosted with that architecture.
- New platform services — JFBus and JFmelt are first-class services that need their own lifecycle, health checks, and horizontal pod autoscaling (HPA).
| Benefit | Description |
|---|---|
| Independent scaling | HPA on Frontend, JFBus, and JFmelt without touching Artifactory |
| Isolated upgrades | Rolling updates per service; fewer full-platform restarts |
| Better resilience | A failure in one service does not necessarily restart the whole platform |
| Resource tuning | Per-service requests/limits in sizing profiles — see Hardware Sizing Matrix |
| Operational clarity | Clear pod-level health, logs, and metrics per service |
Mandatory Join Key and Master Key
Helm now validates that a Join Key and Master Key can be resolved for every installation (unless keysPassedViaSystemyaml: true is set), because Frontend, JFBus, and JFmelt now run as independent deployments and each must authenticate to the platform at startup. If either key is missing, helm install/helm upgrade fails early with a descriptive error rather than deploying a pod that can't join the topology.
Exact Error Names You May See
Depending on which key is missing, the chart's
fail()message header readsERROR: MISSING MANDATORY KEYS(both keys unresolved),ERROR: MISSING MASTER_KEY, orERROR: MISSING JOIN_KEY(only one unresolved).
How to Provide Keys
Option 1 — Kubernetes Secret (recommended for production):
kubectl create secret generic artifactory-mandatory-keys -n <namespace> \
--from-literal=master-key=${MASTER_KEY} \
--from-literal=join-key=${JOIN_KEY}
helm upgrade --install artifactory jfrog/artifactory \
--set global.masterKeySecretName=artifactory-mandatory-keys \
--set global.joinKeySecretName=artifactory-mandatory-keysOption 2 — Inline Helm values (dev/test only):
helm upgrade --install artifactory jfrog/artifactory \
--set global.masterKey=${MASTER_KEY} \
--set global.joinKey=${JOIN_KEY}Option 3 — Keys already in system.yaml: If keys are already defined via artifactory.extraSystemYaml, artifactory.systemYaml, or systemYamlOverride under shared.security.joinKey/shared.security.masterKey, skip Options 1 and 2 and set:
helm upgrade --install artifactory jfrog/artifactory \
--set keysPassedViaSystemyaml=trueRetrieving Existing Keys for an Upgrade
-
Join Key — In the JFrog Platform UI, go to Administration > Security > General > Connection Details, enter your password, and copy the Join Key. See Manage Keys for the full procedure.
-
Master Key — Retrieve it from a running Artifactory pod:
export MASTER_KEY=$(kubectl exec -it <release>-artifactory-0 -n <namespace> -c artifactory -- cat /opt/jfrog/artifactory/var/etc/security/master.key)
Fresh installs can generate new keys instead of retrieving existing ones:
export MASTER_KEY=$(openssl rand -hex 32)
export JOIN_KEY=$(openssl rand -hex 32)Breaking Changes and Customer Impact
| Scenario | Symptom | Resolution |
|---|---|---|
| Upgrade without Join/Master Key | Helm fails with ERROR: MISSING MANDATORY KEYS (or the single-key variant) | Provide keys per How to Provide Keys |
Keys only in old artifactory.joinKey/artifactory.masterKey values but empty | Validation may still fail | Set global.joinKey/global.masterKey, or use Kubernetes Secrets |
| Keys already in system.yaml but the flag isn't set | Validation fails despite keys existing | Set keysPassedViaSystemyaml=true |
| OSS/JCR/CPP-CE customers | JFmelt does not deploy | Expected — JFmelt requires a Pro license and jfconnect.enabled: true |
| Resource planning | More pods mean a higher baseline CPU/memory footprint | Review Hardware Sizing Matrix; update requests/limits |
| Want the smallest footprint (Frontend in-pod, JFBus/JFmelt off) | N/A — these are now the defaults | Disable individually: frontend.asPod: false, jfbus.enabled: false, jfmelt.enabled: false |
splitServicesToContainers Requirement
From Artifactory 7.161.x, splitServicesToContainers: false is no longer supported. Setting it to false fails Helm validation with:
'splitServicesToContainers: false' is no longer supported.
Starting with releases from 7.161.x, the Helm chart no longer supports running all services in a single container.
Set 'splitServicesToContainers: true' to proceed.splitServicesToContainers: true is the default and must remain enabled.
Support Troubleshooting Checklist
- Helm install/upgrade fails immediately — Check for a missing Join Key or Master Key; verify
keysPassedViaSystemyamlis set if keys already exist insystem.yaml. - JFmelt not deploying — Confirm a Pro license,
jfconnect.enabled: true, andjfbus.enabled: true. - Frontend pod not starting — Check the
waitForArtifactoryinit behavior and the Join/Master Key environment variables on the Frontend pod.
Related Topics
- Manage Keys
- Configure Frontend, JFBus, and JFmelt Deployments
- Hardware Sizing Matrix
- Artifactory Helm Upgrade
- Artifactory Product
Frequently Asked Questions
FAQs
Q: Why does my Helm upgrade fail with a MISSING MANDATORY KEYS (or MISSING MASTER_KEY/MISSING JOIN_KEY) error?
MISSING MANDATORY KEYS (or MISSING MASTER_KEY/MISSING JOIN_KEY) error?A: Frontend, JFBus, and JFmelt now run as independent deployments and must each authenticate to the platform using a Join Key and Master Key. Helm validates that both keys are resolvable before proceeding (unless keysPassedViaSystemyaml: true). See How to Provide Keys to resolve this.
Q: I'm on OSS, JCR, or CPP-CE — why doesn't JFmelt deploy?
A: This is expected. JFmelt requires jfbus.enabled: true and jfconnect.enabled: true, and JFConnect itself is only available on Pro and above — the chart detects OSS/JCR/CPP-CE installations by their image repository name and disables JFConnect support there, which in turn keeps JFmelt from deploying.
Q: Can I go back to running Frontend in-pod and JFBus/JFmelt disabled?
A: Yes. Set frontend.asPod: false, jfbus.enabled: false, and jfmelt.enabled: false individually to restore Frontend to the Artifactory StatefulSet pod and turn JFBus/JFmelt off. splitServicesToContainers must remain true — from Artifactory 7.161.x, false is no longer supported.
Q: I get a Deployment.apps is invalid: spec.template.spec.containers[N].volumeMounts[M].name: Not found error — what's wrong?
Deployment.apps is invalid: spec.template.spec.containers[N].volumeMounts[M].name: Not found error — what's wrong?A: You configured router.customVolumeMounts without a matching volume. The router now runs as a sidecar in the Frontend, JFBus, and JFmelt deployments, and each pod needs the volume defined locally — global.customVolumes/artifactory.customVolumes only add the volume to the Artifactory StatefulSet, not to these deployments. Add the corresponding volume under router.customVolumes using the same volume name referenced in router.customVolumeMounts, then re-run helm upgrade. Alternatively, define both global.customVolumeMounts and global.customVolumes so every pod gets the mount and its volume together. See Configure Frontend, JFBus, and JFmelt Deployments for the full pattern.
Q: I use an Oracle database — is there anything extra to configure for AppTrust and Platform Federation?
A: Yes. When using Oracle as your database, configure an initContainer to load the Oracle database drivers for AppTrust and Platform Federation before those services start.
Q: Does this affect Xray or Distribution?
A: No. This change is specific to the artifactory and artifactory-ha charts. Xray and Distribution are unaffected.
Updated 8 days ago
