Image migration script

The migrate-images.sh script automates the process of pulling OpenIAM Docker images from the official source registry, retagging them, and pushing them to a target registry (such as a self-hosted Harbor instance). This is useful for:

  • Air-gapped / offline Kubernetes environments that cannot access the internet.
  • Internal enterprise registries for security compliance.
  • Version-controlled image promotion between environments (dev, staging, prod).
  • Disaster recovery — maintaining a local mirror of all required images.

The script interactively prompts for all credentials, auto-detects the current image tag from the live Kubernetes cluster, and automatically creates Harbor projects if they do not exist.

Prerequisites

Ensure all of the following are in place before running the script.

Software requirements

ComponentMinimum VersionNotes
Docker20.10+Must be installed and running on the machine executing the script
Docker Composev2.0+ (plugin)Required only for Harbor setup, not for migration itself
Bash4.0+Script uses associative arrays and mapfilesh is not supported
Python 33.6+Used for auto-detecting image tag from kubectl JSON output
kubectl1.20+Optional — needed for auto tag detection from cluster; if absent, tag is prompted manually
curlAnyRequired for Harbor project auto-creation via REST API

Network requirements

  • Outbound HTTPS (port 443) to registry.openiam.com from the migration host
  • Outbound access to hub.docker.com (port 443) for public images: busybox and hashicorp/consul-k8s-control-plane
  • Inbound/outbound access to the target registry (default port 80 for Harbor HTTP, 443 for HTTPS)
  • If using HTTP (insecure) for target registry — Docker daemon must be configured with insecure-registries

Credentials required

RegistryCredential TypeWhere to Obtain
registry.openiam.comUsername + PasswordProvided by OpenIAM support / your license agreement
Target Registry (Harbor)Username + PasswordHarbor admin account — default: admin / Harbor12345
Docker Hub (public images)Not requiredbusybox and hashicorp images are pulled anonymously

Disk space

⚠️ Warning: Ensure at least 80–100 GB of free disk space on the migration host. All 46 images are pulled locally before being pushed to the target registry. Images are NOT automatically cleaned up after migration.

To clean up local images after a successful migration run the following.

# Remove all pulled openiam images after migration
docker images | grep 'registry.openiam.com' | awk '{print $3}' | xargs docker rmi -f
# Check remaining disk usage
docker system df

Docker insecure registry (HTTP only)

If the target registry runs on HTTP (not HTTPS), Docker must be configured to allow insecure connections. Skip this step if using HTTPS with a valid certificate.

# Edit or create /etc/docker/daemon.json
cat > /etc/docker/daemon.json << 'EOF'
{
"insecure-registries": ["<TARGET_REGISTRY_IP_OR_HOST>:<PORT>"]
}
EOF
# Restart Docker to apply
sudo systemctl restart docker
# Verify
docker info | grep -A5 'Insecure Registries'

Harbor target registry setup

If using Harbor as the target registry, it can be set up on the same Linux host using the harbor-setup.sh script. Harbor requires:

  • Linux host (RHEL 8/9/10, Ubuntu 20.04+, or CentOS 8+)
  • Docker 20.10+ and Docker Compose v2+
  • Minimum 4 GB RAM, 2 vCPUs, 80 GB disk for Harbor data
  • Port 80 (HTTP) or 443 (HTTPS) available — not used by another service
ℹ️ Info: The `harbor-setup.sh` script automatically creates three projects: `openiam_infra`, `openiam_service`, and `public` if you create the Harbor registry from the OpenIAM repository. For other repositories, please create these projects manually in your target registry.
⚠️ Note:The `harbor-setup.sh` script is currently supported only on Debian and Ubuntu-based operating systems.
For other Linux distributions, please manually install the required prerequisites (such as Docker Compose and other dependencies) using the appropriate package manager and commands for your operating system. Once the prerequisites are installed, you can use the script to complete the Harbor setup.

Image Inventory

The following 46 images are migrated by the script. This list was captured from the live Kubernetes cluster on June 2026.

Infrastructure images (openiam_infra)

ImagePurpose
openiam_infra/activitiWorkflow engine (BPMN)
openiam_infra/cassandraNoSQL database for IAM data
openiam_infra/certificate-generatorTLS/SSL certificate provisioning
openiam_infra/chownInit container — file permission fixer
openiam_infra/consulService mesh and config store
openiam_infra/curatorOpenSearch index lifecycle manager
openiam_infra/flywayDatabase schema migration tool
openiam_infra/iamscriptsBootstrap and initialization scripts
openiam_infra/janusgraphGraph database for identity relationships
openiam_infra/medusaSecrets and config management
openiam_infra/nfs-provisionerKubernetes NFS storage provisioner
openiam_infra/nginxReverse proxy / ingress
openiam_infra/opensearch-k8Search and analytics engine
openiam_infra/postgres-k8PostgreSQL relational database
openiam_infra/rabbitmq-k8Message queue broker
openiam_infra/redis-k8In-memory cache
openiam_infra/redis-sentinelRedis high-availability sentinel
openiam_infra/vaultHashiCorp Vault secrets manager
openiam_infra/vault-bootstrapVault initialization and unseal job

Service images (openiam_service)

ImagePurpose
openiam_service/audit-log-managerAudit trail and compliance logging
openiam_service/auth-managerAuthentication and token management
openiam_service/business-rule-managerPolicy and business rule engine
openiam_service/email-managerEmail notification service
openiam_service/esbEnterprise Service Bus — event routing
openiam_service/groovy-managerGroovy script execution engine
openiam_service/idmIdentity management core service
openiam_service/idpIdentity Provider / SSO / SAML
openiam_service/jdbc-connector-rabbitmqJDBC database connector via RabbitMQ
openiam_service/ldap-connector-rabbitmqLDAP directory connector via RabbitMQ
openiam_service/linux-connector-rabbitmqLinux system connector via RabbitMQ
openiam_service/machine-learningML-powered risk and anomaly detection
openiam_service/reconciliationAccount reconciliation service
openiam_service/reportviewerReports and dashboard viewer
openiam_service/rproxyReverse proxy for service routing
openiam_service/scim-connector-rabbitmqSCIM protocol connector
openiam_service/script-connector-rabbitmqCustom script connector via RabbitMQ
openiam_service/selfserviceEnd-user SelfService portal
openiam_service/selfservice-extSelfService portal extensions
openiam_service/selfservice-v2-uiSelfService UI v2 (React)
openiam_service/synchronizationIdentity synchronization engine
openiam_service/ui-staticStatic UI assets server
openiam_service/webconsoleAdmin web console
openiam_service/workflowWorkflow orchestration engine

Public / Third-party images

ImagePurpose
busybox:latestLightweight init/debug container
hashicorp/consul-k8s-control-plane:1.6.3HashiCorp Consul Kubernetes controller

Environment Variables

All credentials and settings can be pre-set as environment variables to avoid interactive prompts. This is recommended for CI/CD pipelines or automated deployments.

VariableDefaultDescription
SOURCE_REGISTRYregistry.openiam.comOpenIAM source registry hostname
SOURCE_USER(prompted)Username for source registry login
SOURCE_PASS(prompted)Password for source registry login
TARGET_REGISTRY(prompted)Target registry IP:port or hostname (e.g. 10.1.0.10:80)
TARGET_USER(prompted)Username for target registry login
TARGET_PASS(prompted)Password for target registry login
SOURCE_TAG(auto-detect)Override auto-detected source image tag
NEW_TAG(same as source)New tag to apply on target registry (for version bumps)

Usage

Interactive mode (recommended for first run)

Download the repository which contains the migration script and Harbor repository setup.

git clone https://github.com/openiam-platform/kubernetes-docker-configuration.git
cd kubernetes-docker-configuration
git checkout RC-2026.6.2

Run the script (migrate-images.sh) without any environment variables. It will prompt for all required inputs:

bash migrate-images.sh
# The script will ask for:
# Source registry URL (default: registry.openiam.com)
# Source username
# Source password (hidden — no echo)
# Target registry URL (e.g. 10.1.0.10:80)
# Target username
# Target password (hidden — no echo)
# New tag (Enter to keep same as detected source tag)

Non-interactive mode

Set environment variables before running. The script skips prompts for any pre-set variables.

export SOURCE_REGISTRY="registry.openiam.com"
export SOURCE_USER="openiam_user"
export SOURCE_PASS="openiam_password"
export TARGET_REGISTRY="10.1.0.10:80"
export TARGET_USER="admin"
export TARGET_PASS="Harbor12345"
export SOURCE_TAG="2026.5.1-prod"
export NEW_TAG="2026.6.0-prod" # New version tag on target
# Run non-interactively (auto-confirm)
bash migrate-images.sh <<< "yes"

Mirror same version (no tag change)

To simply mirror images with the same tag (no version bump):

export NEW_TAG="" # Leave empty — script keeps same tag
bash migrate-images.sh
# Or press Enter when prompted for new tag

Upgrading to new OpenIAM version

When OpenIAM releases a new version (e.g. 2026.6.1), simply update the NEW_TAG:

# Script auto-detects current cluster tag: 2026.5.1-prod
# Set the new version as target tag
export NEW_TAG="2026.6.0-prod"
bash migrate-images.sh <<< "yes"
# Result:
# Pulls: registry.openiam.com/openiam_infra/cassandra:2026.5.1-prod
# Pushes: 10.1.0.10:80/openiam_infra/cassandra:2026.6.0-prod

How the script works

The script follows this workflow for each image:

StepActionDetail
1Collect inputsPrompts or reads env vars for source/target registry, credentials, and tags.
2Auto-detect tagRuns kubectl get pods to find the current OpenIAM image tag from the live cluster.
3LoginRuns docker login for both source and target registries.
4Create projectsCalls Harbor REST API to create openiam_infra, openiam_service, public projects if missing.
5Pulldocker pull from source registry for each image.
6Retagdocker tag — applies target registry URL and new tag
7Pushdocker push to target registry
8SummaryPrints success/failure count, timing, and list of any failed images

Troubleshooting

Pull failed: unauthorized

Source registry credentials are incorrect or the account does not have pull access. Verify:

  • Username and password are correct
  • Account has pull permissions on registry.openiam.com
  • Check with OpenIAM support if the account is active

Push failed: project does not exist

The target registry is not Harbor, or the Harbor API is not reachable. Manually create the projects:

# Manually create projects via Harbor API
for PROJECT in openiam_infra openiam_service public; do
curl -u admin:Harbor12345 -X POST http://10.1.0.10:80/api/v2.0/projects \
-H 'Content-Type: application/json' \
-d "{\"project_name\": \"${PROJECT}\", \"public\": true}"
done

Push failed: server gave HTTP response to HTTPS client

Docker is trying to use HTTPS but the registry is running HTTP. Add the registry to insecure-registries in /etc/docker/daemon.json and restart Docker. See Section 2.5.

Auto tag detection not working

kubectl is not installed or not configured with the correct kubeconfig. Either:

  • Install kubectl and configure it: export KUBECONFIG=/path/to/kubeconfig
  • Set the SOURCE_TAG environment variable manually before running the script

No space left on device during pull

Free up disk space on the migration host. See Section 2.4 for cleanup commands. Alternatively, migrate in batches by temporarily commenting out image entries in the build_image_list function.

ℹ️ Tip: Run the script with `bash -x migrate-images.sh` to see every command as it executes — this helps diagnose exactly which step is failing.

Quick reference

# ── First time setup ─────────────────────────────────────────
sudo bash harbor-setup.sh # Install Harbor
bash migrate-images.sh # Run migration (interactive)
# ── Check Harbor status ──────────────────────────────────────
cd /opt/harbor && docker compose ps
# ── Stop / Start Harbor ──────────────────────────────────────
cd /opt/harbor && docker compose down
cd /opt/harbor && docker compose up -d
# ── Verify images in Harbor ──────────────────────────────────
curl -s -u admin:Harbor12345 \
http://10.1.0.10:80/api/v2.0/repositories?page_size=50 \
| python3 -m json.tool | grep name
# ── Refresh image list from cluster ─────────────────────────
kubectl get pods -o json | python3 -c "
import json,sys; data=json.load(sys.stdin); imgs=set()
[imgs.add(c['image']) for i in data['items']
for c in i['spec'].get('containers',[])+i['spec'].get('initContainers',[])]
[print(i) for i in sorted(imgs) if i]"
# ── Next version upgrade ─────────────────────────────────────
NEW_TAG="2026.6.0-prod" bash migrate-images.sh <<< "yes"