Deploying Docker Workloads on VMware vSphere
Deploying a Containerized Application on VMware vSphere with Docker starts with an important boundary: ESXi does not run Docker containers directly. vSphere provides the virtual machine, storage and network, while Docker Engine runs inside a Linux guest and supervises the application.
The pattern below uses an Ubuntu VM and Compose for a straightforward internal service. It covers preparation, deployment, storage, security and recovery, while identifying when a supported Kubernetes service is a better fit.
Choose the deployment model
Use a Docker VM when the service has modest replica counts, a small team and Compose-based operations. Standard OCI images fit this path. For automatic scaling, service discovery, rolling releases or many dependent services, evaluate Tanzu Kubernetes Grid or another supported Kubernetes design integrated with vSphere.
Australian teams in Sydney and Melbourne should also compare nearby public-cloud regions, data-residency obligations and local support costs before standardising on on-premises infrastructure. Broadcom subscription terms, partner support and charges in AUD can change the calculation, especially when workloads move to VMware Cloud on AWS.
Prepare the vSphere foundation
Create the workload from a supported Ubuntu long-term-support image, normally 24.04 LTS, using a reviewed virtual machine template. Two vCPUs, 4 GB of memory and a 40 GB disk suit a small application; adjust through load testing. Record the ESXi, vCenter and guest-OS versions in the deployment runbook.
Attach a dedicated vSwitch port group and VLAN, use DHCP reservation or a static address, and point the guest at approved DNS and NTP servers. Reserve a .com.au hostname or an internal service name for the endpoint; do not expose the Docker bridge interface or the ESXi management interface to application traffic.
Install Docker on the Ubuntu VM
Apply the vSphere guest customisation or cloud-init profile, patch the guest and create a non-default administrator account with SSH keys. Add Docker’s signed Ubuntu package repository, then install the engine, CLI, containerd and Compose plugin. Pin package versions where change control requires reproducible rebuilds.
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo systemctl enable --now docker
sudo usermod -aG docker $USER
Enable the daemon at boot and add only trusted operators to the docker group. Membership grants root-equivalent control of the host, so use named accounts and review membership regularly. Permit SSH and only the published application port through the guest firewall.
Run the containerized application
Build or import an OCI-compatible image, scan it and push it to an authenticated registry. Use an immutable version tag or digest in Compose, then keep credentials outside version control. A minimal definition can look like this:
services:
app:
image: registry.example.com/orders:1.4.2
restart: unless-stopped
ports:
- "10.20.30.40:8080:8080"
environment:
DATABASE_URL: ${DATABASE_URL}
volumes:
- app-data:/var/lib/orders
volumes:
app-data: {}
Run docker compose pull and docker compose up -d, then verify health, logs and application telemetry before replacing the previous release. The restart policy restarts the container, not the VM; vSphere High Availability must be configured separately. Back up application data with application-aware methods rather than copying a live database volume.
Design networking and persistent storage
Published container ports terminate on the Ubuntu VM, not on ESXi. Restrict them to the application VLAN with a reverse proxy or supported load balancer, terminate TLS there and preserve the client address. Avoid promiscuous mode, bridged Compose drivers and direct routing into Docker’s internal bridge unless the design has been tested.
A named Docker volume normally lives on the VM disk and follows that VM rather than a container. Give stateful services a separate vMDK or a mounted datastore; the two-node vSAN guide explains a compact storage foundation for a lab. For Australian metropolitan designs, measure Sydney-to-Melbourne latency and recovery time instead of relying on headline bandwidth.
Secure and monitor the workload
Run containers as a non-root user with a read-only filesystem where possible, drop Linux capabilities and mount only required paths. Never expose the Docker socket to the application. Rebuild images frequently enough to receive operating-system fixes, remove unused packages and fail builds that contain critical vulnerabilities or expired base-image licences.
Centralise logs and metrics, alert on image age, container restarts, disk pressure and failed health checks, and restrict vCenter permissions by job role. For inventory, reporting and evidence collection, the free PowerCLI tools can automate checks across vSphere estates, from a Brisbane home lab to a Melbourne production cluster.
Validate recovery and local operations
Test application failure, Docker daemon restart, VM reboot and controlled datastore recovery in a non-production window. Confirm that health checks fail quickly, alerts reach the right Australian on-call roster and backups restore to a clean environment. Define recovery point and recovery time objectives before promising service levels to business owners.
Store timestamps in UTC while displaying AEST or AEDT, accounting for daylight-saving transitions in Brisbane, Sydney and Melbourne. Map controls to the ASD Essential Eight and, where relevant, APRA obligations; document data location, privileged access and incident contacts. These Australian requirements should shape validation evidence, not sit in a separate compliance checklist.
Start with a disposable non-production VM: deploy one pinned image, publish it only on the private application VLAN, capture restart evidence and record the rollback command. Once those checks pass, promote the same artefact through staging and production rather than rebuilding it at each stage.