Skip to content

Deploy MinIO + Iceberg with the minio-iceberg template

Deployment

Deploy MinIO + Iceberg with the minio-iceberg template

Stand up MinIO and an Apache Iceberg REST catalog on a single Quake AI instance using the validated OpenTofu template minio-iceberg. You apply the template, read the bootstrap credentials, confirm MinIO and the REST catalog respond, and create a namespace through the REST API.

You run this stack yourself; it is a self-hosted lakehouse catalog, not a managed warehouse service.

YouFloating IPUbuntu instanceMinIOS3 API :9000Iceberg RESTcatalog :8181Block volume/var/lib/docker metadata commitstable filesS3 + REST
Click to zoom
What you will build: MinIO for table files and an Iceberg REST catalog on one instance, reachable over the floating IP from your workstation or a peer in the private network

Monthly cost estimate

Pricing calculator ↗

Sized as a custom package on dedicated vCPU.

Starting template$67.40/mo

Monthly total for the required template above. Use the configurator below to add optional pieces and see the total update.

What each resource is for

MinIO + Iceberg REST catalog host

m2a.large · 2 dedicated vCPU, 8 GiB RAM, 0.5 Gbps

Runs MinIO (S3-compatible object storage) and an Apache Iceberg REST catalog in Docker, with table data on an attached block volume.

MinIO plus the REST catalog run on 2 vCPU and 8 GiB RAM. Size up the instance and data volume for heavy ingest or large curated layers.

$66.00/mo

Compute shown per role at custom-package rates ($29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM). The headline above is the billed total: the cheaper of a named plan and the custom package, plus add-ons.

Included in baseline

m2a.large

2 dedicated vCPU, 8 GiB RAM, 0.5 Gbps

$66.00

Compute + RAM rate basis

2 vCPU + 8 GiB RAM at $29/dedicated vCPU, $7.25/shared vCPU, $1/GiB RAM (regular). Totals apply the flat −$5/mo package promotion.

—

Block storage (80 GiB)

80 GiB at $0.08/GiB/mo

$6.40

Public IP (included)

1 included with the custom package

$0.00

Package promotional discount

Flat −$5.00/mo on the custom package (same promotion as named plans).

$-5.00

Included at no charge

These line items are zero on Quake AI. Many other providers meter them separately.

Data transfer (inbound and outbound)

Unlimited data transfer on every plan; Quake AI does not meter per-GB egress.

AWS, GCP, and Azure meter outbound transfer per GB. DigitalOcean and Hetzner include an allowance on compute plans, then charge overage.

Learn more
$0.00

Private networking

Private networks, subnets, Neutron routers, and security groups are included with the plan.

VPC objects are usually free to create elsewhere, but NAT gateways bill hourly plus per-GB processed. Quake AI uses router SNAT with no separate NAT line item.

$0.00

Control-plane API requests

OpenStack API calls for provisioning and management are included.

Some managed services on other clouds meter API calls or charge for premium control-plane features.

$0.00

Dev/test vs production

Start on shared CPU for dev/test, then promote to dedicated for production with a flavor resize. The network, storage, and template stay the same.

Dev/test on shared CPU

Burstable s1a flavors; suited to prototyping and low or bursty load.

$17.90/mo

Production on dedicated CPU

The headline estimate above; predictable steady-load performance.

$67.40/mo

Saves $49.50/mo while you build on shared CPU.

Shared flavors carry less RAM (m2a.large (8 GiB RAM) -> s1a.small (2 GiB RAM)). A resize reboots the instance; data on attached volumes persists. Size the dedicated flavor for the RAM your production workload needs.

Pricing data last validated: . For current rates, check quake.ai/pricing.

Prerequisites#

You need:

  • OpenTofu 1.6.0 or later (or Terraform 1.6.0 or later) installed locally.
  • Your OpenStack credentials sourced into the shell (source openrc.sh). See the OpenStack CLI guide.
  • An SSH keypair that already exists in your project. Record its name for the key_name variable.
  • A copy of the minio-iceberg template directory from the template reference page.
  • Your workstation's public IP address if you plan to reach MinIO and the REST catalog directly during setup. Find it with curl -sS https://api.ipify.org.

Step 1: Set the variables and apply the template#

MinIO and the REST catalog listen on ports 9000, 9001, and 8181. The template's security group restricts all three to api_allowed_cidr, which defaults to the private network only. To reach the services from your workstation during setup, set api_allowed_cidr to your own address.

Copy the template's example variables file and open it:

bash
cp terraform.tfvars.example terraform.tfvars

Set key_name to the SSH keypair already in your project, and api_allowed_cidr to your workstation's public IP with a /32 suffix:

HCL
key_name           = "YOUR_KEY_NAME"
api_allowed_cidr   = "YOUR_IP/32"

Initialize the working directory, preview the plan, and apply:

bash
tofu init
tofu plan
tofu apply

OpenTofu provisions a private network, a router, a security group, a block volume mounted at /var/lib/docker, an instance, and a floating IP. On first boot, cloud-init mounts the data volume, installs Docker Engine, generates MinIO credentials, creates the warehouse bucket, and starts MinIO plus the REST catalog.

When the apply finishes, read the outputs:

bash
tofu output

Record floating_ip, minio_api_url, minio_console_url, and iceberg_rest_url.

Step 2: Read bootstrap credentials#

No credential ships with the template. cloud-init generates MinIO root credentials on first boot and writes them to the instance.

cloud-init takes a few minutes after the instance reaches ACTIVE. SSH to the host and read the bootstrap file:

bash
ssh ubuntu@YOUR_FLOATING_IP "sudo cat /opt/lakehouse/.bootstrap-credentials"

The file lists minio_root_user, minio_root_password, and warehouse_bucket. Use these values for MinIO console login and S3 client configuration.

Confirm both containers are running:

bash
ssh ubuntu@YOUR_FLOATING_IP "sudo docker ps --filter name=lakehouse"

Step 3: Verify MinIO and the REST catalog#

Open minio_console_url (for example http://YOUR_FLOATING_IP:9001) in your browser and sign in with the bootstrap credentials.

From your workstation, confirm the REST catalog responds:

bash
curl -sS "http://YOUR_FLOATING_IP:8181/v1/config" | head

The response includes catalog configuration. Next, create an Iceberg namespace through the REST API:

bash
curl -sS -X POST "http://YOUR_FLOATING_IP:8181/v1/namespaces" \
  -H "Content-Type: application/json" \
  -d '{"namespace": ["analytics"], "properties": {}}'

List namespaces to confirm registration:

bash
curl -sS "http://YOUR_FLOATING_IP:8181/v1/namespaces"

You now have an open Iceberg catalog backed by MinIO. Query engines such as Spark, Flink, or Trino connect to iceberg_rest_url and read table metadata from the same warehouse URI.

What you built#

  • Applied the minio-iceberg template to provision a network, security group, data volume, instance, and floating IP, and let cloud-init install Docker, MinIO, and the Iceberg REST catalog
  • Read bootstrap credentials generated on first boot
  • Verified MinIO and the REST catalog and registered an Iceberg namespace through the REST API

Scope of this deployment#

This template runs a single-VM lakehouse catalog and object store, not a managed warehouse. The instance is CPU-only and runs in one region. You operate MinIO, the REST catalog, and the data volume yourself: back them up, patch them, and watch disk use as table volume grows. For federated SQL over the tables you register here, add a Trino query host that points at the same REST endpoint and warehouse URI.

Next steps#

Clean up#

When you no longer need the deployment, destroy everything the template created:

bash
tofu destroy

Because MinIO object data and catalog state live on the instance and its attached volume, tofu destroy removes them along with the infrastructure. Export any tables or buckets you want to keep before you destroy.

Before this
Was this page helpful?