S3 Storage Appliance for VMware DSM: Build, Deploy, and Configure

I built this appliance to give VMware Data Services Manager (DSM) a dedicated S3-compatible backup target in my lab. The goal was a repeatable OVA that I could deploy in vSphere, configure through deployment properties, and connect to DSM without rebuilding an object storage server each time.

The result is S3 Storage Appliance 1.0.0: Ubuntu Server 24.04, SeaweedFS 4.48, and NGINX in one VM. It includes the software needed for offline first-boot installation, a separate data disk, and two buckets with separate credentials. This is a lab release.

GitHub repository · Download the OVA, deployment guide, checksum, and qualification manifest

Update: using this S3 server for the PAIS document library

October 21, 2026: I also use my existing S3 endpoint as source storage for the PAIS instance now configured through VCF Automation. This was an additional configuration on the existing server; it does not change the two-bucket defaults or qualification results of the downloadable 1.0.0 OVA.

I created a separate pais-shared-library bucket and separate library-reader and uploader identities. The PAIS identity lists the approved bucket and reads documents; the uploader supplies the documents. DSM system backups, database backups, and logs remain separate from this library. The bucket stores source documents; PAIS indexing creates the retrieval representation separately.

In PAIS, select Data Indexing and Retrieval → Data Sources → Amazon S3 Compatible Store, then supply the HTTPS server URL, library-reader credentials, dedicated bucket, and an optional approved prefix. Keep endpoint CA trust configured in PAIS. A signed workstation S3 listing does not prove that the PAIS runtime can connect.

After the Automation migration, my S3 firewall needed HTTPS from the new VPC’s actual translated source address. I checked the arriving traffic and added the narrow source rule while preserving DSM’s existing access. Do not copy another lab’s subnet or assume the old runtime source still applies. The new PAIS connector validated and its knowledge-base link was recreated. The CPU embedding endpoint returned a 384-dimensional vector, but initial document indexing and retrieval tests were still pending at this update.

What it was built for

DSM system backups and database backups serve different purposes. A system backup protects DSM’s own configuration and state. A managed database backup protects a database and its recovery history. I wanted a single lab endpoint with separate buckets and service identities for those two workflows.

  • dsm-system: DSM system backup repository.
  • dsm-postgres: intended backup location for managed PostgreSQL databases.

Each identity is scoped to its own bucket. Anonymous access and cross-bucket access are denied. The endpoint uses HTTPS and path-style S3 addressing. Bucket names and region can be changed during deployment.

How the appliance works

DSM system backup → HTTPS :443 → NGINX → SeaweedFS S3 → dsm-system
DSM database backup → HTTPS :443 → NGINX → SeaweedFS S3 → dsm-postgres
                                                    ↓
                                  Data and storage metadata: /srv/s3

SeaweedFS master, volume, filer, and S3 services run under a dedicated account. Their internal listeners bind to loopback; NGINX exposes HTTPS. Object data and SeaweedFS metadata reside on the data disk at /srv/s3. The storage services require that mount, preventing a missing data disk from silently redirecting writes onto the OS disk.

ComponentDefault
CPU / memory4 vCPU / 8 GiB RAM
OS disk60 GiB
Data disk500 GiB
Client endpointHTTPS, TCP 443
Administrationubuntu account, SSH on TCP 22
S3 regionus-east-1

1. Download and verify the OVA

Download S3-Storage-Appliance-1.0.0.ova and its SHA256 file from the release. On Windows, calculate the hash with PowerShell:

Get-FileHash ./S3-Storage-Appliance-1.0.0.ova -Algorithm SHA256

The expected SHA256 for version 1.0.0 is:

a17f9ead3724444da9979254620d94d11796e8f891a904b55be6797c482ac6e7

2. Deploy in vSphere

  1. Select Deploy OVF Template, choose the OVA, and select the destination compute resource and datastore. Use thin provisioning for the two disks.
  2. Map VM Network to a port group reachable by DSM and the database workloads that will write backups.
  3. Set a unique hostname and the masked Password for default user (ubuntu). There is no baked-in password and no mandatory first-login password change.
  4. Choose DHCP or Static. Static mode requires an address, dotted-decimal netmask, gateway, and DNS servers. NTP properties apply in Static mode; DHCP deployments use Ubuntu’s NTP defaults.
  5. Set the S3 endpoint DNS name, for example s3.lab.example.com, and create the matching DNS record. Set the DNS search domain if required, particularly for a unicast internal .local domain.
  6. Keep or change the region and two bucket names. Restrict SSH administrator and HTTPS S3 client source CIDRs to the networks that need access. Defaults allow private IPv4 ranges.
  7. Power on the VM and allow initialization to complete.

Supply an SSH public key if you want key-based access. Uncheck Enable SSH password authentication for key-only SSH; the deployment password still applies to the Ubuntu account. Supply at least a password or key so that you can administer the VM. vCenter administrators can access deployment metadata, including supplied passwords.

First boot expects exactly one blank secondary disk of at least 10 GiB and formats it to its full initial size. Increase disk sizes before first boot if needed. Do not attach an existing data disk for automatic initialization, and do not clone an initialized appliance as a new deployment. Import the clean OVA to generate independent identities and keys.

3. Check initialization and retrieve credentials

Log in as ubuntu using the deployment password or SSH key. Ubuntu initialization finishes before S3 initialization:

cloud-init status --wait
sudo systemctl status s3-appliance-initialize
sudo s3-appliance status
sudo /usr/local/sbin/s3-appliance-health
sudo s3-appliance credentials

Wait for the initializer to show active (exited) and for the health check to pass. The credentials command displays the endpoint, buckets, and their scoped access keys and secret keys. Keep that output private. Each deployment generates new credentials and TLS keys, which persist across reboot.

4. Prepare TLS trust

The appliance initially generates a unique self-signed certificate for its configured DNS name. For DSM integration, I use a certificate issued by my lab CA. Generate a CSR with the existing appliance key:

sudo s3-appliance csr > s3.csr

Submit the CSR to your CA, requesting a server certificate whose SAN includes the endpoint DNS name. Transfer the issued certificate and issuer CA bundle securely to the appliance, then install them using the existing private key:

sudo s3-appliance install-tls   --cert server-chain.pem   --key /etc/s3-appliance/tls/s3.key   --ca issuer-ca.pem

The helper checks the hostname, certificate chain, and key match before testing and reloading NGINX. DSM must also trust the issuer. For a deliberate self-signed lab deployment, trust the appliance’s public certificate explicitly. Do not disable certificate verification.

DSM’s supported Kubernetes API documents S3 trust through BackupLocation.spec.trustBundle. For a globally trusted custom CA, append the public CA certificate to ca-bundle.crt in the trusted-root-ca ConfigMap in namespace dsm-system, preserving existing certificates. A location-specific trust ConfigMap is another supported option for database backup locations. Use the DSM API kubeconfig and permissions appropriate to your installation; these are DSM S3 trust settings, separate from vCenter certificate bindings. See the official DSM Kubernetes API reference for the trust bundle format and scope.

5. Configure DSM system backups

My initial integration was tested with DSM 9.1.1, build 9.1.1.0100.25777183. Sign in with an account authorized to manage the system backup repository. In DSM’s system backup repository configuration, enter the following values, replacing the example endpoint and generated credentials:

SettingValue
S3 endpointhttps://s3.lab.example.com
Bucketdsm-system
Regionus-east-1
Access key / secret keyThe dsm-system identity from the appliance
Force path styleEnabled
TLS verificationEnabled, with the endpoint certificate chain trusted

The endpoint is the server URL; enter the bucket in its separate field. Use the region and bucket selected during OVA deployment if you changed the defaults. Save the repository, confirm connectivity, then run or observe the initial system backup. Check DSM’s system backup history and WAL archival status, and review the retention policy and schedule for your lab.

6. Configure managed PostgreSQL backups separately

A working DSM system repository does not automatically configure database backups. With a DSM Admin or another appropriately authorized account, create an S3 database backup location using the same endpoint and region, the dsm-postgres bucket, and its separate credentials. Enable path-style addressing and configure certificate trust for that location. Select the location in the managed PostgreSQL database’s backup configuration and set the required schedule and retention.

Allow HTTPS connectivity from the database backup workers as well as DSM itself. Run a database backup, restore it to an isolated test database, and test point-in-time recovery when that is part of your lab exercise. My initial system backup integration passed; managed PostgreSQL backup, restore, and PITR remain a separate validation step.

What I tested

The OVA passed twenty qualification checks, including fresh DHCP and static deployments in VMware Workstation, an offline first boot on vCenter, supplied-password authentication, SSH key-only mode, independent credentials and TLS keys, signed S3 operations, multipart readback, bucket isolation, missing-data-mount protection, and object and credential persistence across reboots.

On my original lab deployment, DSM completed a full system backup and reported successful WAL archival. Backup manifests and a sample database file were read back from S3. A complete DSM recovery has not yet been tested. The generic OVA qualification and the original DSM integration are separate evidence; a successful backup is not proof of a successful restore.

Troubleshooting and day-to-day operation

  • 403 in a browser: expected without signed credentials. A 403 from an authenticated client calls for checking the identity, bucket, region, and path-style setting.
  • Certificate errors: check the endpoint DNS name against the SAN, the served chain, and DSM’s S3 trust bundle.
  • Timeouts: check DNS and routing from the actual writer, port group mapping, and the appliance’s permitted HTTPS CIDRs.
  • Initialization fails: inspect sudo journalctl -u s3-appliance-initialize --no-pager and confirm that the secondary disk is blank and unambiguous.
  • Storage services refuse to start: verify that /srv/s3 is mounted. The mount guard is intentional.

A local health timer runs every fifteen minutes and checks the mount, services, free space, certificate expiry, and anonymous-access denial. External alerts and DSM backup-age monitoring are not configured. Versioning, object lock, and lifecycle expiration are not enabled by default.

This is one VM with one data disk and no object-level redundancy. Keep an independent recovery copy; this protects the data in my lab if the appliance or its datastore fails. For a consistent cold copy, stop NGINX and all SeaweedFS services and copy the entire /srv/s3 filesystem together with configuration, credentials, and TLS material. Volume files alone do not include all the metadata needed for recovery.

Download S3 Storage Appliance 1.0.0 and the deployment guide.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.