Self-Hosted Installation
Examples on this page assume chart 1.2.5 or later. For older deployments, contact engineering@plexicus.ai for migration guidance.
Plexicus can be deployed on any Kubernetes cluster using the official Helm chart, published to a private Google Artifact Registry (GAR). This guide walks you through every step — from requesting access credentials to a running installation.
Prerequisites
Where you run these commands
Every command in this guide runs from your operator workstation — the machine that already has kubectl and helm configured to talk to the target Kubernetes cluster (laptop, jump host, or dedicated CI runner). No commands run on the cluster nodes themselves.
Pick a working directory and stay there for the whole install. The chart artifact, your values overlay, and the GAR service-account key all land in the same place:
mkdir -p ~/plexicus-deploy
cd ~/plexicus-deploy
The rest of this guide assumes the current directory is ~/plexicus-deploy. When a command refers to sa-key.json, my-values.yaml, or plexicus/, it means files inside that directory.
CLI tooling on the operator workstation
| Requirement | Minimum version | Notes |
|---|---|---|
| Kubernetes (cluster) | v1.25 | Any CNCF-conformant distribution |
| Helm | v3.8 | OCI registry support is required |
| kubectl | — | Must be configured to target your cluster (kubectl config current-context should show the right context) |
git | any recent | Required only for the ArgoCD / GitOps path |
openssl | any recent | Used to generate random secret values |
| Ingress controller (cluster) | — | Traefik is the default; nginx also works |
| cert-manager (cluster) | v1.x | Recommended for automatic TLS provisioning |
Run helm version to confirm your Helm version. If it is below 3.8, upgrade it before continuing — earlier versions cannot pull OCI charts.
Public DNS, before you start
The chart provisions two externally-reachable Ingress resources: plexicus.<your-domain> (the SPA) and api.plexicus.<your-domain> (the FastAPI backend). Configure both A records to point at your ingress controller's external IP before step 4 (cert-manager) — otherwise Let's Encrypt's HTTP-01 challenge will fail and your TLS certificates will never be issued.
1. Request Registry Access
The Plexicus Helm chart and all container images are hosted in a private GAR repository. You need a Google Cloud service account key to pull them.
Send an email to engineering@plexicus.ai with the following information:
- Your organization name
- The target environment (e.g., staging, production)
- The Kubernetes provider you are using (e.g., GKE, EKS, AKS, on-premises)
You will receive a JSON key file (sa-key.json). Save it to your working directory (~/plexicus-deploy/sa-key.json) — every subsequent command in this guide assumes that path. This file authenticates both Helm (to pull the chart) and Kubernetes (to pull the container images at runtime).
sa-key.json is equivalent to a password. Never commit it to version control, share it over unencrypted channels, or store it in plain text on shared systems. Add sa-key.json to your shell's ~/.gitignore_global if you ever plan to git init inside this directory.
2. Authenticate Helm Against the Registry
Use the service account key to log Helm in to the OCI registry:
cat sa-key.json | helm registry login \
europe-west3-docker.pkg.dev \
--username _json_key \
--password-stdin
A successful login prints Login Succeeded. You only need to do this once per machine.
3. Create the Kubernetes Namespace
kubectl create namespace plexicus
4. Create the Image Pull Secret
Kubernetes needs the same GAR credentials to pull container images at runtime. The chart expects this secret to be named gar-secret:
kubectl create secret docker-registry gar-secret \
--docker-server=europe-west3-docker.pkg.dev \
--docker-username=_json_key \
--docker-password="$(cat sa-key.json)" \
--namespace plexicus
If you rotate the service account key later, re-create this secret with the new key and restart the affected deployments.
5. Create Application Secrets
Plexicus follows a GitOps-safe secrets pattern: sensitive values (passwords, API keys, OAuth secrets) are never stored in values.yaml. Instead, each service reads them from a dedicated Kubernetes Secret at runtime via existingSecret.
You must create all secrets before installing the chart.
Use the same password value for a given dependency (e.g. DATABASE_PASSWORD) across every service that shares it. Mismatches will cause connection errors at runtime.
Key catalog
Eight Secrets are required — one per service that has existingSecret wired:
| Secret name | Required keys |
|---|---|
plexicus-fastapi | DATABASE_PASSWORD, REDIS_PASSWORD, SECRET_KEY, PLEXALYZER_SECRET_KEY, MINIO_ROOT_PASSWORD, OPENAI_API_KEY, plus optional GH_APP_PRIVATE_KEY, GITHUB_CLIENT_SECRET, GITLAB_CLIENT_SECRET, BITBUCKET_CLIENT_SECRET, SMTP_PASSWORD, STRIPE_API_KEY, STRIPE_WEBHOOK_SECRET, BREAK_GLASS_SECRET_KEY, SSO_RELAY_STATE_SECRET, SSO_ENCRYPTION_KEY (only the integrations you use; SSO keys required only when SAML/OIDC SSO is enabled) |
plexicus-worker | DATABASE_PASSWORD, REDIS_PASSWORD, SECRET_KEY, PLEXALYZER_SECRET_KEY, GH_APP_PRIVATE_KEY, MINIO_ROOT_PASSWORD, PLEXALYZER_TOKEN, OPENAI_API_KEY |
plexicus-frontend | NUXT_SECRET_KEY |
plexicus-analysis-scheduler | DATABASE_PASSWORD, OPENAI_API_KEY |
plexicus-codex-remedium | DATABASE_PASSWORD, REDIS_PASSWORD, PLEXALYZER_SECRET_KEY, OPENAI_API_KEY |
plexicus-exporter | DATABASE_PASSWORD, OPENAI_API_KEY |
plexicus-plexalyzer-code | PLEXALYZER_SECRET_KEY, OPENAI_API_KEY |
plexicus-plexalyzer-prov | PLEXALYZER_SECRET_KEY, OPENAI_API_KEY |
DATABASE_PASSWORD, REDIS_PASSWORD, MINIO_ROOT_PASSWORD, PLEXALYZER_SECRET_KEY, PLEXALYZER_TOKEN, OPENAI_API_KEY, and SECRET_KEY MUST be identical across every Secret that lists them. They are the same credential consumed by different services. Mismatches cause MongoDB Authentication failed, WRONGPASS from Redis, and Plexalyzer worker handshake failures at runtime.
OPENAI_API_KEY can be a regular OpenAI API key, an Azure OpenAI endpoint key, or a DeepSeek key — set the matching global.required.ai.openAiBaseUrlSwe to the provider's URL.
Bootstrap all eight secrets
The recipe below sets a handful of shell variables once, then creates every Secret. Run it from ~/plexicus-deploy after step 4. Replace each <...> placeholder.
When you choose DB_PASS, REDIS_PASS, and MINIO_PASS, use only letters and digits (e.g. openssl rand -hex 24). pymongo refuses to URL-encode special characters (@, :, /, ?, #, %, !, $) in connection URIs and will fail with Username and password must be escaped according to RFC 3986. Redis and MinIO have similar quoting traps in their clients.
# === Shared values (set once, used across multiple Secrets) ===
DB_PASS='<choose-a-strong-mongo-root-password>'
REDIS_PASS='<choose-a-redis-password>'
MINIO_PASS='<choose-a-minio-password>'
SECRET_KEY=$(openssl rand -hex 32) # Plexicus signing key
PLEXALYZER_SECRET=$(openssl rand -hex 32) # Plexalyzer worker handshake
NUXT_SECRET=$(openssl rand -hex 32) # Nuxt session secret
OPENAI_KEY='<your-openai-or-azure-or-deepseek-api-key>'
# === Optional integration secrets — leave empty if not used ===
GH_OAUTH_SECRET="" # GitHub OAuth client_secret (App or OAuth App)
GL_OAUTH_SECRET="" # GitLab OAuth client_secret
BB_OAUTH_SECRET="" # Bitbucket OAuth client_secret
SMTP_PASS="" # SMTP password for transactional email
# === SSO / SAML / OIDC secrets — required only when SSO is enabled ===
# Generate strong random values; safe to populate even if SSO is off
# (they're only consumed when SAML/OIDC handlers are invoked).
BREAK_GLASS=$(openssl rand -hex 32) # Emergency-admin bypass key
SSO_RELAY=$(openssl rand -hex 32) # HMAC for SAML RelayState signing
SSO_ENCRYPT=$(openssl rand -hex 32) # AES-256 key for OIDC client_secret encryption at rest
# === Eight secrets — copy/paste the entire block ===
kubectl -n plexicus create secret generic plexicus-fastapi \
--from-literal=DATABASE_PASSWORD="$DB_PASS" \
--from-literal=REDIS_PASSWORD="$REDIS_PASS" \
--from-literal=SECRET_KEY="$SECRET_KEY" \
--from-literal=PLEXALYZER_SECRET_KEY="$PLEXALYZER_SECRET" \
--from-literal=MINIO_ROOT_PASSWORD="$MINIO_PASS" \
--from-literal=SWE_OPENAI_API_KEY="$OPENAI_KEY" \
--from-literal=DEPLOYMENT_MANAGER_OPENAI_API_KEY_FREE="$OPENAI_KEY" \
--from-literal=GH_APP_PRIVATE_KEY="" \
--from-literal=GITHUB_CLIENT_SECRET="$GH_OAUTH_SECRET" \
--from-literal=GITLAB_CLIENT_SECRET="$GL_OAUTH_SECRET" \
--from-literal=BITBUCKET_CLIENT_SECRET="$BB_OAUTH_SECRET" \
--from-literal=SMTP_PASSWORD="$SMTP_PASS" \
--from-literal=BREAK_GLASS_SECRET_KEY="$BREAK_GLASS" \
--from-literal=SSO_RELAY_STATE_SECRET="$SSO_RELAY" \
--from-literal=SSO_ENCRYPTION_KEY="$SSO_ENCRYPT"
kubectl -n plexicus create secret generic plexicus-worker \
--from-literal=DATABASE_PASSWORD="$DB_PASS" \
--from-literal=REDIS_PASSWORD="$REDIS_PASS" \
--from-literal=SECRET_KEY="$SECRET_KEY" \
--from-literal=PLEXALYZER_SECRET_KEY="$PLEXALYZER_SECRET" \
--from-literal=GH_APP_PRIVATE_KEY="" \
--from-literal=MINIO_ROOT_PASSWORD="$MINIO_PASS" \
--from-literal=PLEXALYZER_TOKEN="$PLEXALYZER_SECRET"
kubectl -n plexicus create secret generic plexicus-frontend \
--from-literal=NUXT_SECRET_KEY="$NUXT_SECRET"
kubectl -n plexicus create secret generic plexicus-analysis-scheduler \
--from-literal=DATABASE_PASSWORD="$DB_PASS"
kubectl -n plexicus create secret generic plexicus-codex-remedium \
--from-literal=DATABASE_PASSWORD="$DB_PASS" \
--from-literal=REDIS_PASSWORD="$REDIS_PASS" \
--from-literal=PLEXALYZER_SECRET_KEY="$PLEXALYZER_SECRET"
kubectl -n plexicus create secret generic plexicus-exporter \
--from-literal=DATABASE_PASSWORD="$DB_PASS" \
--from-literal=OPENAI_API_KEY="$OPENAI_KEY"
for s in plexalyzer-code plexalyzer-prov; do
kubectl -n plexicus create secret generic plexicus-$s \
--from-literal=PLEXALYZER_SECRET_KEY="$PLEXALYZER_SECRET"
done
# Verify
kubectl -n plexicus get secrets | grep ^plexicus-
# Expected: 8 plexicus-* secrets
If you operate a real GitHub App (preferred over plain OAuth for production), replace the empty GH_APP_PRIVATE_KEY="" with GH_APP_PRIVATE_KEY="$(cat /path/to/gh-app.pem)" in both plexicus-fastapi and plexicus-worker.
6. Install Infrastructure Prerequisites
Plexicus depends on five infrastructure services: MongoDB, Redis, MinIO, PostgreSQL, and Temporal. They are not bundled in the umbrella chart — bundling produced an artifact that exceeded the 1 MB Kubernetes Secret limit Helm uses for release storage. Install each as a separate Helm release in the plexicus namespace before installing the umbrella chart. Customers who already operate any of these services can skip the corresponding install and point Plexicus at their existing endpoints via global.required.* and global.dependencies.* overrides.
Bitnami moved the official chart images to a paid distribution. Free legacy images live under docker.io/bitnamilegacy/*. The commands below override every image reference (main + init containers + sidecars) to use the legacy registry. If you mirror these into your own registry, replace bitnamilegacy/ with your mirror path.
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo add temporal https://go.temporal.io/helm-charts
helm repo update
# 1. MongoDB
helm upgrade --install mongodb bitnami/mongodb --version 18.6.15 -n plexicus \
--set global.security.allowInsecureImages=true \
--set image.repository=bitnamilegacy/mongodb \
--set defaultInitContainers.volumePermissions.image.repository=bitnamilegacy/os-shell \
--set metrics.image.repository=bitnamilegacy/mongodb-exporter \
--set 'auth.rootPassword=<your-mongo-root-password>' \
--set 'auth.databases={plexicus}' \
--set 'auth.usernames={plexicus}' \
--set 'auth.passwords={<your-plexicus-db-password>}' \
--set persistence.size=10Gi --wait
# 2. Redis
helm upgrade --install redis bitnami/redis --version 25.3.2 -n plexicus \
--set global.security.allowInsecureImages=true \
--set image.repository=bitnamilegacy/redis \
--set sentinel.image.repository=bitnamilegacy/redis-sentinel \
--set metrics.image.repository=bitnamilegacy/redis-exporter \
--set kubectl.image.repository=bitnamilegacy/kubectl \
--set defaultInitContainers.volumePermissions.image.repository=bitnamilegacy/os-shell \
--set sysctl.image.repository=bitnamilegacy/os-shell \
--set auth.password=<your-redis-password> \
--set replica.replicaCount=0 \
--set master.persistence.size=4Gi --wait
# 3. MinIO
helm upgrade --install minio bitnami/minio --version 17.0.21 -n plexicus \
--set global.security.allowInsecureImages=true \
--set image.repository=bitnamilegacy/minio \
--set defaultInitContainers.volumePermissions.image.repository=bitnamilegacy/os-shell \
--set console.image.repository=bitnamilegacy/minio-object-browser \
--set apiIngress.enabled=false --set ingress.enabled=false \
--set auth.rootUser=<your-minio-user> \
--set auth.rootPassword=<your-minio-password> \
--set defaultBuckets=platform \
--set persistence.size=10Gi --wait
# 4. PostgreSQL (for Temporal)
helm upgrade --install temporal-postgresql bitnami/postgresql --version 18.5.6 -n plexicus \
--set global.security.allowInsecureImages=true \
--set image.repository=bitnamilegacy/postgresql \
--set metrics.image.repository=bitnamilegacy/postgres-exporter \
--set defaultInitContainers.volumePermissions.image.repository=bitnamilegacy/os-shell \
--set auth.postgresPassword=<your-temporal-pg-password> \
--set primary.persistence.size=4Gi --wait
# 5. Temporal
# NOTE: --wait is intentionally omitted. Temporal pods crash-loop for ~2
# minutes while the schema-setup Job seeds the database — that is expected.
# Wait for the schema Job to complete (the section below polls the pods).
helm upgrade --install temporal temporal/temporal --version 0.73.2 -n plexicus \
--set server.replicaCount=1 \
--set cassandra.enabled=false --set elasticsearch.enabled=false \
--set prometheus.enabled=false --set grafana.enabled=false \
--set server.config.persistence.default.driver=sql \
--set server.config.persistence.default.sql.driver=postgres12 \
--set server.config.persistence.default.sql.host=temporal-postgresql \
--set server.config.persistence.default.sql.port=5432 \
--set server.config.persistence.default.sql.database=temporal \
--set server.config.persistence.default.sql.user=postgres \
--set server.config.persistence.default.sql.password=<your-temporal-pg-password> \
--set server.config.persistence.visibility.driver=sql \
--set server.config.persistence.visibility.sql.driver=postgres12 \
--set server.config.persistence.visibility.sql.host=temporal-postgresql \
--set server.config.persistence.visibility.sql.port=5432 \
--set server.config.persistence.visibility.sql.database=temporal_visibility \
--set server.config.persistence.visibility.sql.user=postgres \
--set server.config.persistence.visibility.sql.password=<your-temporal-pg-password>
kubectl -n plexicus get pods # confirm all 5 prereqs are Running before continuing
The default in-cluster service names produced by these installs are mongodb, redis-master, minio, temporal-postgresql, and temporal-frontend. Chart 1.2.5+ defaults global.required.database.host, global.required.redis.host, global.required.minio.service, and the wait-loop endpoints to those names — so as long as you used the release names above, the customer overlay does not need to repeat them. Override only when connecting to externally-managed services or when ArgoCD prefixes the release names (see the ArgoCD section below).
7. Prepare Your Values File
The remaining commands in this guide reference a $CHART_VERSION shell variable. Set it once to the version you want to install — your Plexicus contact will provide the current version when you receive registry credentials. To upgrade later, contact engineering@plexicus.ai for the latest version.
export CHART_VERSION=1.2.6
This variable persists for the rest of your shell session.
Instead of dumping the full 700-line default values file, start from the canonical customer overlay that ships inside the chart artifact. Pull and extract the chart, then copy the example overlay:
# Pull and extract the chart (creates a ./plexicus/ directory)
helm pull oci://europe-west3-docker.pkg.dev/plexicus-registry/charts/plexicus \
--version $CHART_VERSION --untar
# Copy the canonical customer overlay
cp plexicus/values-customer.yaml.example my-values.yaml
# Edit my-values.yaml to replace every <to-fill> placeholder
The relevant contents of the overlay are shown below (~30 lines):
global:
# Your root domain — all service URLs are derived from this.
domain: plexicus.yourdomain.com # REQUIRED
scheme: "https"
wsScheme: "wss"
# Ingress controller class applied to ALL eight service Ingress resources.
ingressClassName: "traefik" # also: "nginx", "gce", "alb"
# When enabled, the chart injects cert-manager.io/cluster-issuer on every
# Ingress that has TLS configured. Set enabled: false if you manage TLS yourself.
certManager:
enabled: true
clusterIssuer: "letsencrypt-prod"
imagePullSecrets:
- name: gar-secret
fastapi:
ingress:
enabled: true
hosts:
- host: api.plexicus.yourdomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: plexicus-fastapi-tls
hosts:
- api.plexicus.yourdomain.com
existingSecret: plexicus-fastapi
frontend:
ingress:
enabled: true
hosts:
- host: plexicus.yourdomain.com
paths:
- path: /
pathType: Prefix
tls:
- secretName: plexicus-frontend-tls
hosts:
- plexicus.yourdomain.com
existingSecret: plexicus-frontend
worker:
existingSecret: plexicus-worker
analysis-scheduler:
existingSecret: plexicus-analysis-scheduler
codex-remedium:
existingSecret: plexicus-codex-remedium
exporter:
existingSecret: plexicus-exporter
plexalyzer-code:
existingSecret: plexicus-plexalyzer-code
plexalyzer-prov:
existingSecret: plexicus-plexalyzer-prov
global.domain is required and validated by values.schema.json — the install fails fast if it is empty.
Chart 1.2.5+ defaults the in-cluster service names (mongodb, redis-master, minio:9000), the cross-service URLs (FastAPI's importer / notification / receive endpoints), the AI endpoint (DeepSeek's OpenAI-compatible API), and the Cloudflare Turnstile keys (test tokens for eval). All sensitive values (passwords, OAuth client secrets, API keys, real Turnstile keys for production) come from the eight existingSecret references — they are never written into my-values.yaml.
Override entries in global.required.* only when:
- you connect the chart to externally-managed MongoDB / Redis / MinIO / Temporal (different host/port than the prereq install in step 6 produced),
- you use a non-default release name for the prereqs (e.g. ArgoCD prefixes them — see the ArgoCD section below),
- you run production and need to set real Cloudflare Turnstile keys, real OAuth client_id values, or your own AI provider URL.
Cloudflare Turnstile (production)
Plexicus' login form is gated by Cloudflare Turnstile. The chart defaults to Cloudflare's documented "always passes" test tokens (1x00000000000000000000AA / 1x0000000000000000000000000000000AA) so that fresh installs reach the login form without further configuration. For any production deployment you must replace both with real keys generated at dash.cloudflare.com → Turnstile — leaving the test tokens in place effectively disables bot protection.
global:
required:
turnstile:
siteKey: "0x4AAAAAAA…YOUR-SITEKEY" # public — rendered into the login page
secretKey: "0x4AAAAAAA…YOUR-SERVER-SECRET" # private — server-side validation
successToken: "XXXX.DUMMY.TOKEN.XXXX" # used only for end-to-end test fixtures
Both siteKey and secretKey are required for the Nuxt frontend to render the Turnstile widget AND to verify tokens server-side at /api/_turnstile/validate. Mismatched or empty values surface as either skeleton-loader inputs that never resolve (sitekey wrong) or Turnstile validation failed, Please try again after submitting the form (secret wrong).
CORS allow-list
The chart's fastapi.envs.CORS_ORIGINS defaults to <scheme>://<domain>,<scheme>://api.<domain> so the SPA at the same domain plus the api subdomain works out of the box. Override fastapi.envs.CORS_ORIGINS in your customer overlay only if you front the SPA on additional hostnames (multi-tenant, branded subdomains, embedded iframe). An empty CORS_ORIGINS makes every cross-origin request return 400 Disallowed CORS origin.
global.ingressClassName (default: traefik) and global.certManager.enabled + global.certManager.clusterIssuer (default: letsencrypt-prod) apply to all eight Ingress resources automatically. Per-service overrides via <service>.ingress.className or <service>.ingress.annotations are possible but rarely needed.
Only fastapi and frontend are externally reachable. The other six services (worker, analysis-scheduler, codex-remedium, exporter, plexalyzer-code, plexalyzer-prov) are cluster-internal and do not need Ingress.
8. Install the Chart
helm upgrade --install plexicus \
oci://europe-west3-docker.pkg.dev/plexicus-registry/charts/plexicus \
--version $CHART_VERSION \
--namespace plexicus \
--values my-values.yaml
The installation takes a few minutes while all pods and dependencies initialize. upgrade --install is idempotent — re-running it after fixing a values typo does the right thing instead of erroring with release plexicus already exists.
9. Verify the Installation
# All pods should reach Running or Completed status
kubectl get pods -n plexicus
# Ingress should have an external address assigned
kubectl get ingress -n plexicus
Pods typically reach a healthy state within 3–5 minutes. If a pod is stuck in CrashLoopBackOff or Error, inspect its logs:
kubectl logs -n plexicus <pod-name> --previous
Common causes are missing secret keys or incorrect connection details in my-values.yaml.
After install, Helm prints a NEXT STEPS banner (templates/NOTES.txt) with verification commands tailored to your release. Re-display it any time with:
helm get notes plexicus -n plexicus
A first end-to-end smoke test from outside the cluster:
curl -s -o /dev/null -w "Frontend %{http_code}\n" https://<your-domain>/
curl -s -o /dev/null -w "API/health %{http_code}\n" https://api.<your-domain>/health
# Frontend 302 (the SPA's login redirect — Tier A passes)
# API/health 200 (FastAPI is reading from MongoDB / Redis / MinIO / Temporal)
A trusted-TLS verification (no -k needed when using a public ClusterIssuer):
curl -s -o /dev/null -w "TLS verify=%{ssl_verify_result}\n" https://<your-domain>/
# TLS verify=0 (publicly trusted certificate)
10. Bootstrap the First Admin User
The chart ships with an empty database. Plexicus does not seed an initial admin during install — every account is created through the registration API. The default registration flow expects email verification via SMTP; on a brand-new install the very first admin therefore has to be either:
- (Recommended for production) registered through the regular UI flow once
SMTP_*credentials are wired intoplexicus-fastapi(the user clicks the verification link in the welcome email), or - (Bootstrap-only shortcut) registered via the API and then flagged
is_verified: truedirectly on theUsersMongoDB collection — useful for environments where SMTP is intentionally not configured (air-gapped, internal-only, or staging).
10.1 Register the user via the API
The schema validator requires at least one uppercase letter, one lowercase letter, one digit, and one special character:
curl -s -X POST -H "Content-Type: application/json" \
-d '{
"email":"admin@your-domain.example",
"password":"ChangeMeNow1!",
"confirm_password":"ChangeMeNow1!",
"first_name":"Admin",
"last_name":"User",
"company":"Your Company"
}' \
https://api.<your-domain>/register
# {"success":true,"message":"User successfully registered. Please check your email for verification link."}
If SMTP is wired up, the user clicks the link in the welcome email and is done. Skip to step 10.3.
10.2 (Bootstrap shortcut) Manually verify the user in MongoDB
This shortcut writes directly to MongoDB. In production, prefer wiring real SMTP credentials and using the verification email. Use the shortcut only for the very first admin in eval / staging / air-gapped clusters.
The collection name is Users (capital U); the verification flag is is_verified:
kubectl -n plexicus exec deploy/mongodb -- mongosh \
# ↑ if you installed via the ArgoCD path the deploy is named `plexicus-mongodb` —
# substitute `deploy/plexicus-mongodb` in this command and the next.
#
"mongodb://root:<your-mongo-root-password>@localhost:27017/plexicus?authSource=admin" \
--quiet --eval '
db.Users.updateOne(
{ email: "admin@your-domain.example" },
{ $set: { is_verified: true, role: "admin" } }
)
'
# { acknowledged: true, matchedCount: 1, modifiedCount: 1 }
10.3 Log in
curl -s -X POST -H "Content-Type: application/json" \
-d '{"email":"admin@your-domain.example","password":"ChangeMeNow1!"}' \
https://api.<your-domain>/login
# {"access_token":"eyJhbGc…","token_type":"bearer"}
A 200 with an access_token confirms the full chain — frontend → ingress → fastapi → MongoDB authentication — is healthy. Open https://<your-domain> in a browser and sign in with the credentials you just registered.
11. Connect a SCM and run your first scan
The first run-through has two paths: a Sandbox option that uses Plexicus' pre-configured vulnerable repository (no OAuth required, useful for verifying the install end-to-end before integrating with your real Git host) and a Production / Connect SCM option that wires the platform to GitHub / GitLab / Bitbucket / Gitea via OAuth.
The screenshots below were captured against a working install at https://demo.plexicus.com. Substitute your own hostname.
11.1 Sign in to the panel
Open https://<your-domain> in your browser and sign in with the admin user you bootstrapped in step 10.

11.2 Accept the Beta Agreement
The first time any user logs in, a modal asks them to read and accept the Plexicus Beta Agreement. Scroll the modal to the bottom — the Continue button is disabled until the inner scrollbar reaches the bottom — then click Continue.

11.3 Pick your onboarding path
Onboarding offers two cards: Connect SCM (production — real OAuth redirect) or Go To Sandbox (eval — pre-configured vulnerable repo, no OAuth).

Sandbox path (recommended for the first scan)
Click Go To Sandbox. Plexicus presents a catalogue of pre-configured repositories — simplest-vulnerable is the canonical demo target. Click the card to select it.

The branch dropdown defaults to main. Confirm and click Continue.

Plexicus shows the Scanning in progress screen while the worker pipeline (clone → SAST → SCA → enrichment) runs. The sandbox scan typically completes in 2 minutes; real-world repos take 1–5 minutes for a small project, longer for monorepos.

Production path — register OAuth apps first
For production deployments, Connect SCM uses a real OAuth 2.0 redirect flow. Each provider must have an OAuth application registered on its side, with a callback URL that exactly matches the URL Plexicus will redirect to. If the registered callback doesn't match, the provider rejects the request with 400 redirect_uri_mismatch (GitHub) or equivalent.
Substitute <your-domain> (e.g. plexicus.acme.com) in every URL below — they all point at the SPA domain, not the API subdomain.
| Provider | Authorization callback URL to register |
|---|---|
| GitHub | https://<your-domain>/api/callback/github |
| GitLab | https://<your-domain>/api/callback/gitlab |
| Bitbucket Cloud | https://<your-domain>/api/callback/bitbucket_cloud |
| Google (SSO) | https://<your-domain>/api/callback/google |
The eval install at https://plexicus.local does not need OAuth apps — the Sandbox path uses a synthetic SCM connector that bypasses the real OAuth flow. OAuth registration is required only when connecting Plexicus to real GitHub / GitLab / Bitbucket repositories from a public hostname.
GitHub — register an OAuth App
For per-user OAuth (the simplest path):
- On GitHub, navigate to Settings → Developer settings → OAuth Apps → New OAuth App (direct link). For organisation-wide installs, register the app under the organisation's settings instead of your personal account.
- Fill the form:
- Application name:
Plexicus(or any label your users will see on the consent screen) - Homepage URL:
https://<your-domain> - Authorization callback URL:
https://<your-domain>/api/callback/github← exactly this path - Application description: optional
- Leave Enable Device Flow unchecked
- Application name:
- Click Register application.
- On the resulting page, copy the Client ID (visible) and click Generate a new client secret to reveal the Client Secret (shown only once — copy it before navigating away).
For richer integration (webhooks, branch checks, repo-level metadata), use GitHub Apps instead: Settings → Developer settings → GitHub Apps → New GitHub App. Set the same callback URL and grant the repository Metadata: Read-only, Contents: Read-only, Pull requests: Read & Write, Webhooks: Read & Write. Download the generated private-key .pem file and note the App ID — these go into GH_APP_PRIVATE_KEY and GITHUB_APP_ID instead of (or alongside) the OAuth client credentials.
GitLab — register an OAuth Application
- On GitLab, navigate to User settings → Applications → New application (direct link) — or Admin Area → Applications for instance-wide registration on self-hosted GitLab.
- Fill the form:
- Name:
Plexicus - Redirect URI:
https://<your-domain>/api/callback/gitlab - Confidential: keep checked
- Scopes:
read_user,read_api,read_repository,read_registry(addapiif you want write access for PR comments / merge requests)
- Name:
- Click Save application.
- Copy the Application ID (=
clientId) and the Secret shown on the next page (visible only once).
Bitbucket Cloud — register an OAuth Consumer
- On Bitbucket, navigate to Workspace settings → OAuth consumers → Add consumer (go to Bitbucket Cloud and pick the workspace).
- Fill the form:
- Name:
Plexicus - Callback URL:
https://<your-domain>/api/callback/bitbucket_cloud - URL:
https://<your-domain>(homepage) - This is a private consumer: keep checked
- Permissions: Account
Read; RepositoriesRead; Pull requestsRead(addWritefor inline-comment integration)
- Name:
- Click Save.
- Expand the new consumer entry to reveal the Key (=
clientId) and Secret (=clientSecret).
Wire the credentials into Plexicus
OAuth credentials split into two halves: the client_id is public (rendered into the SPA's Login button URL) and the client_secret is private (used only by the FastAPI backend and the Nuxt SSR layer to exchange the OAuth code for an access token).
Public IDs go into your customer values overlay (my-values.yaml):
global:
required:
oauth:
github:
clientId: "Iv1.abcdef0123456789" # GitHub OAuth App "Client ID"
# appId / appPrivateKey only if you registered a GitHub App (not OAuth App):
# appId: 1234567
# appInstallationUrl: "https://github.com/apps/<your-app-slug>/installations/new"
gitlab:
clientId: "abcdef0123456789abcdef..." # GitLab Application ID
bitbucket:
key: "abcdef0123456789abcd" # Bitbucket Consumer Key
google:
clientId: "1234567890-abcdef.apps.googleusercontent.com"
Private secrets go into the plexicus-fastapi Kubernetes Secret you created in step 5 (re-create with the new keys, or kubectl edit secret to add them):
kubectl -n plexicus create secret generic plexicus-fastapi \
... existing keys ... \
--from-literal=GITHUB_CLIENT_SECRET="<github-oauth-client-secret>" \
--from-literal=GITLAB_CLIENT_SECRET="<gitlab-application-secret>" \
--from-literal=BITBUCKET_CLIENT_SECRET="<bitbucket-consumer-secret>" \
--dry-run=client -o yaml | kubectl apply -f -
If you registered a GitHub App (not an OAuth App), also add the private key:
kubectl -n plexicus patch secret plexicus-fastapi \
--type=json -p='[{"op":"add","path":"/data/GH_APP_PRIVATE_KEY","value":"'$(base64 -w0 < ~/Downloads/your-app.private-key.pem)'"}]'
kubectl -n plexicus patch secret plexicus-worker \
--type=json -p='[{"op":"add","path":"/data/GH_APP_PRIVATE_KEY","value":"'$(base64 -w0 < ~/Downloads/your-app.private-key.pem)'"}]'
Roll the workloads so the new env vars take effect:
helm upgrade plexicus oci://europe-west3-docker.pkg.dev/plexicus-registry/charts/plexicus \
--version $CHART_VERSION --namespace plexicus -f my-values.yaml
kubectl -n plexicus rollout restart deploy/fastapi deploy/frontend deploy/worker
Now click Connect SCM
After the rollout completes, return to the Connectors page, find your provider, and click Connect:
- Open the Connectors entry in the left sidebar.
- Find your SCM (GitHub / GitLab / Bitbucket) in the SCM Integrations panel and click Connect.
- Plexicus redirects to the provider's authorize URL. Log in and click Authorize Plexicus.
- The provider redirects back to
https://<your-domain>/api/callback/<provider>and the connector card displays Connected.
If you see redirect_uri_mismatch (GitHub) or invalid_redirect_uri (GitLab/Bitbucket) in the browser address bar after step 3, the Authorization callback URL registered with the provider does not match what Plexicus sent. Re-check it: the value must be exactly https://<your-domain>/api/callback/<provider> — same scheme (https vs http), same hostname (no api. prefix), no trailing slash, no path query string.
The OAuth redirect is browser-only — there is no Personal Access Token or API shortcut. Once a SCM is connected through the browser, every subsequent operation is available over the REST API for CI / scripting (POST /create_repository_with_list, POST /request_repo_scan, GET /findings).
Add a repository and scan
After Connect succeeds, the Applications page replaces the Sandbox flow:
- Open Applications in the left sidebar and click Add applications.
- Pick the SCM connector you just authorized.
- Choose a repository, set a nickname, pick the branch (defaults to
main). - Click Create selected repositories.
- Open the new repository entry and click Run scan.
11.4 Land on the Dashboard
After the scan completes Plexicus drops you on the Dashboard, which summarises platform value (saved cost, returned engineering time, comparison vs industry baseline) and surfaces the Findings Report panel ready to populate as more scans accumulate.

11.5 Review the repository in Assets
Open Assets in the left sidebar. Each connected repository appears with a TOOLS badge showing the scanner state — enriching while the AI piloting service annotates findings, then transitioning to the final scanned state. The FINDINGS, PIPELINE, PRIORITY, and TAGS columns populate as enrichment completes.

11.6 Open the Findings page
Open Findings in the left sidebar. The page splits into Repo / SCM / Cloud / Registry tabs (Repo is the default). On a brand-new install, the default view often shows the "Zero findings remaining" empty state — the SAST scanner produced findings, the AI enriched them, and they sit in the enriched / completed state until you act on them.

Click the funnel icon next to the search box and include statuses like enriched and completed to make every finding visible, or open the repository tile from Assets (11.5) and drill in for a per-repo view. From there each finding shows the affected file, the matched rule, and the AI-generated remediation patch.
Day 2 References
The chart artifact bundles operator documentation under docs/. After running helm pull --untar (see step 7), the following guides are available locally:
ls plexicus/docs/
getting-started.md— customer install walk-throughsecrets-management.md— secrets catalog and ESO/Sealed Secrets recipesingress-tls.md— ingress and TLS configurationimage-registry.md— image mirroring and air-gapped deploymentsupgrading.md— how to upgrade to a new chart version and roll backtroubleshooting.md— common install failures and fixesuninstall.md— clean removal of all chart resources
These ship with the chart and stay in sync with the version you installed. For environment-specific guidance, contact engineering@plexicus.ai.
12. Upgrading
Contact engineering@plexicus.ai to obtain the latest chart version, then run:
helm upgrade plexicus \
oci://europe-west3-docker.pkg.dev/plexicus-registry/charts/plexicus \
--version <new-version> \
--namespace plexicus \
--values my-values.yaml
Review the release notes provided by the Plexicus team before upgrading. Any breaking changes or required values migrations will be described there.
ArgoCD Deployment (Alternative)
If you manage your cluster with ArgoCD, you can point it directly at the OCI chart instead of using the Helm CLI.
The procedure below was validated end-to-end on demo.plexicus.com (k3s + ArgoCD v3, Helm chart 1.2.5+). The reference manifest set lives in the chart repo at argocd/prereqs/applications-prereqs.yaml and argocd/application.yaml — extract via helm pull --untar and adapt to your environment. Key gotchas surfaced during validation:
- Prereq service names take the
<release-name>-prefix. When ArgoCD creates the Bitnami Helm releases as Applications namedplexicus-mongodb,plexicus-redis, etc., the in-cluster Services areplexicus-mongodb,plexicus-redis-master,plexicus-temporal-postgresql,plexicus-temporal-frontend, etc. — not the baremongodb/redis-masterdefaults. Updateglobal.required.database.host,global.required.minio.service,global.required.redis.host,global.dependencies.temporal.host, andglobal.dependencies.redis.hostin the umbrella Application'shelm.valuesblock to match. (SettingfullnameOverrideon each prereq Application is an alternative if you prefer the bare names.) - The AppProject's
sourceReposlist must include every chart source you reference, including the OCI registry that hosts the Plexicus chart. Either enumerate them explicitly or usesourceRepos: ['*']in development. - Self-signed certificates on the chart's OCI registry break ArgoCD's repo-server pull even when
insecure: "true"is set on the repository Secret. Either expose the registry behind an Ingress with a publicly trusted (Let's Encrypt) certificate, OR mount your private CA into theargocd-repo-serverpod's truststore. The first option is simpler — register a DNS record likeregistry.<your-domain>pointing at the cluster, add a cert-manager-issued LE certificate to the registry's Ingress, and usehttps://registry.<your-domain>/chartsas the OCI URL. - Image-tag drift between bundled Plexicus services and the published GAR images. The chart pins
<service>.image.tagto the chart version (e.g.1.2.6), but the actual GAR images use independent build numbers (1.0.NNN) with alatestfloating tag. Either override<service>.image.tag: latestin the umbrella'shelm.values(acceptable for evaluation), or pin specific build tags per service for reproducible production deployments.
Create the GitOps repository
ArgoCD pulls Application manifests from a Git repository — that is the heart of the GitOps model. Even when the chart itself lives in OCI (and is referenced by repoURL in the umbrella Application), the Application manifest, AppProject, prereq Applications, and any environment-specific overlay still live in Git so that every change is auditable, peer-reviewable, and revertable.
If you already have a GitOps repo, skip this step and adapt the layout to match. If not, create one now.
Recommended layout for an evaluator who is starting from scratch:
plexicus-gitops/
├── README.md # Operator notes for the team
├── projects/
│ └── plexicus-appproject.yaml # Restricts which sources/destinations are allowed
├── apps/
│ ├── plexicus-app.yaml # Umbrella Plexicus Application (sync-wave 5)
│ └── prereqs/
│ ├── mongodb-app.yaml # All five prereqs (sync-wave 0)
│ ├── redis-app.yaml
│ ├── minio-app.yaml
│ ├── temporal-postgresql-app.yaml
│ └── temporal-app.yaml
├── values/
│ └── plexicus-prod.yaml # Environment-specific overlay (NO secrets)
└── secrets/
└── README.md # Pointer to your secrets backend (do NOT commit raw Secret YAML)
Initialize the repo from your operator workstation:
cd ~/plexicus-deploy
mkdir -p plexicus-gitops/{projects,apps/prereqs,values,secrets}
cd plexicus-gitops
git init -b main
cat > .gitignore <<'EOF'
# Never commit raw credentials — the OCI repo Secret in step 2
# contains the GAR service-account JSON.
repo-gar.yaml
sa-key.json
*.key
*.pem
EOF
git add .gitignore
git commit -m "chore: bootstrap plexicus GitOps repo"
Push to a private remote (GitHub, GitLab, Bitbucket, Gitea, or your internal Git host). Use HTTPS with a personal-access token or SSH — ArgoCD will use the same credentials when it pulls.
git remote add origin git@github.com:<your-org>/plexicus-gitops.git
git push -u origin main
Register the repo with ArgoCD. Apply a Secret in the argocd namespace labelled argocd.argoproj.io/secret-type: repository. Pick the auth flavor that matches your remote and apply via heredoc — do NOT commit this Secret to Git, your .gitignore from the previous step already excludes it.
For SSH (recommended for production):
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Secret
metadata:
name: plexicus-gitops-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
type: Opaque
stringData:
type: git
url: git@github.com:<your-org>/plexicus-gitops.git
sshPrivateKey: |
-----BEGIN OPENSSH PRIVATE KEY-----
<paste the deploy key here>
-----END OPENSSH PRIVATE KEY-----
EOF
For HTTPS with a personal-access token:
kubectl apply -f - <<'EOF'
apiVersion: v1
kind: Secret
metadata:
name: plexicus-gitops-repo
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
type: Opaque
stringData:
type: git
url: https://github.com/<your-org>/plexicus-gitops.git
username: <bot-user>
password: <github-pat> # use a fine-grained PAT scoped to this repo only
EOF
AppProject — restrict allowed sources. Save the following as projects/plexicus-appproject.yaml inside the GitOps repo. The sourceRepos list must include both your GitOps Git URL and the Plexicus OCI registry — ArgoCD rejects any Application that references a source not on this list.
apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
name: plexicus
namespace: argocd
spec:
description: Plexicus platform deployment
sourceRepos:
- https://github.com/<your-org>/plexicus-gitops.git
- europe-west3-docker.pkg.dev/plexicus-registry/charts
- https://charts.bitnami.com/bitnami
- https://go.temporal.io/helm-charts
destinations:
- namespace: plexicus
server: https://kubernetes.default.svc
- namespace: argocd
server: https://kubernetes.default.svc
clusterResourceWhitelist:
- group: ""
kind: Namespace
- group: cert-manager.io
kind: ClusterIssuer
namespaceResourceWhitelist:
- group: "*"
kind: "*"
For an evaluator-style throwaway environment you can skip the whitelist tightening and just use sourceRepos: ["*"] plus destinations: [{namespace: "*", server: "*"}], but do not ship that to production.
Secrets handling — never commit raw Secret YAML. The plexicus-fastapi, plexicus-worker, etc. Secrets contain database passwords, OAuth client secrets, and API keys. Pick one of:
- Sealed Secrets (
bitnami-labs/sealed-secrets) — encrypt with a public key tied to the cluster, commit theSealedSecretciphertext, controller decrypts in-cluster. Simplest for a single cluster. - External Secrets Operator (ESO) —
ExternalSecretCRD pulls from Vault, AWS Secrets Manager, GCP Secret Manager, etc. Best when you already operate a secrets backend. - SOPS with
argocd-vault-pluginorhelm-secrets— encrypt with age/PGP/KMS, commit the ciphertext, decrypt at sync time.
Whichever you pick, the plaintext Secret YAML never goes into Git. Bootstrap the eight Plexicus Secrets out-of-band (as in step 5 of the Helm-CLI path above), or write SealedSecret / ExternalSecret manifests under secrets/ and let ArgoCD reconcile them in sync-wave -1 (before everything else).
For the rest of this walk-through, every Application manifest you create lives under apps/ and is committed and pushed before being applied.
Configure the OCI repository secret
The Plexicus chart itself lives in OCI, not in your GitOps repo, so ArgoCD also needs credentials for the GAR. Create a file named repo-gar.yaml with the following content, replacing <CONTENTS OF sa-key.json> with the literal text of your service account JSON key:
apiVersion: v1
kind: Secret
metadata:
name: plexicus-gar
namespace: argocd
labels:
argocd.argoproj.io/secret-type: repository
type: Opaque
stringData:
type: helm
name: plexicus-gar
url: europe-west3-docker.pkg.dev/plexicus-registry/charts
enableOCI: "true"
username: _json_key
password: |
<CONTENTS OF sa-key.json>
Apply it to your cluster:
kubectl apply -f repo-gar.yaml
Do not commit repo-gar.yaml with real credentials to version control.
Create prerequisite Applications (sync-wave 0)
Plexicus depends on five infrastructure services (MongoDB, Redis, MinIO, PostgreSQL, Temporal). They are not bundled in the umbrella chart — bundling them exceeded the 1 MB Kubernetes Secret limit Helm uses for release storage. Each is installed as its own ArgoCD Application synced before the umbrella.
Create one Application per prereq, each annotated with argocd.argoproj.io/sync-wave: "0". The umbrella Application below carries sync-wave: "5" so ArgoCD waits for the prereqs to reach Healthy before it syncs.
A reference manifest set is available at argocd/prereqs/applications-prereqs.yaml inside the chart artifact (extract via helm pull --untar from ~/plexicus-deploy). Copy it into your GitOps repo, commit, push, then apply:
cd ~/plexicus-deploy
helm pull oci://europe-west3-docker.pkg.dev/plexicus-registry/charts/plexicus \
--version $CHART_VERSION --untar
# Copy the reference manifests into the GitOps repo (under apps/prereqs/)
cp plexicus/argocd/prereqs/applications-prereqs.yaml \
plexicus-gitops/apps/prereqs/applications-prereqs.yaml
cd plexicus-gitops
# Edit apps/prereqs/applications-prereqs.yaml: replace every <TO-FILL>
# password with a SealedSecret/ExternalSecret reference (see step 1 secrets handling).
git add apps/prereqs/applications-prereqs.yaml
git commit -m "feat(argocd): add prereq Applications (mongo/redis/minio/postgres/temporal)"
git push
# Apply the manifest — ArgoCD reads it from the cluster and starts syncing
# from your GitOps repo's main branch.
kubectl apply -f apps/prereqs/applications-prereqs.yaml
The reference manifest uses bitnamilegacy/* free legacy images. Replace <TO-FILL> with real passwords (or wire to ESO/Sealed-Secrets) before applying.
Customers who already operate their own MongoDB / Redis / Temporal / MinIO / PostgreSQL can delete the corresponding Application from the manifest and instead point the umbrella Application at their existing endpoints via global.required.* and global.dependencies.* overrides.
Create the umbrella ArgoCD Application
Save the following manifest as apps/plexicus-app.yaml inside your GitOps repo, adjusting the domain, version, and values to match your environment. Reference the AppProject you defined in step 1 (spec.project: plexicus) so the source-repo allow-list applies.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: plexicus
namespace: argocd
annotations:
# Defer until the five prerequisite Applications (sync-wave 0/1) are Healthy
argocd.argoproj.io/sync-wave: "5"
spec:
project: plexicus
source:
repoURL: europe-west3-docker.pkg.dev/plexicus-registry/charts
chart: plexicus
targetRevision: "1.2.6"
helm:
values: |
global:
domain: plexicus.yourdomain.com
scheme: https
wsScheme: wss
ingressClassName: "traefik"
certManager:
enabled: true
clusterIssuer: "letsencrypt-prod"
imagePullSecrets:
- name: gar-secret
# ArgoCD names the per-prereq Helm release after the Application
# metadata.name (`plexicus-mongodb`, `plexicus-redis`, etc.), so
# the in-cluster Services are *prefixed*. The Helm-CLI install in
# step 6 produces bare names; this overlay rewrites the chart
# defaults to match the ArgoCD-prefixed names.
required:
database:
host: plexicus-mongodb
redis:
host: plexicus-redis-master
minio:
service: plexicus-minio:9000
dependencies:
redis:
host: plexicus-redis-master
temporal:
host: plexicus-temporal-frontend
fastapi:
existingSecret: plexicus-fastapi
worker:
existingSecret: plexicus-worker
frontend:
existingSecret: plexicus-frontend
analysis-scheduler:
existingSecret: plexicus-analysis-scheduler
codex-remedium:
existingSecret: plexicus-codex-remedium
exporter:
existingSecret: plexicus-exporter
plexalyzer-code:
existingSecret: plexicus-plexalyzer-code
plexalyzer-prov:
existingSecret: plexicus-plexalyzer-prov
destination:
server: https://kubernetes.default.svc
namespace: plexicus
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true
ArgoCD ≤ 2.12 does not support semver ranges for OCI sources. Always pin targetRevision to an exact version string (e.g. "1.1.0"). Contact engineering@plexicus.ai for the current version.
Commit the umbrella Application (and the AppProject from step 1 if you haven't yet) to the GitOps repo, then apply it to the cluster:
cd ~/plexicus-deploy/plexicus-gitops
git add projects/plexicus-appproject.yaml apps/plexicus-app.yaml
git commit -m "feat(argocd): add plexicus AppProject + umbrella Application"
git push
# Bootstrap: tell ArgoCD about the AppProject and the umbrella Application.
# From here on, every change you push to apps/ or values/ is reconciled automatically.
kubectl apply -f projects/plexicus-appproject.yaml
kubectl apply -f apps/plexicus-app.yaml
For a fully self-contained GitOps loop, define a single "root" Application that points at apps/ in your GitOps repo and uses the App-of-Apps pattern to install all the prereq + umbrella Applications. Then the only kubectl apply you ever run is the root manifest — every subsequent change goes through git push.
Verify the sync
Open the ArgoCD UI or run:
argocd app get plexicus
The application should reach Healthy and Synced status within a few minutes.
Next Steps
Once the platform is running, open https://plexicus.yourdomain.com in your browser to complete the initial account setup.
From there you can:
- Connect your source code repositories from the Connectors section
- Review advanced configuration options (resource limits, replica counts, storage classes) in the full
values.yamlreference - Set up two-factor authentication for your account
For questions, access requests, or support, contact engineering@plexicus.ai.