PRIVATE AI LAB · PART 2
Creating the PostgreSQL database for Private AI Services
With DSM deployed, the next step is to provision the managed PostgreSQL database used by my Private AI Services configuration. This walkthrough follows the database I created in my lab, then prepares the DNS, CA trust, and Kubernetes references needed to connect PAIS.
My lab: DSM 9.1.1.0100.25777183 · PostgreSQL 18.6+vmware.v9.1.1.0100 · PAIS 3.0.0
Update: dedicated database for my Automation-managed PAIS instance
October 21, 2026: My active PAIS instance is now configured through VCF Automation. I provisioned a separate DSM instance named pais-automation-db, with logical database paisautomation, rather than pointing two independent PAIS instances at the original application’s database. My new database uses PostgreSQL 18.6+vmware.v9.1.1.0100, Single Server, best-effort-large, and 60 GiB initial storage. DSM still manages its lifecycle and backups.
For this deployment I supplied the new database host, port 5432, logical database name, initialization administrator credential, and DSM public CA chain through the Automation PAIS configuration workflow. Setup initialized pgvector and created the restricted instance-specific runtime database user; the resulting PAIS configuration uses full TLS verification. The initialization administrator and runtime application user serve different purposes.
The manual Secret and PAISConfiguration examples in sections 9–10 below describe my original Supervisor deployment. They are not additional steps to apply over the Automation-generated configuration. The optional psql checks remain useful for administrators, but installing a Windows database client was not required to complete this Automation setup. I verified the new PAIS service and inference path; a complete database restore test remains a separate recovery check.
Start with Deploying VMware Data Services Manager for VCF PAIS and the S3 storage appliance build. This article assumes those foundations are available. The version and sizing below describe my lab, rather than a universal compatibility or production sizing recommendation.
Examples use lab.example.com and a documentation-only IP address. Replace them with your actual environment values. Passwords and access keys are deliberately excluded.
1. Confirm the prerequisites
- The PostgreSQL data service bundle is Ready and the intended database version is enabled.
- The DSM namespace has a valid Postgres Data Service Policy allowing that version, infrastructure placement, and backup storage.
- The workload infrastructure policy has sufficient compute, storage, IP capacity, and the required VM class.
- The Ubuntu S3 backup appliance is reachable from the database infrastructure, with trusted HTTPS and a dedicated database backup bucket.
- The Supervisor has the exact KubernetesRelease required by the selected DSM bundle.
In my lab, a missing v1.35.5---vmware.1-vkr.1 release prevented provisioning even though newer releases were present. I staged the required release in my offline depot and synchronized the Kubernetes Service Content Library. Use the exact release named by your bundle and deployment error:
kubectl get kubernetesreleases
kubectl get kubernetesreleases v1.35.5---vmware.1-vkr.1Confirm Ready and Compatible are both True before retrying a deployment blocked by that prerequisite.
2. Start the Postgres creation wizard
Sign in to the DSM database management interface, open the database inventory, and start creating a Postgres database. For the Basic Information page, use these values as a starting point:
| Field | Lab choice and purpose |
|---|---|
| Namespace | wkld1-dsm — the namespace associated with the Postgres policy configured in my lab |
| Version | 18.6+vmware.v9.1.1.0100 — the version used in my lab |
| Instance Name | pais-db — DSM’s managed database instance name |
| Database Name | pais — the logical database PAIS connects to |
| Admin Username | vcfadmin — the database administrator used in my lab configuration |
| Admin Password | Set a unique password or securely retrieve DSM’s generated password |
| Directory Service Authentication | Disabled for this password-based application connection |
| DNS Names | pais-db.lab.example.com — also included in the database certificate |
| Certificate Management | DSM-Managed |
The instance name and logical database name serve different purposes. Use pais as PAIS’s database name. Entering a DNS name in this wizard does not create a DNS record; add the record after DSM assigns the address.
I used the provisioned administrator for PAIS. Do not substitute a restricted account without checking PAIS’s schema initialization and migration privileges for your installed release.
3. Select availability and infrastructure
- Choose the availability topology. I used Standalone / Single Server. Select a supported resilient topology if your recovery and availability requirements demand it.
- Select the infrastructure policy associated with the workload namespace. The infrastructure policy in my lab was
wkld1-dsm. - Select the assigned storage policy. I used the workload cluster’s datastore policy; use the actual policy available in your environment.
- Select the VM class. The database in my lab used
best-effort-large. - Set the database disk size. The initial allocation in my lab was 60 GiB.
- Review the network/IP pool and remaining namespace capacity before continuing.
These are initial lab allocations. Size storage for database growth, indexes, recovery needs, and operational headroom. A standalone database remains a single database server even when its VM benefits from vSphere HA.
4. Select the S3 database backup location
Use the Database Backup Storage location configured against the Ubuntu S3 appliance. DSM appliance system backups and system logs are separate settings; neither replaces database backup configuration.
- Select the database backup location permitted by the Data Service Policy.
- If no location appears, create or expose Database Backup Storage in DSM and verify policy access before returning to the wizard.
- For my lab’s path-style S3 configuration, use the HTTPS endpoint, dedicated database bucket and credentials, configured region, and Force Path Style.
- Choose the backup schedule and retention appropriate to your recovery requirements and available capacity. Record the choices rather than accepting an unexplained default.
- Confirm any point-in-time recovery options against the selected topology and DSM release, then plan a restore test.
For example, https://s3.lab.example.com and a bucket such as dsm-postgres represent the database repository. Use your appliance’s actual values. Avoid an independent bucket expiration rule that could remove recovery dependencies before DSM retention allows it.
5. Review optional database settings
- Maintenance window: choose a period when maintenance is acceptable for the application.
- Locale and encoding: the resulting database in my lab used UTF8 encoding. Leave optional locale settings at the supported default unless the application requires something specific.
- vSphere tags: optional; use them if they support your inventory or operations process.
- Database options: keep defaults unless a documented PAIS requirement calls for a change.
- HBA configuration: leave custom entries empty initially if the supported default permits the intended connection. If restrictions are required, use DSM’s supported configuration and the actual PAIS client source network.
Do not add a broad trust rule or allow every source network to make a connection test pass. Network access rules, database authentication, and TLS trust solve different parts of the connection.
6. Create the database and wait for Ready
- Review the instance name, logical database name, version, placement, capacity, and backup selections.
- Submit the creation request.
- Monitor DSM tasks and instance status until the database shows Ready.
- Record the assigned IP address, port, logical database name, username, and DNS name from Basic Information.
- Store the password securely and retrieve the CA certificate using View CA.
The completed instance in my lab showed Ready, port 5432, database pais, DSM-managed certificates, and database connections Allowed. If creation fails, inspect the detailed alert before recreating the instance; release availability, policy permissions, networking, and storage capacity are useful first checks.
7. Create DNS and test reachability
Create an A record for the exact DNS name entered in the wizard, pointing to the address DSM assigned. The address below is a documentation example and must be replaced.
# Example DNS record: pais-db.lab.example.com -> 192.0.2.96
Resolve-DnsName pais-db.lab.example.com
Test-NetConnection pais-db.lab.example.com -Port 5432The workstation test in my lab succeeded across subnets. Also verify reachability from the PAIS runtime network: a workstation success does not prove the PAIS worker can connect. Restrict TCP 5432 to the required clients and administrative sources.
8. Validate the CA and a real database connection
Download the CA chain from DSM and save it locally, for example C:\Lab\PrivateAI\VMware-DB-CA-chain.pem. It is a file to read or pass to a client, not a command to execute.
certutil -dump 'C:\Lab\PrivateAI\VMware-DB-CA-chain.pem'Review the issuer, validity, and CA constraints. Inspecting a CA file alone does not prove that the live database presents the expected certificate. If a PostgreSQL client is installed, test a real connection using full certificate and hostname verification:
psql "host=pais-db.lab.example.com port=5432 dbname=pais user=vcfadmin sslmode=verify-full sslrootcert=C:/Lab/PrivateAI/VMware-DB-CA-chain.pem" -W
SELECT current_database(), current_user;
SELECT ssl, version FROM pg_stat_ssl WHERE pid = pg_backend_pid();
SELECT extname, extversion FROM pg_extension ORDER BY extname;
\qThe extension query is an inventory check. Follow the installed PAIS release’s requirements before changing extensions or schemas; do not assume database creation alone enables every capability needed for indexing.
9. Prepare the PAIS namespace references
The PAIS instance in my lab runs in a separate Supervisor namespace, wkld1-private-ai. Database placement remains in wkld1-dsm; the CA and credential references belong in the PAIS configuration’s namespace.
First verify your Supervisor context, then create the CA ConfigMap:
kubectl config current-context
kubectl get namespace wkld1-private-ai
kubectl create configmap pais-db-ca -n wkld1-private-ai --from-file=ca.crt='C:\Lab\PrivateAI\VMware-DB-CA-chain.pem' --dry-run=client -o yaml | kubectl apply -f -For a new deployment, create the password Secret without putting a literal password in the command history. This prompts locally and sends the manifest directly to kubectl:
$dbCredential = Get-Credential -UserName 'vcfadmin' -Message 'Enter the pais database password'
try {
@{
apiVersion = 'v1'
kind = 'Secret'
metadata = @{name='pais-db-credentials'; namespace='wkld1-private-ai'}
type = 'Opaque'
stringData = @{password=$dbCredential.GetNetworkCredential().Password}
} | ConvertTo-Json -Depth 6 -Compress | kubectl create -f -
} finally {
$dbCredential = $null
}
kubectl get configmap pais-db-ca -n wkld1-private-ai
kubectl get secret pais-db-credentials -n wkld1-private-aiThis Secret creation command intentionally fails if the name already exists. Do not delete or replace a credential used by an existing PAIS instance as part of this setup walkthrough. Kubernetes Secrets still require appropriate RBAC and cluster protection; avoid printing or exporting their values.
10. Connect the database in the PAIS configuration
The following is a partial configuration excerpt based on the PAIS manifest deployed in my lab. Merge it into the complete configuration for your release; it is not a standalone deployment manifest.
spec:
clientTls:
caBundleRefs:
- name: pais-db-ca
# Preserve other CA references required by your PAIS deployment.
database:
host: pais-db.lab.example.com
port: 5432
username: vcfadmin
dbname: pais
sslMode: VerifyFull
passwordRef:
name: pais-db-credentials
fieldPath: passwordIn my lab, the CA was supplied through clientTls.caBundleRefs. Inspect the installed API before applying examples to another release:
kubectl explain paisconfiguration.spec.database --recursive
kubectl explain paisconfiguration.spec.clientTls --recursive
kubectl get paisconfiguration -n wkld1-private-aiThe PAIS Kubernetes API reference documents the database connection fields and TLS modes. Keep hostname verification enabled and connect using the name included in the database certificate.
Completion checks
- The DSM Postgres instance is Ready and the intended logical database exists.
- DNS resolves the database FQDN to its assigned address.
- The PAIS network can reach TCP 5432.
- A database client can authenticate and verify the server certificate and hostname.
- The CA and password references exist in the PAIS namespace.
- The PAIS configuration uses the correct host, username, database name, and Secret key.
- A database backup completes to the S3 appliance, and an isolated restore test is scheduled and verified before relying on the recovery design.
The database is now prepared for the PAIS deployment. Model downloads, Harbor projects, GPU endpoints, and agent configuration are separate steps in the Private AI build.
Evidence boundary: DSM Ready status, workstation DNS/TCP connectivity, CA inspection, Kubernetes references, and the PAIS configuration above reflect the configuration and validation completed in my lab. The psql commands and backup/restore checks are recommended validation procedures; this post does not claim those recovery tests were already completed.
