Back
Deploying an OCI Container Instance Terraform

🐳 Deploying an OCI Container Instance with Ephemeral Public IP Using Terraform — and the Docker Push Trick You Shouldn’t Miss (Refreshed: October 2025)

This guide focuses on OCI Container Instance Terraform deployment — showing how to combine ephemeral public IPs with Docker image push to OCIR for a fully automated setup. In this tutorial, we’ll walk through deploying an OCI Container Instance with an ephemeral public IP using Terraform (or Oracle Resource Manager).

But here’s the real trick 👇
Before your container can run in OCI, you need to build your Docker image locally and push it to OCIR — fully automated as part of your Terraform plan.

When working with OCI Container Instance Terraform setups, pushing images to OCIR is often the missing step that trips people up.

This post is part of a hands-on journey inside FoggyKitchen’s Terraform training. At the end, you’ll find a link to explore the full course

🌐 What We’re Building

  • A private container repo in OCIR.

  • A Docker build & push pipeline triggered by Terraform (null_resource + local-exec).

  • A Container Instance running the pushed image, exposed through ephemeral public IP.

  • Optional SSL volume mount and environment variables.

This architecture is lightweight, perfect for labs, demos, or as a building block for larger OCI deployments.

Figure 1. Container Instance architecture with ephemeral public IP.

🧱 Step 1: Build & Push to OCIR (The Trick)

Before the Container Instance can pull an image, you need to build and push the image to your private OCIR repo. This is done entirely within Terraform using a null_resource block.

resource "oci_artifacts_container_repository" "FoggyKitchenArtifactsContainerRepository" {
  provider       = oci.targetregion
  compartment_id = oci_identity_compartment.FoggyKitchenCompartment.id
  display_name   = "${var.ocir_repo_name}/fknginx"
  is_public      = false
}

resource "null_resource" "deploy_to_ocir" {
  depends_on = [oci_artifacts_container_repository.FoggyKitchenArtifactsContainerRepository]

  # 1) Login to OCIR
  provisioner "local-exec" {
    command = "echo '${local.ocir_user_password}' | docker login ${local.ocir_docker_repository} --username ${local.ocir_user_name} --password-stdin"
  }

  # 2) Clean old images
  provisioner "local-exec" {
    command = "image=$(docker images | grep fknginx | awk -F ' ' '{print $3}') ; docker rmi -f $image &> /dev/null || true"
  }

  # 3) Build the image
  provisioner "local-exec" {
    command = "docker build -f docker/Dockerfile${local.enable_ssl} --build-arg NGINX_PORT=${var.nginx_port} --build-arg NGINX_SSL_PORT=${var.nginx_ssl_port} --build-arg HOST_NAME=${var.dns_domain} -t fknginx ."
  }

  # 4) Tag & push to OCIR
  provisioner "local-exec" {
    command = "image=$(docker images | grep fknginx | awk -F ' ' '{print $3}') ; docker tag $image ${local.ocir_docker_repository}/${local.ocir_namespace}/${var.ocir_repo_name}/fknginx:latest"
  }

  provisioner "local-exec" {
    command = "docker push ${local.ocir_docker_repository}/${local.ocir_namespace}/${var.ocir_repo_name}/fknginx:latest"
  }

  # 5) Optional cleanup
  provisioner "local-exec" {
    when    = destroy
    command = "image=$(docker images | grep fknginx | awk -F ' ' '{print $3}') ; docker rmi -f $image &> /dev/null || true"
  }
}

🔑 Requirements

  • Docker installed on the machine running terraform apply.

  • OCIR auth token (not your console password!) for login.

  • Namespace, region, repo variables configured.

  • IAM policies allowing Container Instances to pull images from OCIR.

🐳 Step 2: Provision the Container Instance

Once the image is pushed, the Container Instance can reference it via image_url. Here’s the core Terraform snippet:

resource "oci_container_instances_container_instance" "FoggyKitchenContainerInstance" {
  depends_on          = [null_resource.deploy_to_ocir, oci_identity_policy.FoggyKitchenContainerInstancesVaultPolicy]
  provider            = oci.targetregion
  compartment_id      = oci_identity_compartment.FoggyKitchenCompartment.id
  availability_domain = var.availablity_domain_name == "" ? data.oci_identity_availability_domains.ADs.availability_domains[0]["name"] : var.availablity_domain_name

  image_pull_secrets {
    registry_endpoint = "${local.ocir_docker_repository}/${local.ocir_namespace}/${var.ocir_repo_name}/"
    secret_type       = var.enable_vault ? "VAULT" : "BASIC"
    username          = var.enable_vault ? null : base64encode("${local.ocir_namespace}/${var.ocir_user_name}")
    password          = var.enable_vault ? null : base64encode(var.ocir_user_password)
    secret_id         = var.enable_vault ? var.vault_secret_id : null
  }

  containers {
    image_url    = "${local.ocir_docker_repository}/${local.ocir_namespace}/${var.ocir_repo_name}/fknginx:latest"
    display_name = "FoggyKitchenContainerInstance"
    environment_variables = local.environment_variables
  }

  shape = var.container_instance_shape

  shape_config {
    memory_in_gbs = var.container_instance_shape_memory
    ocpus         = var.container_instance_shape_ocpus
  }

  vnics {
    subnet_id             = oci_core_subnet.FoggyKitchenContainerInstanceSubnet.id
    is_public_ip_assigned = var.enable_ephemeral_public_ip
    nsg_ids               = var.enable_nsg ? [oci_core_network_security_group.FoggyKitchenWebSecurityGroup[0].id] : []
  }

  display_name = "FoggyKitchenContainerInstance"
  state        = "ACTIVE"
}

The key is is_public_ip_assigned = var.enable_ephemeral_public_ip.
This assigns a temporary IP that’s ideal for quick testing.

This is a lightweight OCI Container Instance Terraform configuration that you can extend for production-grade workloads.

📚 OCI Container Instances Documentation

🚀 Quick Start

1. Clone the repo:

git clone https://github.com/mlinxfeld/terraform-oci-container-instance
cd terraform-oci-container-instance

2. Configure variables & auth
OCIR namespace, repo name, auth token, compartment, etc.

3. Run Terraform:

terraform init
terraform apply

4. Test the endpoint:

curl -I http://EPHEMERAL_PUBLIC_IP/

5. Clean up:

terraform destroy

🛡️ Security & Production Tips

  • Prefer Vault secrets for OCIR authentication in image_pull_secrets.

  • Add NSG rules to restrict inbound access (e.g., 80/443 from specific IPs).

  • In production, offload build & push to OCI DevOps or GitHub Actions — not local-exec.

  • Use versioned image tags, not :latest, for immutability.

🔗 Related Post

Want to see the same OCIR push trick applied to Kubernetes (OKE)?
👉 OCI OKE + OCIR + Terraform: Build, Push, Deploy

Both workflows share the same building block — pushing to OCIR from Terraform — making it easy to graduate from single Container Instances to fully orchestrated OKE clusters.

🧠 Ready to Go Deeper?

This tutorial is just a teaser. In our OCI Container Instances with Terraform (2023 Edition) course, we dive much deeper.

You’ll learn how to:

  • Learn how OCI Container Instances work
  • Deploy containerized apps using Docker images
  • Set up networking (VCNs, subnets, security lists)
  • Configure DNS and SSL certificates for HTTPS access
  • Integrate everything with OCI IAM for access control
  • Automate the entire workflow using Terraform

👉 Enroll now and master Container Instances end-to-end in OCI.

OCI Container Instances course

👉 Master OCI Container Instances with Terraform

Hands-on course covering OCIR, networking, SSL, DNS, IAM integration, and full automation — everything you need to deploy containerized apps on OCI like a pro.

🔒 Lifetime • ⏱️ Self-paced • 🧪 Real labs

Check also other courses:​

Leave A Reply

🚀 Master OCI Container Instances with Terraform

Build, push, and deploy containerized apps on OCI like a pro. Learn networking, OCIR, SSL, and automation — all hands-on, step by step.

OCI Container Instances course