> ## Content Index
> Fetch the complete content index at: https://davidstart.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# Connecting Autonomous AI Database Serverless to Oracle Private AI Services Container
- URL: https://davidstart.com/connecting-autonomous-ai-database-serverless-to-oracle-private-ai-services-container/
- Published: 2026-06-25T12:00:00.000Z
- Updated: 2026-10-04T22:16:14.000Z
- Author: David Start
- Tags: Data4U, ai, oracle, database, autonomous-database, private-ai, vector-search, oci

AI Vector Search is useful because it lets applications find related information by meaning, not just by exact words. Most retrieval augmented generation patterns need some version of that flow: turn text, images, or documents into embeddings, store those vectors with the business data, and retrieve the most relevant context before an application calls a model. The practical question is where those embeddings and model calls happen, because many customers are not embedding harmless sample text. They may be embedding support notes, contracts, case summaries, engineering documents, or other data that should not be sent to a public hosted AI endpoint just to make semantic search work.

That is where Oracle Private AI Services Container has value. You can run the model service in the customer environment, expose an OpenAI-compatible endpoint near the database, and let Oracle AI Database call that endpoint when it needs embeddings or generated text. The expensive AI work is offloaded from the database server, but the workload still runs close to the data. That matters for privacy, but it also matters for performance because embedding generation can be moved to a runtime designed for that work, using ONNX Runtime with multi-threading on multi-core CPUs.

The same offload idea also applies to vector indexing. The Private AI Services Container Vector Index Service can create In-Memory Neighbor Graph vector indexes faster by using GPU offload on a remote Linux machine with a GPU. In that model, `CREATE VECTOR INDEX` can define the REST endpoint and credential for the Private AI Services Container, and most modern NVIDIA GPUs are supported for vector index offload. This post focuses on the embedding endpoint, but the same architecture explains why placing the container next to Autonomous AI Database Serverless matters: the database keeps doing database work, while the AI compute runs on infrastructure sized for the AI task.

The model packaging matters too. The container ships with embedding models, and customers can add other embedding models when they need different accuracy, language, image, or deployment characteristics. That is especially important in air-gapped environments because the customer can prepare the models they need and run the service without depending on a live connection to a public AI provider.

This gets more interesting with Autonomous AI Database Serverless. The database is managed, the container is running on customer-controlled compute, and the REST call from the database to the container should stay private. The goal is not just to start a container. The goal is to show how Autonomous AI Database Serverless can use a private AI endpoint that sits next to the database environment instead of sending embedding requests somewhere else. This post builds on Doug Hood's getting started walkthrough for Oracle Private AI Services Container and Markus Kissling's PL/SQL HTTP example, but focuses on the Autonomous AI Database Serverless networking details that were not obvious until we tested the full path.

## What We Are Building

The architecture has two separate access paths. Administrators and developers can still use Database Actions when public access is enabled and restricted to approved client networks, while the database-to-container call takes the private VCN path. The operational access path and the AI service path are different by design: a developer can use Database Actions through an allowed public endpoint if that fits the environment, while the database calls the AI service by private DNS name inside the VCN.

```text
Developer or administrator browser
  -> Autonomous AI Database Serverless SQL Worksheet

Autonomous AI Database Serverless private endpoint
  -> private VCN route
  -> VM private DNS name
  -> Oracle Private AI Services Container on port 8080

Administrator SSH
  -> VM public IP

```

Before using vectors, first prove the database can make a basic REST call to the private AI endpoint:

```sql
SELECT UTL_HTTP.REQUEST(
  'http://<private-ai-vm-private-dns-name>:8080/v1/models'
)
FROM dual;

```

Once that works, the same private path can be used by `DBMS_VECTOR` to generate an embedding:

```sql
SELECT DBMS_VECTOR.UTL_TO_EMBEDDING(
  'hello',
  JSON('{
    "provider": "privateai",
    "url": "http://<private-ai-vm-private-dns-name>:8080/v1/embeddings",
    "host": "local",
    "model": "all-minilm-l12-v2"
  }')
) AS embedding
FROM dual;

```

## Network Layout

The network is doing two jobs at the same time. It needs an operational path for people or automation to manage the database and compute instance, and it needs a private service-to-service path from Autonomous AI Database Serverless to the AI endpoint. That is why this architecture separates public administration from private AI traffic. For a straightforward deployment pattern, this layout keeps the moving parts small:

```text
VCN CIDR: 10.20.0.0/16

Public subnet: 10.20.10.0/24
  - Compute VM running Oracle Private AI Services Container
  - Public IP enabled for SSH
  - Private DNS enabled

Private subnet: 10.20.20.0/24
  - Autonomous AI Database Serverless private endpoint
  - Public access enabled for SQL Worksheet

```

The VM is in a public subnet in this topology so an administrator can SSH into it directly while building the service. In a stricter customer environment, the same container could run on a private subnet and be managed through Bastion, an internal jump host, or another approved operations path. Either way, Autonomous AI Database Serverless should call the VM private DNS name, not the VM public IP. Your name will be different, but the DNS pattern matters because this is what Autonomous AI Database Serverless resolves through the VCN:

```text
Example: ai-temp-vm.aitemppublic.aitemp.oraclevcn.com
Pattern: <vm-hostname>.<subnet-dns-label>.<vcn-dns-label>.oraclevcn.com

```

## Security Lists

This setup works with Security Lists. Network Security Groups are not required, but they are often cleaner for customer deployments because you can attach one NSG to the Autonomous AI Database Serverless private endpoint, another NSG to the VM VNIC, and allow traffic from one NSG to the other. Security Lists keep the subnet-level controls explicit, which is useful when you are documenting the path.

The purpose of the security rules is to allow only the paths this configuration needs. SSH comes from an administrator network to the VM public IP in this topology, while the AI call comes from the Autonomous AI Database Serverless private endpoint to the VM private IP on port 8080\. Those are different paths, so they need to be allowed in the right places. The critical detail is easy to miss: creating a Security List under the VCN is not enough. The Security List must be attached to the subnet whose traffic it is meant to control. If the rule exists but is not attached to the subnet, the database call can still time out.

For the public subnet, where the VM runs, the rules need to allow administrator SSH and Autonomous AI Database Serverless private endpoint traffic to the container port:

```text
Ingress:
  0.0.0.0/0     TCP 22    SSH to VM
  10.20.0.0/16  TCP 8080  Autonomous AI Database Serverless private endpoint to Private AI HTTP

Egress:
  0.0.0.0/0     All       General outbound access

```

For the private subnet, where the Autonomous AI Database Serverless private endpoint lives, the database needs egress to the VM subnet on the container port:

```text
Egress:
  10.20.10.0/24 TCP 8080  Autonomous AI Database Serverless private endpoint to VM HTTP

```

If your policy allows broader egress during setup, you can temporarily simplify private subnet egress:

```text
Egress:
  0.0.0.0/0     All

```

The traffic path you are enabling is Autonomous AI Database Serverless private endpoint to VM private IP on TCP 8080:

```text
Autonomous AI Database Serverless private endpoint in 10.20.20.0/24
  -> TCP 8080
VM private IP in 10.20.10.0/24

```

Same-VCN traffic does not need a route table rule between the subnets because the route is implicit. The security list rules still have to allow it.

## Create the Compute VM

Create an Oracle Linux VM in the public subnet. The VM is where the Private AI Services Container runs, so it becomes the private model endpoint that Autonomous AI Database Serverless will call. Putting the VM in the public subnet keeps the administration path easy to inspect because you can SSH directly to the public IP, but it does not change the database path. Autonomous AI Database Serverless should still call the VM by private DNS name so the request stays inside the VCN.

Use a shape with enough memory for the container and models. For a small deployment, 2 OCPUs and 24 GB RAM is a reasonable starting point. In our test, the VM had 46 GB RAM.

Enable the public IP for administration and the private DNS record for the database-to-container path:

```text
Public IPv4 address: Yes
Private DNS record: Yes
Hostname: ai-temp-vm

```

Then SSH into the VM:

```bash
ssh -i ~/.ssh/id_rsa opc@<vm-public-ip>

```

If the boot volume was resized in OCI but the OS still sees a small root filesystem, grow the root volume. This is worth checking before pulling images because container images, extracted setup files, logs, and model files can consume more space than the default root filesystem exposes inside the operating system.

```bash
sudo growpart /dev/sda 3
sudo pvresize /dev/sda3
sudo lvextend -r -l +100%FREE /dev/ocivolume/root
df -h /

```

Install Podman and unzip before pulling and unpacking the container:

```bash
sudo dnf install -y podman unzip
podman --version

```

## Pull and Start Oracle Private AI Services Container

Doug Hood's getting started post covers the container setup in more depth, including both HTTP and HTTP/SSL modes. The commands below are the short version of the HTTP path we used for Autonomous AI Database Serverless calling the container over a private network path. Starting with HTTP keeps the first milestone focused on the database route, ACLs, subnet rules, VM firewall, and container health. HTTPS is the right production direction, but it adds certificate and wallet handling before you know whether the basic private path works.

The container image is distributed through Oracle Container Registry, so the VM needs to authenticate before it can pull the image. The Oracle account also needs to accept the image license terms in the registry before the pull will work.

```bash
podman login container-registry.oracle.com

```

After login, pull the Private AI image:

```bash
podman pull container-registry.oracle.com/database/private-ai:25.1.2.0.0

```

The setup scripts are packaged inside the container image, so creating a temporary container and copying the zip out gives you the supported setup scripts without keeping that temporary container around:

```bash
podman create --name privateai-setup-extract \
  container-registry.oracle.com/database/private-ai:25.1.2.0.0

podman cp \
  privateai-setup-extract:/privateai/scripts/privateai-setup-25.1.2.0.0.zip \
  /home/opc/

podman rm privateai-setup-extract

cd /home/opc
unzip -o privateai-setup-25.1.2.0.0.zip

```

Start the container in HTTP mode:

```bash
mkdir -p /home/opc/privateai
cd /home/opc/setup

./configSetup.sh -d /home/opc/privateai
sudo loginctl enable-linger opc
./containerSetup.sh -d /home/opc/privateai -v 25.1.2.0.0 --http
podman update --restart=always privateai

```

The setup scripts create the container configuration and start the Private AI service. Enabling lingering lets the user-level container keep running after the SSH session ends, and the restart policy helps the container come back after a reboot. After the container is running, open the VM firewall because the OCI Security List only gets traffic to the VM. The operating system firewall still has to allow the port, and if it blocks 8080, Autonomous AI Database Serverless will still fail to connect.

```bash
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --reload

```

Verify the container locally first. This proves that the container is running and serving requests on the VM, but it does not prove that Autonomous AI Database Serverless can reach it yet.

```bash
podman ps
curl -i http://localhost:8080/health
curl http://localhost:8080/v1/models

```

Then verify using the VM private DNS name. That test is a better preview of what Autonomous AI Database Serverless will use. If it fails from the VM, fix the hostname, listener, or local firewall before moving on to database ACLs.

```bash
curl -i http://ai-temp-vm.aitemppublic.aitemp.oraclevcn.com:8080/health

```

The health check should return HTTP 200:

```text
HTTP/1.1 200 OK
content-length: 0

```

The model list should include embedding models such as:

```text
all-minilm-l12-v2
all-mpnet-base-v2
multilingual-e5-base
multilingual-e5-large
clip-vit-base-patch32-txt
clip-vit-base-patch32-img

```

## Create Autonomous AI Database Serverless

Autonomous AI Database Serverless is the caller in this setup. It needs a private endpoint so outbound requests can originate from the VCN. Public access is optional, but useful when developers or DBAs need to open Database Actions from an approved client network. Those two access paths can exist at the same time, so create Autonomous AI Database Serverless with Oracle Database 26ai and private endpoint networking:

```text
Database version: 26ai
Network access: Private endpoint access only
Virtual cloud network: the VCN created for this deployment
Subnet: private subnet
Hostname prefix: a short, stable prefix such as aiadb
Network security groups: select the Autonomous AI Database Serverless private endpoint NSG if you are using NSGs
Allow public access: Enabled only if approved users need Database Actions from outside the VCN
mTLS: Set based on your client access requirements

```

![Autonomous AI Database Serverless network access selection with private endpoint access enabled](https://davidstart.com/content/images/2026/10/adb-network-access-private-endpoint-annotated-1.png)

The private endpoint belongs in the private subnet of the VCN you created for this deployment. The hostname prefix is not the hardest setting, but it is worth setting deliberately because it gives the private endpoint a predictable name for SQL examples, troubleshooting, and documentation. If you let the console generate the value, the connection can still work, but the rest of the setup is harder to follow.

The advanced private endpoint options are also where you select NSGs if you are using point-to-point resource rules instead of Security Lists. Choose the NSG that represents the Autonomous AI Database Serverless private endpoint so your VM-side rule can allow traffic from that NSG to the container port. The `Allow public access` option is in the same advanced network area. Enabling it does not replace the private endpoint path. It adds a public access path for approved users while the database can still use the private endpoint to call the container through the VCN. If the customer manages the database only from inside the VCN, public access can be disabled. The important part for this pattern is that Autonomous AI Database Serverless has a private endpoint in the same VCN as the container endpoint, the allowed public access model matches how administrators will connect, and the database outbound route is set to use the private endpoint path.

![Autonomous AI Database Serverless advanced private endpoint options showing hostname prefix, NSG selection, and Allow public access](https://davidstart.com/content/images/2026/10/adb-private-endpoint-advanced-options-annotated-1.png)

After the database is created, connect as `ADMIN` and set outbound routing. This setting matters because the database may have both public and private access paths. For the container call, you want outbound connections to use the private endpoint path into the VCN.

```sql
ALTER DATABASE PROPERTY SET ROUTE_OUTBOUND_CONNECTIONS = 'PRIVATE_ENDPOINT';

```

Verify the outbound routing property:

```sql
SELECT property_value
FROM database_properties
WHERE property_name = 'ROUTE_OUTBOUND_CONNECTIONS';

```

The expected value is:

```text
PRIVATE_ENDPOINT

```

## Add the Autonomous AI Database Serverless Network ACLs

This is the part that matters most. OCI security rules decide whether packets can move through the VCN, but the database also has its own outbound network ACL model. If the database user does not have ACL permission for the target host and port, `UTL_HTTP` fails before the traffic ever reaches the VM. Use the VM private DNS name, not the VM public IP. In our testing, using the raw private IP caused `ORA-01031` even when the ACL rows looked correct. The private DNS name let Autonomous AI Database Serverless resolve the target as a private target and match the ACL correctly.

The ACL needs three privileges for this connection. `connect` allows the outbound TCP connection, `http` allows the HTTP request, and `resolve` allows the database to resolve the private DNS name. The `private_target => TRUE` argument tells Autonomous AI Database Serverless that this ACL is for a private endpoint target.

Grant `connect` on port 8080:

```sql
BEGIN
  DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
    host           => 'ai-temp-vm.aitemppublic.aitemp.oraclevcn.com',
    lower_port     => 8080,
    upper_port     => 8080,
    ace            => xs$ace_type(
      privilege_list => xs$name_list('connect'),
      principal_name => 'ADMIN',
      principal_type => xs_acl.ptype_db
    ),
    private_target => TRUE
  );
END;
/

```

Grant `http` on port 8080:

```sql
BEGIN
  DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
    host           => 'ai-temp-vm.aitemppublic.aitemp.oraclevcn.com',
    lower_port     => 8080,
    upper_port     => 8080,
    ace            => xs$ace_type(
      privilege_list => xs$name_list('http'),
      principal_name => 'ADMIN',
      principal_type => xs_acl.ptype_db
    ),
    private_target => TRUE
  );
END;
/

```

Grant `resolve` with no port range:

```sql
BEGIN
  DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
    host           => 'ai-temp-vm.aitemppublic.aitemp.oraclevcn.com',
    ace            => xs$ace_type(
      privilege_list => xs$name_list('resolve'),
      principal_name => 'ADMIN',
      principal_type => xs_acl.ptype_db
    ),
    private_target => TRUE
  );
END;
/

```

Verify the ACL entries before testing the call:

```sql
SELECT host, lower_port, upper_port, privilege, principal, private_target
FROM dba_host_aces
WHERE host = 'ai-temp-vm.aitemppublic.aitemp.oraclevcn.com'
ORDER BY privilege;

```

The expected rows should show each privilege for `ADMIN` with `PRIVATE_TARGET` set to `YES`:

```text
CONNECT  ADMIN  YES
HTTP     ADMIN  YES
RESOLVE  ADMIN  YES

```

## Test REST from Autonomous AI Database Serverless

Before using `DBMS_VECTOR`, prove that the database can make a basic REST call. This test is intentionally small because it isolates the hard part: can Autonomous AI Database Serverless reach the private container endpoint over HTTP? If this fails, the problem is networking or ACLs, not vector search.

```sql
SET SERVEROUTPUT ON SIZE UNLIMITED

DECLARE
  l_resp VARCHAR2(32767);
BEGIN
  UTL_HTTP.SET_TRANSFER_TIMEOUT(10);

  l_resp := UTL_HTTP.REQUEST(
    'http://ai-temp-vm.aitemppublic.aitemp.oraclevcn.com:8080/v1/models'
  );

  DBMS_OUTPUT.PUT_LINE(SUBSTR(l_resp, 1, 3000));
END;
/

```

The expected output is a JSON document with the available models. At that point, the test has proven Autonomous AI Database Serverless can reach the private HTTP endpoint.

## Generate an Embedding with DBMS\_VECTOR

After the REST test works, call the embeddings endpoint. This is the point where the setup moves from "the database can reach a private HTTP service" to "the database can use that private service for AI Vector Search work."

```sql
SET SERVEROUTPUT ON SIZE UNLIMITED

DECLARE
  input CLOB;
  v VECTOR;
BEGIN
  UTL_HTTP.SET_TRANSFER_TIMEOUT(30);

  input := 'hello';

  v := DBMS_VECTOR.UTL_TO_EMBEDDING(
    input,
    JSON('{
      "provider":"privateai",
      "url":"http://ai-temp-vm.aitemppublic.aitemp.oraclevcn.com:8080/v1/embeddings",
      "host":"local",
      "model":"all-minilm-l12-v2"
    }')
  );

  DBMS_OUTPUT.PUT_LINE(SUBSTR(VECTOR_SERIALIZE(v), 1, 3000));
END;
/

```

The expected output is a serialized vector. That confirms the request reached the Private AI Services Container and returned an embedding to the database:

```text
[-7.49069378E-002,-1.44330524E-002,4.86498736E-002,...]

```

The full path now looks like this:

```text
DBMS_VECTOR
  -> UTL_HTTP
  -> Autonomous AI Database Serverless private endpoint
  -> VM private DNS name
  -> Private AI Services Container

```

## Troubleshooting

The easiest way to debug this setup is to separate database permissions from network reachability. `ORA-01031` usually means the database ACL did not match. A timeout usually means the request passed the database ACL check but could not reach the container through the network path.

### ORA-01031 from UTL\_HTTP

This usually means the database ACL is wrong or not matching the target. Check the ACL rows and make sure the target host is the VM private DNS name and `PRIVATE_TARGET` is `YES`.

```sql
SELECT host, lower_port, upper_port, privilege, principal, private_target
FROM dba_host_aces
ORDER BY host, privilege;

```

### ORA-30699 Connection Timed Out

This means the database got past the ACL check and is now blocked at the network layer. Check the subnet rules, VM firewall, and container listener before changing the PL/SQL again.

```text
Public subnet security list ingress allows 10.20.0.0/16 -> TCP 8080
Private subnet security list egress allows TCP 8080 to the VM subnet
Security lists are attached to the correct subnets
VM firewall allows 8080/tcp
Container is listening on 0.0.0.0:8080

```

### The Container Works from the VM but Not from Autonomous AI Database Serverless

That usually narrows the issue to one of three things:

```text
Autonomous AI Database Serverless outbound routing is not set to PRIVATE_ENDPOINT
Autonomous AI Database Serverless ACL does not use private_target => TRUE
OCI security lists are not attached to the subnets

```

### SQL Worksheet Works but Autonomous AI Database Serverless Cannot Call the Container

Those are separate paths. SQL Worksheet can use public Autonomous AI Database Serverless access, while the container call uses the Autonomous AI Database Serverless private endpoint. You can have SQL Worksheet access working while private outbound calls still fail because of security lists or ACLs.

## What This Proves

This setup proves that Autonomous AI Database Serverless can call Oracle Private AI Services Container over a private VCN path and use the result through `DBMS_VECTOR`. That is the useful customer outcome: the database can keep vectors close to the data, the model endpoint can stay inside the customer's network, and expensive embedding generation can be offloaded to compute that sits next to the Autonomous AI Database Serverless environment. Customers can scale or size that compute for the AI workload, use the shipped embedding models or bring additional models, and still keep the runtime inside their security boundary.

The pieces that made it work were:

```text
Optional Autonomous AI Database Serverless public access for SQL Worksheet
Autonomous AI Database Serverless private endpoint for outbound private calls
VM private DNS name as the target
DBMS_NETWORK_ACL_ADMIN with private_target => TRUE
Security lists attached to the correct subnets
Private AI container running in HTTP mode on 8080

```

HTTP is useful while proving the private network and ACL path. For production, the next step is HTTPS, certificate handling, API key management, and a tighter security model.

## References

- [Getting Started with Private AI Services Container](https://blogs.oracle.com/database/getting-started-with-private-ai-services-container?ref=davidstart.com)
- [Oracle Private AI Services Container](https://www.oracle.com/database/private%5Fai%5Fservices%5Fcontainer/?ref=davidstart.com)
- [How to use the Oracle Private Services Container with HTTP in PL/SQL](https://blogs.oracle.com/coretec/how-to-use-the-oracle-private-services-container-with-http-in-pl-sql?ref=davidstart.com)