Install on OVHcloud
Viberglass on OVHcloud Managed Kubernetes Service (MKS), with OVHcloud's managed PostgreSQL and Object Storage. Each agent run is a Kubernetes Job. Install on Kubernetes explains each setting; this page says what to choose on OVHcloud.
Before you start
You need:
- An OVHcloud Public Cloud project, with permission to create Kubernetes clusters, databases and Object Storage in it.
- A domain whose DNS you control, for two hostnames: the app and artifact previews. The examples use
viberglass.example.comandpreview.viberglass.example.com. - On your machine: Git, kubectl, Helm 3, the AWS CLI v2 (for Object Storage) and OpenSSL.
- A release of Viberglass whose images are published, such as
v1.0.2. - A model key and a GitHub repository with a fine-grained token, as in first-run setup.
Use one region for everything. The examples use Gravelines: GRA9 for the cluster, gra for Object Storage.
VIBERGLASS_TAG=v1.0.2
OVH_S3_REGION=gra
OVH_S3_ENDPOINT=https://s3.$OVH_S3_REGION.io.cloud.ovh.net
VIBERGLASS_BUCKET=viberglass # the bucket you create in step 1
VIBERGLASS_INSTALL_DIR="$HOME/viberglass-ovh"
install -d -m 700 "$VIBERGLASS_INSTALL_DIR"
git clone https://github.com/Ilities/viberglass.git
cd viberglass
git checkout "$VIBERGLASS_TAG"
1. Create the bucket
- In the project, open Storage → Object Storage → Create a container. Name it
viberglass, choose the S3 API, Standard storage and your region. Bucket names are global across OVHcloud; ifviberglassis taken, choose another name and setVIBERGLASS_BUCKETto it. Every command below uses that variable. - Under User, choose Create a user, or pick an existing user with the Administrator or Object Storage Operator role. Then choose View credentials and copy the S3 access key and secret key.
- Finish the wizard. Keep the bucket private.
Keep the keys in an AWS CLI profile of their own, so the commands below don't touch any AWS account:
aws configure --profile ovh
# The access key and secret key from step 2, region: gra, output: json
Browsers download task media from the bucket through signed links. Allow the app's origin to read:
cat > "$VIBERGLASS_INSTALL_DIR/cors.json" <<'EOF'
{"CORSRules": [{"AllowedOrigins": ["https://viberglass.example.com"], "AllowedMethods": ["GET", "HEAD"], "AllowedHeaders": ["*"], "MaxAgeSeconds": 3600}]}
EOF
aws --profile ovh --endpoint-url "$OVH_S3_ENDPOINT" s3api put-bucket-cors \
--bucket "$VIBERGLASS_BUCKET" --cors-configuration "file://$VIBERGLASS_INSTALL_DIR/cors.json"
Check that the keys can write and delete:
echo ok > /tmp/viberglass-probe
aws --profile ovh --endpoint-url "$OVH_S3_ENDPOINT" s3 cp /tmp/viberglass-probe "s3://$VIBERGLASS_BUCKET/probe"
aws --profile ovh --endpoint-url "$OVH_S3_ENDPOINT" s3 rm "s3://$VIBERGLASS_BUCKET/probe"
2. Create the cluster
In the project, open Managed Kubernetes Service → Create a cluster:
- Region
GRA9, plan Free. - The latest Kubernetes version offered.
- No private network. The nodes reach the database over its public address, allowed by IP in the next step.
- A node pool of 2 nodes, flavor
b3-16(4 vCPU, 16 GB), autoscaling off: the database only accepts the nodes it lists, so new nodes would be refused until added.
Each agent run asks for 1 CPU and 4 GiB, and the backend and frontend need little next to that, so two such nodes fit the app and five or six concurrent runs.
A new project's vCPU quota may be too small for that, and creating the cluster fails with InsufficientVCPUsQuota. Either use 2 × b3-8 (2 vCPU, 8 GB), which fits the app and two concurrent runs, or raise the quota for the region under Project Management → Quota and Regions.
When the cluster is ready, download its kubeconfig from the cluster's page:
mv ~/Downloads/kubeconfig.yml "$VIBERGLASS_INSTALL_DIR/kubeconfig"
chmod 600 "$VIBERGLASS_INSTALL_DIR/kubeconfig"
export KUBECONFIG="$VIBERGLASS_INSTALL_DIR/kubeconfig"
kubectl get nodes -o wide
Note each node's EXTERNAL-IP.
3. Create the database
In the project, open Databases → Create a database service:
- PostgreSQL, the newest version offered, plan Essential, one node, region
GRA, public network.
When it's running, on its page:
- Authorized IPs: add each node's address from step 2, and your own for checking the connection.
- Databases: add
viberglass. - Users: add
viberglass, and copy its password. - General information: note the host and port. The port isn't PostgreSQL's usual 5432.
The viberglass database belongs to OVHcloud's admin user, avnadmin, and since PostgreSQL 15 other users can't create tables in its public schema. Let the viberglass user create them, connecting as avnadmin (its password is on the database's page):
psql "postgresql://avnadmin@HOST:PORT/viberglass?sslmode=require" \
-c 'GRANT USAGE, CREATE ON SCHEMA public TO viberglass;'
Without this, the install in step 7 fails with permission denied for schema public.
4. Ingress and certificates
MKS comes without an ingress controller. Install Traefik; its Service gets an OVHcloud Load Balancer with a public address:
helm repo add traefik https://traefik.github.io/charts
helm repo update
helm upgrade --install traefik traefik/traefik --namespace traefik --create-namespace --wait
kubectl -n traefik get service traefik --watch
Wait for EXTERNAL-IP, then stop the watch with Ctrl-C. Point both hostnames at that address with A records, at the DNS provider your domain's nameservers belong to (dig +short NS example.com shows them, for your own domain). Records in an OVHcloud DNS zone only count if the domain's nameservers are OVHcloud's. Wait until they resolve:
dig +short viberglass.example.com preview.viberglass.example.com
Install cert-manager and a Let's Encrypt issuer. Replace REPLACE_WITH_YOUR_EMAIL with a real address: Let's Encrypt refuses addresses at example.com, and the certificate is then never issued.
helm upgrade --install cert-manager oci://quay.io/jetstack/charts/cert-manager \
--namespace cert-manager --create-namespace --set crds.enabled=true --wait
kubectl apply -f - <<'EOF'
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: REPLACE_WITH_YOUR_EMAIL
privateKeySecretRef:
name: letsencrypt-account
solvers:
- http01:
ingress:
ingressClassName: traefik
EOF
cert-manager creates the certificate for both hostnames when Viberglass is installed in step 7.
5. Namespaces and Secrets
kubectl create namespace viberglass
kubectl create namespace viberglass-workers
kubectl label namespace viberglass-workers app.kubernetes.io/managed-by=Helm
kubectl annotate namespace viberglass-workers meta.helm.sh/release-name=viberglass meta.helm.sh/release-namespace=viberglass
Viberglass reads its passwords and keys from two Kubernetes Secrets. Write each as a small file first.
Generate two encryption keys. Viberglass uses them to encrypt the model keys and tokens you add later:
openssl rand -hex 32
openssl rand -hex 32
Create $VIBERGLASS_INSTALL_DIR/app.env with the database user's password from step 3 and those two keys:
DB_PASSWORD=the-viberglass-database-users-password
SECRETS_ENCRYPTION_KEY=the-first-generated-key
WEBHOOK_SECRET_ENCRYPTION_KEY=the-second-generated-key
Create $VIBERGLASS_INSTALL_DIR/storage.env with the bucket user's keys from step 1:
S3_ACCESS_KEY_ID=the-access-key
S3_SECRET_ACCESS_KEY=the-secret-key
Turn them into the Secrets:
chmod 600 "$VIBERGLASS_INSTALL_DIR"/*.env
kubectl -n viberglass create secret generic viberglass-app --from-env-file="$VIBERGLASS_INSTALL_DIR/app.env"
kubectl -n viberglass create secret generic viberglass-storage --from-env-file="$VIBERGLASS_INSTALL_DIR/storage.env"
Keep app.env somewhere safe. Without its two encryption keys, the credentials stored in Viberglass can't be read after a restore.
6. Values
Replace the database host and port from step 3, and the hostnames:
cat > "$VIBERGLASS_INSTALL_DIR/values.yaml" <<EOF
backend:
image: ghcr.io/ilities/viberglass-backend:$VIBERGLASS_TAG
replicas: 1
frontend:
image: ghcr.io/ilities/viberglass-frontend:$VIBERGLASS_TAG
publicUrl: https://viberglass.example.com
workers:
namespace: viberglass-workers
registry: ghcr.io/ilities
imageTag: $VIBERGLASS_TAG
database:
enabled: false
host: REPLACE_WITH_DATABASE_HOST
port: REPLACE_WITH_DATABASE_PORT
name: viberglass
user: viberglass
ssl: true
storage:
enabled: false
endpoint: $OVH_S3_ENDPOINT
publicEndpoint: $OVH_S3_ENDPOINT
region: $OVH_S3_REGION
bucket: $VIBERGLASS_BUCKET
forcePathStyle: true
preview:
publicUrl: https://preview.viberglass.example.com
ingress:
enabled: true
className: traefik
host: viberglass.example.com
annotations:
cert-manager.io/cluster-issuer: letsencrypt
tls:
- hosts: [viberglass.example.com, preview.viberglass.example.com]
secretName: viberglass-tls
networkPolicy:
enabled: true
workerExtraEgress: []
EOF
7. Install
helm lint infra/kubernetes/chart -f "$VIBERGLASS_INSTALL_DIR/values.yaml"
helm upgrade --install viberglass infra/kubernetes/chart --namespace viberglass \
-f "$VIBERGLASS_INSTALL_DIR/values.yaml" --wait --wait-for-jobs --timeout 10m
kubectl -n viberglass get pods,jobs,ingress,certificate
The certificate shows READY True within a couple of minutes. Then:
curl --fail --show-error https://viberglass.example.com/api/auth/setup-status
curl --show-error --output /dev/null --write-out '%{http_code}\n' https://preview.viberglass.example.com/
Expect {"requiresInitialUser":true}, then 404 from the preview host. If the migration Job fails, read its log with kubectl -n viberglass logs job/viberglass-migrate-1 -c migrate; a timeout there is usually the database's authorized IPs. A failed Job doesn't run again: after fixing the cause, run the helm upgrade --install command again, which starts a new one.
8. Use it
Open https://viberglass.example.com, create the administrator and go through setup. Run the starter task and watch its Job:
kubectl -n viberglass-workers get jobs,pods --watch
Then check:
- An image uploaded to a task opens in the browser, loaded from Object Storage.
- A second request in the same task continues where the first left off.
- Cancelling a running task removes its Job from
viberglass-workers. - A Files space's HTML page opens from the preview host.
Costs
Billed by the hour while they exist: the two nodes (the Free plan's control plane costs nothing), the Load Balancer, the PostgreSQL service, and the bucket by stored GB and outgoing traffic. Check current prices for your region in the console.
Teardown
helm uninstall viberglass --namespace viberglass
helm uninstall traefik --namespace traefik # removes the Load Balancer
helm uninstall cert-manager --namespace cert-manager
aws --profile ovh --endpoint-url "$OVH_S3_ENDPOINT" s3 rb "s3://$VIBERGLASS_BUCKET" --force
Then in the console, delete the cluster, the PostgreSQL service and the bucket's user, and check under Network → Load Balancer that none remains. Remove the two DNS records.