Installing CodeScoring.Save in Kubernetes
CodeScoring.Save is installed using the save Helm chart. The same chart supports two deployment scenarios:
- a standard Kubernetes installation with PostgreSQL, Redis, and S3-compatible object storage;
- a hosted installation in a single-node k3s cluster with SQLite and filesystem storage.
Before installation, review the system requirements.
Installing with the Helm chart
The vendor provides the Helm repository and container registry URLs and access credentials. The commands below use these placeholders:
HELM_REPOSITORY_URL— Helm repository URL;REGISTRY_URL— container registry URL;USERNAMEandPASSWORD— access credentials;CHART_VERSION— Helm chart and CodeScoring.Save version.
-
Create a namespace:
-
Create a Secret for accessing the private container registry:
The Secret name must match
image.pullSecretsandosa-proxy.imagePullSecretsinvalues.yaml. -
Install Helm and add the CodeScoring.Save repository:
-
Download and unpack the chart:
Configuring Helm chart values
Make the required changes before the first installation. Before upgrading an existing installation, back up PostgreSQL and the object storage.
The complete installation configuration is stored in values.yaml. The examples below include only the fragments to change; preserve the remaining settings from the distributed file.
Container images
The main components use a shared registry, tag, and image pull Secret:
OSA Proxy is distributed as a chart dependency and has separate image settings:
Use the image versions specified in the distributed values.yaml; they are tested for compatibility with the selected chart version.
Application secrets
Sensitive backend, worker, scheduler, and auth settings are stored in secrets.save-secrets.data:
SECRETS_ENCRYPTION_KEY encrypts stored credentials. Generate it once, for example with openssl rand -base64 32, store it securely, and do not change it during upgrades. Previously stored data cannot be decrypted after the key is changed.
Do not keep production passwords and keys in version control. For a production installation, use a protected values file or External Secrets.
PostgreSQL and Redis from the Helm chart
By default, the chart creates PostgreSQL and Redis as StatefulSets. Enable their resources and configure the PersistentVolumeClaims:
Replace storageClassName and the volume sizes according to the cluster configuration and expected data volume.
The built-in PostgreSQL credentials are configured separately and must match DATABASE_NAME, DATABASE_USER, and DATABASE_PASSWORD in secrets.save-secrets.data:
Application connection settings for PostgreSQL and Redis are stored in the save-backend-envs ConfigMap:
The ConfigMap and Secret are already attached to the components through deploymentsGeneral.envConfigmaps and deploymentsGeneral.envSecrets. Preserve these references when editing the complete values.yaml:
External PostgreSQL and Redis
For an external PostgreSQL server, disable the built-in StatefulSet and PVC and change the connection settings:
Create the database and user before installing CodeScoring.Save.
For an external Redis server, disable the built-in StatefulSet, Service, and PVC:
S3-compatible object storage
The current chart does not deploy an S3-storage. For a standard Kubernetes installation, create a bucket in an external S3-compatible storage service before installation and specify its connection settings:
For storage services that support virtual-hosted-style URLs, set S3_FORCE_PATH_STYLE: "false".
Hosted installation in k3s
The hosted option is intended for a single-server k3s installation and uses SQLite for metadata and the local filesystem for artifacts.
Install k3s and configure cluster access:
To switch the standard chart profile to hosted, change three variables in configMaps.save-backend-envs.data:
The save-backend-envs ConfigMap is attached to backend, worker, scheduler, and auth, so no additional ConfigMap is required. Preserve the other settings from the distributed values.yaml.
The worker and scheduler components require PostgreSQL and do not support SQLite. Both deployments must be disabled in a hosted installation:
Persistent data storage
A hosted installation requires three separate persistent volumes:
db-data— the backend SQLite database;auth-data— the auth SQLite database;storage— filesystem artifact storage.
Attach the PVCs to the deployments through volumes and volumeMounts. For auth, also set an empty initContainers value to remove the inherited wait-for-postgres init container:
Backend and auth use the same DATABASE_SQLITE_PATH value but separate PVCs, so each service stores its own database in its /app/data directory. The default STORAGE_ROOT_PATH is ./storage, which corresponds to the /app/storage mount point when the working directory is /app.
For Dynamic Volume Provisioning, specify a StorageClass for each PVC. The corresponding PVs will be created automatically:
Choose the volume sizes and storageClassName according to the workload and cluster configuration.
You can also use pre-created PVs of any Kubernetes-supported type. In this case, create the PVs separately or describe them under pvs, and set an empty storageClassName and the corresponding volumeName in each PVC, for example:
In this example, for the codescoring-save Helm release, the chart creates the codescoring-save-db-data PV from pvs.db-data, and the PVC binds to it explicitly through volumeName. Replace the NFS server address and export path with values from your infrastructure.
Create and bind the auth-data and storage volumes in the same way. The volume source can be NFS, CSI, a local disk, or another storage system; its parameters depend on the cluster infrastructure.
Optional Redis
Redis is optional for a hosted installation. To run Save without Redis, disable it in the application configuration and disable the related StatefulSet, Service, and PVC:
If Redis is used, keep REDIS_ENABLED: "true", and leave its StatefulSet, Service, and PVC enabled.
SQLite supports a single replica. Do not increase deploymentsGeneral.replicas, and disable autoscaling for backend and worker:
The application no longer uses PostgreSQL after this switch. You can also disable its unused StatefulSet and PVC:
SQLite and filesystem storage are suitable only for a single-server installation. Keep the SQLite database and artifact directories on persistent k3s storage and back them up regularly. Do not use this profile for a multi-replica deployment.
Ingress
Ingress is disabled by default. Enable it and replace the domain name to expose the web interface and API:
If TLS is terminated by an external load balancer, configure tls and the Ingress annotations according to the cluster infrastructure.
HTTPRoute (Gateway API)
If the cluster uses Kubernetes Gateway API, configure a route to the frontend through the httpRoutes section. The referenced Gateway resource must exist before CodeScoring.Save is installed.
Set gatewayName, gatewayNamespace, gatewaySectionName, and hostnames to match the Gateway and DNS name in your cluster.
The backendRefs.name value must be formed as {helm-release-name}-frontend. For example, with helm install codescoring-save ..., specify name: codescoring-save-frontend.
OSA Proxy
OSA Proxy is disabled by default. To enable it set the osa-proxy.enabled field to true. In the existing osa-proxy.config.content block, replace codescoring.url with the CodeScoring installation URL. Pass the token through the osa-proxy Secret:
If component checks through OSA Proxy are not required, disable the dependency:
osa-proxy.config.content contains the complete service configuration. Preserve the remaining sections from the distributed values.yaml when modifying it.
Resource limits
The distributed values.yaml does not limit the main component containers. For a production installation, set requests and limits for every component based on load testing:
Configure deployments.scheduler, deployments.auth, deployments.save-frontend, statefulSets.save-postgresql, and statefulSets.save-redis in the same way. CPU requests must be defined for HPA to work correctly with scalable containers.
External Secrets
The chart can obtain secrets from an external store through External Secrets Operator. Install the operator and create a SecretStore or ClusterSecretStore in the cluster first.
Enable the required resource under vaults:
Then attach the generated Secret to the deployments:
For the built-in PostgreSQL, configure vaults.postgresql-secrets-external in the same way and attach the Secret under statefulSets.save-postgresql.envSecrets.
Installation
From the unpacked chart directory, run:
To update an existing installation, use the same configured values.yaml version:
Verifying the installation
Check the resource status:
All Pods must reach the Running state and their containers must be ready. Use component logs for diagnostics:
After installation, open the Ingress URL and sign in with the password specified in AUTH_ADMIN_PASSWORD.
Next steps
After a successful installation:
