Skip to main content

OCI Container Registry (OCIR): Store, Manage, and Deploy Docker Images

Calculating read time…

💡 Think of it like: A big magical cupboard ☁️ in the cloud where you store your packaged apps — and anyone with permission can take the package and run it anywhere!




🐳 What is a Container?

Before we talk about OCIR, let's understand what a Container is. This is the foundation of everything!

Think of a container like a tiffin box 🍱 for your software. You pack your app, its settings, and all the libraries it needs — everything — inside one box. Wherever you carry that tiffin box, the food (software) is safe, ready, and tastes exactly the same!

  • 🔴 Without containers: "It works on my laptop but breaks on the server!" 😤
  • 🟢 With containers: "It works everywhere, every single time!" 🎯

⚠️ Important: A Container Image is the recipe for making that tiffin box. It's a file that describes EVERYTHING needed to run your app. When you "run" the image, it becomes a live, working container!

📦 What is OCI Container Registry (OCIR)?

Now that we know what a container is, let's talk about OCIR.

OCI Container Registry (OCIR) is Oracle Cloud's managed service for storing, managing, and sharing your container images. Think of it like Google Drive or iCloud — but ONLY for container images!

You upload (push) your images to OCIR, they are stored safely in the cloud, and your servers download (pull) them whenever they need to run your app.

🧒 Simple Explanation for a 10-year-old: Imagine a HUGE cupboard in the cloud ☁️. You can put your packed app boxes (images) in this cupboard. Your servers (other cloud computers) can open the cupboard and take the box to run the app. OCIR is that magical cloud cupboard!

⭐ Key Features of OCIR

  • 🔒 Private by Default — Only you and your team can see your images. Strangers cannot access them!
  • 🌍 Regional Storage — Your images are stored close to where your servers run, so downloads are super fast!
  • 🔗 OCI Standards — Works with Docker images, Helm charts, ARM and AMD64 images — very flexible!
  • 🛡️ Vulnerability Scanning — OCIR automatically checks your images for security problems!
  • 📜 Image Signing — You can "sign" images with a key so nobody can tamper with them!
  • ♻️ Auto Cleanup — Set rules to automatically delete old images so you don't waste storage!
  • 🤝 IAM Integration — Uses Oracle's own login system — no separate passwords to manage!

🧩 Key Concepts — The Building Blocks of OCIR

Every technology has its own vocabulary. Let's learn the important OCIR words one by one — explained super simply! 

1️⃣ Tenancy Namespace

When you sign up for Oracle Cloud, Oracle gives your account a unique nickname called a Tenancy Namespace. It looks something like this: ansh81vru1zp

🧒 Simple explanation: Imagine your school gives every student a unique ID number. That ID number is like your tenancy namespace — it is random, unique to only you, and never changes!

💡 How to find it: Go to OCI Console → Profile (top right) → Tenancy → Object Storage Namespace. You can also run this CLI command: oci os ns get

2️⃣ Region and Region Key

Oracle Cloud has data centers all over the world called Regions. Each region has a short nickname called a Region Key.

  • US East (Ashburn) → Region Key: iad → OCIR endpoint: iad.ocir.io
  • US West (Phoenix) → Region Key: phx → OCIR endpoint: phx.ocir.io
  • UK South (London) → Region Key: lhr → OCIR endpoint: lhr.ocir.io
  • Germany (Frankfurt) → Region Key: fra → OCIR endpoint: fra.ocir.io
  • Japan (Tokyo) → Region Key: nrt → OCIR endpoint: nrt.ocir.io
  • India (Mumbai) → Region Key: bom → OCIR endpoint: bom.ocir.io

✅ Best Practice: Always use the region closest to where your app is running. This makes image downloads (pulls) super fast!

3️⃣ Repository

A Repository is like a labeled folder inside your registry. It holds different versions of the SAME app image.

🧒 Simple explanation: Imagine a photo album 📸 called "School Trip 2026". All photos from that trip live in that one album. Similarly, a repository called myproject/web-app holds all versions of your web app — version 1.0, version 2.0, version 3.0, etc.

4️⃣ Image Tag

A Tag is a label you put on your image to identify its version. Think of it like a version number sticker on a product!

  • :latest → The most recent version (avoid this in production!)
  • :v1.0 → Version 1.0 (clear and specific ✅)
  • :v2.3.1 → Version 2.3.1 (even better! ✅)

⚠️ Warning: Never use :latest in production! If someone pushes a broken image with the :latest tag, your production app will pull the broken image and crash. Always use specific version tags!

5️⃣ The Full OCIR Image Path (Address)

Every image in OCIR has a complete address. Think of it exactly like a home mailing address — it tells everyone precisely WHERE the image lives.

The format is:

ocir.<region>.oci.oraclecloud.com / <tenancy-namespace> / <repository-name> : <tag>

Example:
ocir.us-ashburn-1.oci.oraclecloud.com/ansh81vru1zp/myproject/myapp:v1.0
|___________________________________|  |___________|  |_____________| |__|
         Registry Endpoint               Tenancy NS     Repository    Tag
       (Which OCI Region?)             (Your unique ID)  (App folder) (Version)

💡 Shorter format also works: iad.ocir.io/ansh81vru1zp/myproject/myapp:v1.0 — Oracle supports both!

🗺️ How OCIR Works — The Big Picture

Let's look at how everything fits together. Read it one step at a time — it is not complicated! 😊

YOUR LAPTOP / CI-CD PIPELINE
┌──────────────────────────────┐
│  1. Write your App Code      │
│  2. Create a Dockerfile      │
│  3. docker build →           │
│     Container Image is ready │
└──────────────┬───────────────┘
               │
        docker push (upload ⬆️)
               │
               ▼
┌──────────────────────────────────────────────────────────┐
│            OCI Container Registry (OCIR)                 │
│                                                          │
│  Repository: myproject/myapp                            │
│    :v1.0  ✅                                             │
│    :v2.0  ✅                                             │
│    :v3.0  ✅   + Vulnerability Scanning + IAM Control   │
└──────────────────────────────┬───────────────────────────┘
                               │
              docker pull (download ⬇️)
               ┌───────────────┴───────────────┐
               │                               │
               ▼                               ▼
  ┌─────────────────────┐         ┌────────────────────────┐
  │  OKE Kubernetes     │         │  OCI Compute Instance  │
  │  (K8s Cluster)      │         │  (Your Cloud Server)   │
  │  Pulls image &      │         │  Runs the container    │
  │  runs the app 🚀    │         │  directly              │
  └─────────────────────┘         └────────────────────────┘

See how it flows? You build the image on your laptop → push it to OCIR (the safe cupboard in the cloud) → your servers pull it from OCIR and run it! 🎯

🛠️ Prerequisites — Pack Your Bag Before Starting!

Before using OCIR, make sure you have these things ready. Think of it like packing your school bag the night before! 🎒

  • ✅ OCI Account — Free tier works perfectly! Sign up at oracle.com/cloud/free
  • ✅ Docker installed on your laptop (get it at docker.com)
  • ✅ OCI CLI installed (Oracle's command-line tool)
  • ✅ Your Tenancy Namespace — find it in OCI Console
  • ✅ An Auth Token — we'll create this step by step below!

📘 Free Tier Note: Oracle gives you a FREE account with enough resources to practice everything in this guide. No credit card needed for the free tier! 🎉

👣 Step-by-Step Guide — Push Your First Image to OCIR!

Now the real fun begins! Let's go through every step one by one. Each step is easy — just follow along! 🙌

Step 1 — Create an Auth Token (Your OCIR Password)

OCIR does NOT use your regular OCI login password. It uses a special token called an Auth Token. This is like a special guest pass 🪪 — created just for OCIR!

How to create it:

  1. Log in to OCI Console at cloud.oracle.com
  2. Click your Profile icon at the top-right corner
  3. Click "My Profile"
  4. In the left panel, under "Resources", click "Auth Tokens"
  5. Click "Generate Token"
  6. Give it a name like ocir-token
  7. Click "Generate Token" again
  8. ⚠️ COPY the token immediately! You will NEVER see it again after closing the popup!

❌ Warning: Once you close that dialog box, the token is gone forever. Save it in a safe place like a password manager or a private notes file BEFORE closing!

Step 2 — Find Your Tenancy Namespace

You need your tenancy namespace for all OCIR operations. Here's how to find it in 3 ways:

  • Console: Hamburger menu ☰ → Governance & Administration → Tenancy Details → Object Storage Namespace
  • CLI command: oci os ns get
  • Profile: Top-right Profile icon → Tenancy (you'll see the namespace listed there)

Your namespace looks something like this: ansh81vru1zp — random letters and numbers, unique to your account.

Step 3 — Login to OCIR with Docker

Now we connect our Docker tool to OCIR. This is like logging into Netflix before you can watch movies! 🎬

📋 What the command below does:
This tells Docker: "Hey! I want to connect to Oracle's container registry in the Ashburn region. Here is my username and my special auth token as the password." After this, Docker knows WHERE to send (push) and receive (pull) images from!

# Replace values inside < > with YOUR actual values!

# For regular OCI users:
docker login iad.ocir.io \
  -u <your-tenancy-namespace>/<your-oci-username>

# For federated users (logged in via Google, Microsoft, or IDCS):
docker login iad.ocir.io \
  -u <your-tenancy-namespace>/oracleidentitycloudservice/<your-email@domain.com>

# When prompted for Password:
# → Paste your Auth Token here (NOT your OCI console password!)

# Example username for regular user:
# ansh81vru1zp/john.doe@example.com

# Example username for federated user:
# ansh81vru1zp/oracleidentitycloudservice/john.doe@example.com

If successful, you will see: Login Succeeded 🎉

✅ Tip: Use iad.ocir.io for Ashburn, phx.ocir.io for Phoenix, lhr.ocir.io for London. Always match the region to where your OCI resources live!

Step 4 — Create a Repository in OCIR

A repository is a labeled folder for your images. You should create it before pushing images to it.

Option A — Using the OCI Console (easiest for beginners):

  1. Go to OCI Console → Developer Services → Container Registry
  2. Click "Create repository"
  3. Choose your Compartment
  4. Enter a repository name (example: myproject/myapp)
  5. Choose Private (strongly recommended!) or Public
  6. Click "Create repository" ✅

Option B — Using OCI CLI:

📋 What the command below does:
This command creates a new private repository inside your Oracle Cloud account. Think of it like creating a new labeled folder in the cloud cupboard before putting any images inside!

# Create a private repository using CLI
oci artifacts container repository create \
  --compartment-id <your-compartment-ocid> \
  --display-name myproject/myapp \
  --is-public false

# Output: A JSON response confirming the repo was created!
# Look for "lifecycle-state": "AVAILABLE" to confirm success.

Step 5 — Write a Dockerfile and Build Your Image

Before you can push anything to OCIR, you need an image to push! Let's build a simple one. First, create two files on your computer.

File 1 — Create a file named Dockerfile (no extension!):

📋 What this Dockerfile does:
This is the recipe for our container. It says: "Start from an official nginx web server. Copy our custom webpage into it. When the container starts, run the web server." Think of it like a cooking recipe — follow these exact steps and you get a working app! 🍳

# Dockerfile — our container image recipe

# Start FROM an official, small nginx web server base image
FROM nginx:alpine

# Copy our custom welcome page into the right folder inside the container
COPY index.html /usr/share/nginx/html/index.html

# Tell Docker that our app will listen on port 80 (standard web port)
EXPOSE 80

# When container starts, run nginx in the foreground
CMD ["nginx", "-g", "daemon off;"]

File 2 — Create a file named index.html in the same folder:

📋 What this HTML file does:
This is the actual webpage that will show up when someone visits our app. It is a simple "Hello from OCIR!" message to prove our container is alive and working! 🌐

<!-- index.html — our app's simple welcome page -->
<html>
  <body>
    <h1>Hello from OCIR! 🎉</h1>
    <p>My first container image is running successfully!</p>
  </body>
</html>

Now build the Docker image from these two files:

📋 What the command below does:
This reads the Dockerfile recipe and builds a container image on your computer. The -t flag gives the image a name (myapp) and version tag (v1.0). The dot (.) at the end means "look for the Dockerfile in THIS current folder."

# Build the Docker image
# -t = tag (give it a name and version)
# The dot at the end means "use the Dockerfile in this folder"
docker build -t myapp:v1.0 .

# Verify the image was created successfully:
docker images

# Output example:
# REPOSITORY   TAG     IMAGE ID       CREATED         SIZE
# myapp        v1.0    abc123def456   2 minutes ago   23.5MB

Step 6 — Tag the Image with the OCIR Address

Right now our image only has a local name: myapp:v1.0. We need to give it the full OCIR address so Docker knows WHERE to upload it!

🧒 Simple explanation: Imagine you wrote a letter but didn't put any address on the envelope. The post office won't know where to deliver it! Tagging is like writing the full delivery address on the envelope before mailing it. 📬

📋 What the command below does:
We are giving our existing image a second name (called a tag) that includes the full OCIR path. The image data itself doesn't change — we are simply adding an "address label" to it so Docker knows to send it to our OCIR repository when we push!

# Format:
# docker tag <local-image>:<tag>   <ocir-endpoint>/<namespace>/<repo>:<tag>

docker tag myapp:v1.0 \
  iad.ocir.io/ansh81vru1zp/myproject/myapp:v1.0

# Verify both tags now exist:
docker images

# Output:
# REPOSITORY                                         TAG    SIZE
# myapp                                              v1.0   23.5MB
# iad.ocir.io/ansh81vru1zp/myproject/myapp           v1.0   23.5MB
# ↑ Same image, just with the OCIR address attached!

Step 7 — Push the Image to OCIR ⬆️

This is the exciting moment! We are uploading our image to the cloud! ☁️

📋 What the command below does:
This command uploads our container image from our local computer to OCIR. Docker breaks the image into layers and sends them one by one to Oracle Cloud. Once done, the image is safely stored in OCIR and any authorized server can download and run it!

# Push the image to OCIR!
docker push iad.ocir.io/ansh81vru1zp/myproject/myapp:v1.0

# You will see output like this:
# The push refers to repository [iad.ocir.io/ansh81vru1zp/myproject/myapp]
# abc123def456: Pushing  10.24MB/23.5MB
# abc123def456: Pushed
# v1.0: digest: sha256:abc123... size: 527

# Done! ✅ Your image is now safely in OCIR!

✅ Verify it worked! Go to OCI Console → Developer Services → Container Registry. You will see your repository and the image with tag v1.0 listed there! 🎉

Step 8 — Pull the Image from OCIR ⬇️

Now let's pretend we are on a different server and we want to get our image. This is exactly what your cloud servers do when they deploy your app!

📋 What the command below does:
This command downloads the container image from OCIR to the current computer — just like downloading a file from Google Drive! After this, we run the image to start our app and verify it works.

# Pull (download) the image from OCIR
docker pull iad.ocir.io/ansh81vru1zp/myproject/myapp:v1.0

# Run the image locally to test it!
# -d means run in background
# -p 8080:80 maps port 8080 on your computer to port 80 in the container
docker run -d -p 8080:80 iad.ocir.io/ansh81vru1zp/myproject/myapp:v1.0

# Now open your browser and visit: http://localhost:8080
# You should see: "Hello from OCIR! 🎉"

Congratulations! 🏆 You have successfully built → tagged → pushed → pulled → ran your first OCIR image!

🔐 IAM Policies — Controlling Who Can Do What

Oracle uses IAM (Identity and Access Management) to control who can push, pull, or manage images in OCIR. Think of it like an access card system in an office building:

  • 🧑‍💻 Developers → Can push new images and pull them
  • 🤖 Kubernetes cluster → Can only pull images to run them
  • 👀 Audit team → Can read and view images but not change anything
  • 👑 Admins → Full access to do everything

📋 What the policy statements below do:
These are permission rules you write in OCI's IAM console. They tell Oracle: "Users in the 'developers' group are ALLOWED to push and pull container images in our tenancy." Without these policies, users get "Access Denied" errors and cannot use OCIR!

# Write these in: OCI Console → Identity & Security → Policies → Create Policy

# Allow developers to push AND pull images in the whole tenancy:
Allow group developers to manage repos in tenancy

# Allow developers to push AND pull in a specific compartment only:
Allow group developers to manage repos in compartment <compartment-name>

# Allow Kubernetes (OKE) to pull images:
Allow service oke to read repos in tenancy

# Allow a read-only team to only pull (download) images:
Allow group readonly-team to read repos in tenancy

💡 Important tip: Always follow the "Principle of Least Privilege" — give each group ONLY the permissions they absolutely need. Developers don't need to delete repositories — so don't give them that permission!

🛡️ Vulnerability Scanning — Keeping Your Images Safe

When you push an image to OCIR, it might have hidden security problems inside the software packages. OCIR can automatically scan your images for known vulnerabilities using OCI Vulnerability Scanning Service (VSS).

🧒 Simple explanation: Imagine your container image is a bottle of milk 🥛. Before putting it on the store shelf, the factory checks if the milk has gone bad. VSS is like that quality checker — it opens the image, examines all the software inside, and reports if anything is dangerous or expired!

How to Enable Scanning on a Repository

📋 What the steps below do:
We are telling OCIR: "Whenever a new image is pushed to this repository, scan it automatically for known security vulnerabilities (CVEs)." This helps you catch dangerous software BEFORE it reaches production and causes problems!

Via OCI Console:

  1. Go to Developer Services → Container Registry
  2. Click on your repository name
  3. Click "Edit"
  4. Toggle "Scan image on push" to ON ✅
  5. Save changes

Via OCI CLI:

# Check existing scan results for images in your compartment:
oci vulnerability-scanning container-scan-result list \
  --compartment-id <your-compartment-ocid>

# List all container images and their scan status:
oci artifacts container image list \
  --compartment-id <your-compartment-ocid>

# Output shows each image with fields like:
# "lifecycle-state": "AVAILABLE"
# You can then check each image's scan report in the OCI Console!

Understanding Scan Results — Risk Levels

After scanning, each image gets a Risk Level rating. Here's what each level means and what you should do:

  • 🟢 None — No vulnerabilities found! Your image is clean and safe to deploy. ✅
  • 🔵 Low — Minor issues with very low risk. Monitor them and plan to fix soon.
  • 🟡 Medium — Moderate security issues. Fix these before going to production!
  • 🔴 High — Serious vulnerabilities found! Do NOT deploy this image. Fix immediately!
  • ⚫ Critical — Extremely dangerous. Emergency fix required right now. NEVER deploy!

❌ Rule: NEVER deploy an image with HIGH or CRITICAL vulnerabilities to production. These are known attack paths that hackers can use to break into your systems and steal data!

✍️ Image Signing — Proving Your Image is Genuine

Image signing is like putting an official wax seal 🪙 on a royal letter. If the seal is unbroken and genuine, you KNOW the letter is authentic and has not been tampered with by anyone!

In OCIR, you sign images using OCI Vault (Oracle's key management service). When Kubernetes is configured to only run signed images, it automatically REJECTS any image without a valid signature — keeping your cluster very secure.

The Signing Workflow

Developer pushes image to OCIR
          │
          ▼
OCIR runs VSS vulnerability scan
          │
          ▼ (scan passes ✅ — no critical issues)
Security Admin SIGNS the image
using OCI Vault Asymmetric Key 🔑
          │
          ▼
Image in OCIR now has a verified SIGNATURE
          │
          ▼
Kubernetes (OKE) checks signature before running any image
  → Valid signature ✅ → Image runs
  → No signature ❌   → Image REJECTED — cannot run

✅ Best Practice: Enable BOTH vulnerability scanning AND image signing for all production environments. Together they guarantee that only clean, verified, untampered images ever reach your users!

♻️ Image Retention Policies — Automatic Cleanup

Over time, you might push hundreds of image versions to OCIR. Old versions take up storage space — and storage costs money! Retention policies automatically delete old images so your registry stays clean and cost-efficient.

🧒 Simple explanation: Imagine your fridge 🧊. If you never throw away old food, it fills up and starts to smell! A retention policy is like a rule: "Throw away any food older than 30 days automatically." OCIR can do the exact same thing for your container images!

Setting a Retention Policy via the Console

  1. Go to Container Registry → click on your repository
  2. Click "Edit retention policy"
  3. Set rules such as:
    • Keep only the last N versions (example: keep last 5)
    • Delete images not pulled in more than X days (example: 30 days)
  4. Save! OCIR now handles cleanup automatically for you.

📋 What the CLI command below does:
This command updates your registry configuration. By setting is-repository-created-on-first-push to true, repositories are automatically created when you first push an image — no need to create them manually each time!

# Update registry-level configuration
oci artifacts container configuration update \
  --compartment-id <compartment-ocid> \
  --is-repository-created-on-first-push true

# List all images in a repository to decide what to clean:
oci artifacts container image list \
  --compartment-id <compartment-ocid> \
  --repository-name myproject/myapp

# Delete a specific old image by its OCID:
oci artifacts container image delete \
  --image-id <image-ocid>

💡 Pro Tip: Always keep at least your last 3–5 production image versions. If something breaks in production, you can instantly roll back to a previous working version without rebuilding anything!

⚓ OCIR + Kubernetes (OKE) — Deploying Your App at Scale

The most powerful use of OCIR is with OCI Container Engine for Kubernetes (OKE). Your Kubernetes cluster automatically pulls images from OCIR and runs your app across many servers at once!

Step 1 — Create a Kubernetes Secret for OCIR Access

Kubernetes needs your OCIR credentials to pull private images. You store these credentials in a "secret" — a secure, encrypted storage inside Kubernetes.

📋 What the command below does:
We are creating a special password-holder called a Kubernetes Secret that stores our OCIR username and auth token. Kubernetes will use this secret to log into OCIR and download our app's container image automatically. Without this secret, Kubernetes gets "Access Denied" and your app never starts!

# Create a Kubernetes secret for OCIR authentication
kubectl create secret docker-registry ocir-secret \
  --docker-server=iad.ocir.io \
  --docker-username='ansh81vru1zp/john.doe@example.com' \
  --docker-password='<paste-your-auth-token-here>' \
  --docker-email='john.doe@example.com'

# Verify the secret was created:
kubectl get secrets

# Output:
# NAME          TYPE                             DATA   AGE
# ocir-secret   kubernetes.io/dockerconfigjson   1      5s

Step 2 — Create a Kubernetes Deployment YAML

📋 What this YAML file does:
This is a Kubernetes deployment recipe. It tells Kubernetes: "Run 3 copies of my app. Find the container image at this OCIR address. Use the secret we just created to log into OCIR. If any copy crashes, automatically restart it!" — All automated, no manual work needed!

# deployment.yaml — tells Kubernetes how to run our app
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment       # Name for this deployment
spec:
  replicas: 3                  # Run 3 copies of the app (for reliability!)
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        # ⬇️ This is the OCIR image address we pushed earlier!
        image: iad.ocir.io/ansh81vru1zp/myproject/myapp:v1.0
        ports:
        - containerPort: 80    # Our app listens on port 80
      # ⬇️ This is the key — tells Kubernetes to use our OCIR credentials!
      imagePullSecrets:
      - name: ocir-secret
# Apply the deployment to your Kubernetes cluster:
kubectl apply -f deployment.yaml

# Check if the pods (running copies) are healthy:
kubectl get pods

# Output:
# NAME                                READY   STATUS    RESTARTS   AGE
# myapp-deployment-7d5f9b4c6-abc12    1/1     Running   0          30s
# myapp-deployment-7d5f9b4c6-def34    1/1     Running   0          30s
# myapp-deployment-7d5f9b4c6-ghi56    1/1     Running   0          30s
# All 3 pods Running! 🎉

✅ Best Practice: In OKE, use Workload Identity authentication instead of storing auth tokens in secrets. This way, Kubernetes can pull from OCIR automatically using IAM — no static passwords needed at all!

🔄 OCIR in CI/CD Pipelines — Automate Everything

In real companies, nobody manually runs docker build and docker push commands. Instead, an automated robot called a CI/CD pipeline does it for you — every single time a developer saves new code! 

Developer commits new code
        │
        ▼
GitHub / GitLab triggers the pipeline automatically
        │
        ▼
Pipeline runs these steps automatically:
  1. git clone (download the code)
  2. docker build (build the image)
  3. docker tag  (add the OCIR address)
  4. docker push (upload to OCIR) ☁️
  5. Vulnerability scan runs ✅
  6. kubectl apply (deploy to Kubernetes) 🚀
        │
        ▼
New version is LIVE in ~5 minutes — automatically! ⚡

📋 What the GitHub Actions script below does:
This is an automation file that GitHub reads and executes automatically every time you push code to the main branch. It logs into OCIR, builds your Docker image with a unique version tag, and pushes it — all without you doing anything manually!

# .github/workflows/deploy.yml
# GitHub Actions pipeline — runs automatically on every code push!

name: Build and Push to OCIR

on:
  push:
    branches: [main]           # Triggers when code is pushed to 'main' branch

jobs:
  build-and-push:
    runs-on: ubuntu-latest     # Uses a fresh Ubuntu Linux machine to run steps

    steps:
      # Step 1: Download your code onto the build machine
      - name: Checkout code
        uses: actions/checkout@v3

      # Step 2: Log in to OCIR using saved secrets (not hardcoded passwords!)
      - name: Login to OCIR
        run: |
          docker login iad.ocir.io \
            -u ${{ secrets.OCI_NAMESPACE }}/${{ secrets.OCI_USERNAME }} \
            -p ${{ secrets.OCI_AUTH_TOKEN }}

      # Step 3: Build the Docker image
      # github.sha is the unique commit ID — used as the version tag!
      - name: Build Docker image
        run: |
          docker build -t iad.ocir.io/${{ secrets.OCI_NAMESPACE }}/myproject/myapp:${{ github.sha }} .

      # Step 4: Push the image to OCIR
      - name: Push to OCIR
        run: |
          docker push iad.ocir.io/${{ secrets.OCI_NAMESPACE }}/myproject/myapp:${{ github.sha }}

📘 Important: Store your OCI credentials (auth token, namespace, username) in GitHub Secrets — NEVER write passwords directly in the code! Go to: GitHub repo → Settings → Secrets and variables → Actions → New repository secret.

⚙️ Advanced — Storing Helm Charts in OCIR

OCIR is not just for Docker images! You can also store Helm charts — which are complete deployment packages for Kubernetes apps. Think of a Helm chart like a fully packed moving box 📦 that contains everything needed to set up your entire app in Kubernetes!

📋 What the commands below do:
First, we package our Helm chart (Kubernetes deployment recipe) into a single file. Then we push that file to OCIR, just like pushing a Docker image. Now our entire app deployment recipe is safely stored, versioned, and ready to be installed anywhere with one simple command!

# Step 1: Package your Helm chart into a .tgz file
helm package ./mychart/
# Creates: mychart-1.0.0.tgz

# Step 2: Push the Helm chart to OCIR using OCI format
helm push mychart-1.0.0.tgz \
  oci://iad.ocir.io/ansh81vru1zp/helm-charts

# Step 3: Pull and install the Helm chart from OCIR
helm install my-release \
  oci://iad.ocir.io/ansh81vru1zp/helm-charts/mychart \
  --version 1.0.0

# Step 4: Verify the installation
helm list
kubectl get all

✅ Trend: Storing Helm charts in OCIR is the modern best practice! It keeps ALL your artifacts — images AND charts — in one single place. No need for separate Helm chart repositories anymore!

🏆 Best Practices Checklist

Here is your final checklist. Follow all of these and you are truly an OCIR Pro! 🌟

✅ ALWAYS DO These Things:

  • ✅ Use specific version tags like :v1.2.3 — never use :latest in production
  • ✅ Enable vulnerability scanning on ALL your repositories
  • ✅ Set retention policies to auto-delete old unused images
  • ✅ Use private repositories for your app images (never make them public by mistake!)
  • ✅ Use IAM policies with minimum required access for each group
  • ✅ Use the same OCI region for OCIR and your OKE cluster — for fast pulls!
  • ✅ Sign images with OCI Vault for all production environments
  • ✅ Store all secrets in OCI Vault or GitHub Secrets — never write them in code or YAML files
  • ✅ Use multi-architecture images (ARM + AMD64) for maximum deployment flexibility
  • ✅ Keep the last 3–5 production image versions for quick rollback if something breaks

❌ NEVER Do These Things:

  • ❌ Never use :latest tag in production deployments — it's unpredictable!
  • ❌ Never put your auth token inside code files, YAML configs, or Git repositories
  • ❌ Never make sensitive app repositories PUBLIC — anyone on the internet can pull them!
  • ❌ Never deploy images with HIGH or CRITICAL vulnerabilities — fix them first!
  • ❌ Never skip IAM policies — open access to OCIR is a serious security risk
  • ❌ Never use a different region for OCIR and your servers — it causes slow pulls and extra costs

📋 Quick Reference — All Commands at a Glance

  • Login to OCIR: docker login iad.ocir.io -u <namespace>/<username>
  • Build image: docker build -t myapp:v1.0 .
  • Tag for OCIR: docker tag myapp:v1.0 iad.ocir.io/<ns>/myproject/myapp:v1.0
  • Push image: docker push iad.ocir.io/<ns>/myproject/myapp:v1.0
  • Pull image: docker pull iad.ocir.io/<ns>/myproject/myapp:v1.0
  • Find namespace: oci os ns get
  • List images: oci artifacts container image list --compartment-id <ocid>
  • Delete image: oci artifacts container image delete --image-id <ocid>
  • Get scan results: oci vulnerability-scanning container-scan-result list --compartment-id <ocid>
  • Push Helm chart: helm push mychart-1.0.0.tgz oci://iad.ocir.io/<ns>/helm-charts

Quick Summary 📝

What we learned:

  • OCIR → Oracle's managed cloud cupboard for storing container images securely
  • Key Concepts → Tenancy Namespace, Region Key, Repository, Tag, Full Image Path
  • Auth Token → Your special OCIR password — generate once, save safely forever!
  • Push / Pull → Push = upload image to cloud. Pull = download image from cloud.
  • IAM Policies → Control who can push, pull, or manage images — use least privilege!
  • Vulnerability Scanning → Auto-checks images for security issues on every push
  • Image Signing → Proves the image is genuine and untampered — use OCI Vault!
  • Retention Policies → Auto-delete old images to save storage space and cost
  • OKE Integration → Kubernetes pulls images from OCIR automatically to run your app
  • CI/CD Pipeline → Automate build → scan → push → deploy with GitHub Actions

Happy learning! ☁️✨

Comments